gws-axi 0.10.2 → 0.11.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/commands/drive/upload.d.ts +17 -0
- package/dist/src/commands/drive/upload.js +217 -0
- package/dist/src/commands/drive/upload.js.map +1 -0
- package/dist/src/commands/drive/upload.test.d.ts +1 -0
- package/dist/src/commands/drive/upload.test.js +86 -0
- package/dist/src/commands/drive/upload.test.js.map +1 -0
- package/dist/src/commands/drive.js +11 -2
- package/dist/src/commands/drive.js.map +1 -1
- package/dist/src/util/mime-types.d.ts +7 -0
- package/dist/src/util/mime-types.js +95 -0
- package/dist/src/util/mime-types.js.map +1 -0
- package/dist/src/util/mime-types.test.d.ts +1 -0
- package/dist/src/util/mime-types.test.js +47 -0
- package/dist/src/util/mime-types.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const UPLOAD_HELP = "usage: gws-axi drive upload <local-path> [flags]\nargs[1]:\n <local-path> REQUIRED \u2014 path to a readable local file to upload\nflags[5]:\n --parent <folder-id> Destination folder ID (default: My Drive root).\n Cannot be combined with --update.\n --name <name> Name to give the file in Drive (default: the local\n file's basename). With --update, renames the target.\n --mime <type> Override the source content type (default: detected\n from the file extension; unknown \u2192 application/octet-stream)\n --convert Convert to the matching native Google format on upload\n (.docx\u2192Doc, .xlsx/.csv\u2192Sheet, .pptx\u2192Slides). Cannot be\n combined with --update.\n --update <file-id> Replace an existing file's content (new revision)\n instead of creating a new file.\n --account <email> REQUIRED when 2+ accounts are authenticated\nexamples:\n gws-axi drive upload ./report.pdf\n gws-axi drive upload ./report.pdf --parent 1AbC... --name \"Q2 Report.pdf\"\n gws-axi drive upload ./notes.docx --convert\n gws-axi drive upload ./report.pdf --update 1XyZ...\nnotes:\n Without --update, every upload creates a NEW Drive file \u2014 re-running makes\n another copy (Drive allows duplicate names). Use --update <id> to replace an\n existing file's content in place.\noutput:\n An `action: created` (or `updated`) line plus a `file{...}` object with\n id, name, mime_type, size_bytes, parents, and web_view_link.\n";
|
|
2
|
+
export interface ParsedFlags {
|
|
3
|
+
localPath: string | undefined;
|
|
4
|
+
parent: string | undefined;
|
|
5
|
+
name: string | undefined;
|
|
6
|
+
mime: string | undefined;
|
|
7
|
+
convert: boolean;
|
|
8
|
+
update: string | undefined;
|
|
9
|
+
}
|
|
10
|
+
export declare function parseFlags(args: string[]): ParsedFlags;
|
|
11
|
+
/**
|
|
12
|
+
* Validate the local path is present and the flag combination is legal,
|
|
13
|
+
* before any FS/network work. Pure — throws `AxiError` on the same cases the
|
|
14
|
+
* spec enumerates, so it's unit-testable without touching disk or Google.
|
|
15
|
+
*/
|
|
16
|
+
export declare function validateFlags(flags: ParsedFlags): void;
|
|
17
|
+
export declare function driveUploadCommand(account: string, args: string[]): Promise<string>;
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { createReadStream } from "node:fs";
|
|
2
|
+
import { stat } from "node:fs/promises";
|
|
3
|
+
import { basename, resolve } from "node:path";
|
|
4
|
+
import { AxiError } from "axi-sdk-js";
|
|
5
|
+
import { driveClient, translateGoogleError } from "../../google/client.js";
|
|
6
|
+
import { joinBlocks, renderHelp, renderObject } from "../../output/index.js";
|
|
7
|
+
import { detectMimeType, googleConversionTarget, } from "../../util/mime-types.js";
|
|
8
|
+
export const UPLOAD_HELP = `usage: gws-axi drive upload <local-path> [flags]
|
|
9
|
+
args[1]:
|
|
10
|
+
<local-path> REQUIRED — path to a readable local file to upload
|
|
11
|
+
flags[5]:
|
|
12
|
+
--parent <folder-id> Destination folder ID (default: My Drive root).
|
|
13
|
+
Cannot be combined with --update.
|
|
14
|
+
--name <name> Name to give the file in Drive (default: the local
|
|
15
|
+
file's basename). With --update, renames the target.
|
|
16
|
+
--mime <type> Override the source content type (default: detected
|
|
17
|
+
from the file extension; unknown → application/octet-stream)
|
|
18
|
+
--convert Convert to the matching native Google format on upload
|
|
19
|
+
(.docx→Doc, .xlsx/.csv→Sheet, .pptx→Slides). Cannot be
|
|
20
|
+
combined with --update.
|
|
21
|
+
--update <file-id> Replace an existing file's content (new revision)
|
|
22
|
+
instead of creating a new file.
|
|
23
|
+
--account <email> REQUIRED when 2+ accounts are authenticated
|
|
24
|
+
examples:
|
|
25
|
+
gws-axi drive upload ./report.pdf
|
|
26
|
+
gws-axi drive upload ./report.pdf --parent 1AbC... --name "Q2 Report.pdf"
|
|
27
|
+
gws-axi drive upload ./notes.docx --convert
|
|
28
|
+
gws-axi drive upload ./report.pdf --update 1XyZ...
|
|
29
|
+
notes:
|
|
30
|
+
Without --update, every upload creates a NEW Drive file — re-running makes
|
|
31
|
+
another copy (Drive allows duplicate names). Use --update <id> to replace an
|
|
32
|
+
existing file's content in place.
|
|
33
|
+
output:
|
|
34
|
+
An \`action: created\` (or \`updated\`) line plus a \`file{...}\` object with
|
|
35
|
+
id, name, mime_type, size_bytes, parents, and web_view_link.
|
|
36
|
+
`;
|
|
37
|
+
export function parseFlags(args) {
|
|
38
|
+
const flags = {
|
|
39
|
+
localPath: undefined,
|
|
40
|
+
parent: undefined,
|
|
41
|
+
name: undefined,
|
|
42
|
+
mime: undefined,
|
|
43
|
+
convert: false,
|
|
44
|
+
update: undefined,
|
|
45
|
+
};
|
|
46
|
+
for (let i = 0; i < args.length; i++) {
|
|
47
|
+
const arg = args[i];
|
|
48
|
+
const next = args[i + 1];
|
|
49
|
+
switch (arg) {
|
|
50
|
+
case "--parent":
|
|
51
|
+
flags.parent = next;
|
|
52
|
+
i++;
|
|
53
|
+
break;
|
|
54
|
+
case "--name":
|
|
55
|
+
flags.name = next;
|
|
56
|
+
i++;
|
|
57
|
+
break;
|
|
58
|
+
case "--mime":
|
|
59
|
+
flags.mime = next;
|
|
60
|
+
i++;
|
|
61
|
+
break;
|
|
62
|
+
case "--convert":
|
|
63
|
+
flags.convert = true;
|
|
64
|
+
break;
|
|
65
|
+
case "--update":
|
|
66
|
+
flags.update = next;
|
|
67
|
+
i++;
|
|
68
|
+
break;
|
|
69
|
+
default:
|
|
70
|
+
if (!arg.startsWith("--") && flags.localPath === undefined) {
|
|
71
|
+
flags.localPath = arg;
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return flags;
|
|
77
|
+
}
|
|
78
|
+
const UPLOAD_FIELDS = "id,name,mimeType,size,parents,webViewLink";
|
|
79
|
+
/**
|
|
80
|
+
* Validate the local path is present and the flag combination is legal,
|
|
81
|
+
* before any FS/network work. Pure — throws `AxiError` on the same cases the
|
|
82
|
+
* spec enumerates, so it's unit-testable without touching disk or Google.
|
|
83
|
+
*/
|
|
84
|
+
export function validateFlags(flags) {
|
|
85
|
+
if (!flags.localPath) {
|
|
86
|
+
throw new AxiError("Missing local file path", "VALIDATION_ERROR", [
|
|
87
|
+
"Usage: gws-axi drive upload <local-path> [flags]",
|
|
88
|
+
]);
|
|
89
|
+
}
|
|
90
|
+
if (flags.update && flags.parent) {
|
|
91
|
+
throw new AxiError("--parent cannot be combined with --update", "VALIDATION_ERROR", [
|
|
92
|
+
"--update replaces a file's content in place; moving folders is not supported here",
|
|
93
|
+
"Drop --parent, or upload as a new file (omit --update) to place it in a folder",
|
|
94
|
+
]);
|
|
95
|
+
}
|
|
96
|
+
if (flags.update && flags.convert) {
|
|
97
|
+
throw new AxiError("--convert cannot be combined with --update", "VALIDATION_ERROR", [
|
|
98
|
+
"Converting a file's type in place is not supported",
|
|
99
|
+
"Drop --convert to replace content as-is, or upload a new file (omit --update) with --convert",
|
|
100
|
+
]);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
export async function driveUploadCommand(account, args) {
|
|
104
|
+
const flags = parseFlags(args);
|
|
105
|
+
validateFlags(flags);
|
|
106
|
+
const absolutePath = resolve(process.cwd(), flags.localPath);
|
|
107
|
+
let fileStat;
|
|
108
|
+
try {
|
|
109
|
+
fileStat = await stat(absolutePath);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
throw new AxiError(`Local file not found: ${flags.localPath}`, "LOCAL_FILE_NOT_FOUND", ["Check the path; it must be a readable file on this machine"]);
|
|
113
|
+
}
|
|
114
|
+
if (fileStat.isDirectory()) {
|
|
115
|
+
throw new AxiError(`Local path is a directory, not a file: ${flags.localPath}`, "LOCAL_PATH_NOT_FILE", ["Upload a single file; recursive directory upload is not supported"]);
|
|
116
|
+
}
|
|
117
|
+
const name = flags.name ?? basename(absolutePath);
|
|
118
|
+
const sourceMime = flags.mime ?? detectMimeType(absolutePath);
|
|
119
|
+
let targetMime;
|
|
120
|
+
if (flags.convert) {
|
|
121
|
+
const target = googleConversionTarget(sourceMime);
|
|
122
|
+
if (!target) {
|
|
123
|
+
throw new AxiError(`Cannot convert ${sourceMime} to a native Google format`, "UNSUPPORTED_CONVERSION", [
|
|
124
|
+
"Supported: word-processing/text → Doc, spreadsheets/CSV → Sheet, presentations → Slides",
|
|
125
|
+
"Drop --convert to upload the file as-is",
|
|
126
|
+
]);
|
|
127
|
+
}
|
|
128
|
+
targetMime = target;
|
|
129
|
+
}
|
|
130
|
+
const api = await driveClient(account);
|
|
131
|
+
const media = {
|
|
132
|
+
mimeType: sourceMime,
|
|
133
|
+
body: createReadStream(absolutePath),
|
|
134
|
+
};
|
|
135
|
+
let file;
|
|
136
|
+
const updating = Boolean(flags.update);
|
|
137
|
+
try {
|
|
138
|
+
if (flags.update) {
|
|
139
|
+
const res = await api.files.update({
|
|
140
|
+
fileId: flags.update,
|
|
141
|
+
requestBody: flags.name ? { name } : {},
|
|
142
|
+
media,
|
|
143
|
+
fields: UPLOAD_FIELDS,
|
|
144
|
+
supportsAllDrives: true,
|
|
145
|
+
});
|
|
146
|
+
file = res.data;
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
const requestBody = { name };
|
|
150
|
+
if (flags.parent)
|
|
151
|
+
requestBody.parents = [flags.parent];
|
|
152
|
+
if (targetMime)
|
|
153
|
+
requestBody.mimeType = targetMime;
|
|
154
|
+
const res = await api.files.create({
|
|
155
|
+
requestBody,
|
|
156
|
+
media,
|
|
157
|
+
fields: UPLOAD_FIELDS,
|
|
158
|
+
supportsAllDrives: true,
|
|
159
|
+
});
|
|
160
|
+
file = res.data;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
const translated = translateGoogleError(err, {
|
|
165
|
+
account,
|
|
166
|
+
operation: updating ? "drive.files.update" : "drive.files.create",
|
|
167
|
+
});
|
|
168
|
+
if (translated.code === "NOT_FOUND") {
|
|
169
|
+
// For --update, the missing item is the target file; for create it's the
|
|
170
|
+
// --parent folder. Re-wrap with an access-check suggestion (cf. drive get).
|
|
171
|
+
const missing = updating
|
|
172
|
+
? `File '${flags.update}' not found (or ${account} can't write to it)`
|
|
173
|
+
: `Parent folder '${flags.parent}' not found (or ${account} can't write to it)`;
|
|
174
|
+
throw new AxiError(missing, "FILE_NOT_FOUND", [
|
|
175
|
+
"Verify the ID is correct (from a Drive URL or `drive search` / `drive ls`)",
|
|
176
|
+
`Confirm ${account} has edit access`,
|
|
177
|
+
]);
|
|
178
|
+
}
|
|
179
|
+
throw translated;
|
|
180
|
+
}
|
|
181
|
+
const details = {
|
|
182
|
+
id: file.id ?? "",
|
|
183
|
+
name: file.name ?? name,
|
|
184
|
+
mime_type: file.mimeType ?? "",
|
|
185
|
+
};
|
|
186
|
+
if (file.size)
|
|
187
|
+
details.size_bytes = parseInt(file.size, 10);
|
|
188
|
+
details.parents = file.parents?.length ? file.parents.join(", ") : "";
|
|
189
|
+
if (file.webViewLink)
|
|
190
|
+
details.web_view_link = file.webViewLink;
|
|
191
|
+
const blocks = [];
|
|
192
|
+
blocks.push(renderObject({ action: updating ? "updated" : "created", account }));
|
|
193
|
+
blocks.push(renderObject({ file: details }));
|
|
194
|
+
const suggestions = [];
|
|
195
|
+
const id = file.id ?? "";
|
|
196
|
+
const isNativeDoc = file.mimeType === "application/vnd.google-apps.document";
|
|
197
|
+
if (isNativeDoc) {
|
|
198
|
+
suggestions.push(`Run \`gws-axi docs read ${id}\` to read it as markdown`);
|
|
199
|
+
}
|
|
200
|
+
else if ((file.mimeType ?? "").startsWith("application/vnd.google-apps.")) {
|
|
201
|
+
suggestions.push(`Native Google file — run \`gws-axi docs download ${id} --as <mime>\` to export it`);
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
suggestions.push(`Run \`gws-axi docs download ${id} --out <path>\` to fetch the bytes back`);
|
|
205
|
+
}
|
|
206
|
+
suggestions.push(`Run \`gws-axi drive get ${id}\` for full metadata`);
|
|
207
|
+
suggestions.push(`Run \`gws-axi drive permissions ${id}\` to see / change who has access`);
|
|
208
|
+
if (!updating) {
|
|
209
|
+
suggestions.push(`Re-running creates another copy — pass \`--update ${id}\` to replace this file's content instead`);
|
|
210
|
+
}
|
|
211
|
+
if (file.webViewLink) {
|
|
212
|
+
suggestions.push(`Open in browser: ${file.webViewLink}`);
|
|
213
|
+
}
|
|
214
|
+
blocks.push(renderHelp(suggestions));
|
|
215
|
+
return joinBlocks(...blocks);
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=upload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../../src/commands/drive/upload.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { AxiError } from "axi-sdk-js";
|
|
3
|
+
import { parseFlags, validateFlags } from "./upload.js";
|
|
4
|
+
describe("drive upload parseFlags", () => {
|
|
5
|
+
it("parses a bare local path with defaults", () => {
|
|
6
|
+
const f = parseFlags(["./report.pdf"]);
|
|
7
|
+
expect(f.localPath).toBe("./report.pdf");
|
|
8
|
+
expect(f.parent).toBeUndefined();
|
|
9
|
+
expect(f.name).toBeUndefined();
|
|
10
|
+
expect(f.mime).toBeUndefined();
|
|
11
|
+
expect(f.convert).toBe(false);
|
|
12
|
+
expect(f.update).toBeUndefined();
|
|
13
|
+
});
|
|
14
|
+
it("parses all flags", () => {
|
|
15
|
+
const f = parseFlags([
|
|
16
|
+
"./report.pdf",
|
|
17
|
+
"--parent",
|
|
18
|
+
"1AbC",
|
|
19
|
+
"--name",
|
|
20
|
+
"Q2 Report.pdf",
|
|
21
|
+
"--mime",
|
|
22
|
+
"application/pdf",
|
|
23
|
+
"--convert",
|
|
24
|
+
]);
|
|
25
|
+
expect(f.localPath).toBe("./report.pdf");
|
|
26
|
+
expect(f.parent).toBe("1AbC");
|
|
27
|
+
expect(f.name).toBe("Q2 Report.pdf");
|
|
28
|
+
expect(f.mime).toBe("application/pdf");
|
|
29
|
+
expect(f.convert).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
it("parses --update with a file id", () => {
|
|
32
|
+
const f = parseFlags(["./report.pdf", "--update", "1XyZ"]);
|
|
33
|
+
expect(f.update).toBe("1XyZ");
|
|
34
|
+
});
|
|
35
|
+
it("takes the first positional as the local path, ignoring later ones", () => {
|
|
36
|
+
const f = parseFlags(["./a.pdf", "./b.pdf"]);
|
|
37
|
+
expect(f.localPath).toBe("./a.pdf");
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
describe("drive upload validateFlags", () => {
|
|
41
|
+
const base = {
|
|
42
|
+
localPath: "./report.pdf",
|
|
43
|
+
parent: undefined,
|
|
44
|
+
name: undefined,
|
|
45
|
+
mime: undefined,
|
|
46
|
+
convert: false,
|
|
47
|
+
update: undefined,
|
|
48
|
+
};
|
|
49
|
+
it("accepts a valid create invocation", () => {
|
|
50
|
+
expect(() => validateFlags({ ...base, parent: "1AbC" })).not.toThrow();
|
|
51
|
+
});
|
|
52
|
+
it("accepts a valid update invocation", () => {
|
|
53
|
+
expect(() => validateFlags({ ...base, update: "1XyZ" })).not.toThrow();
|
|
54
|
+
});
|
|
55
|
+
it("throws VALIDATION_ERROR when the local path is missing", () => {
|
|
56
|
+
try {
|
|
57
|
+
validateFlags({ ...base, localPath: undefined });
|
|
58
|
+
throw new Error("should have thrown");
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
expect(err).toBeInstanceOf(AxiError);
|
|
62
|
+
expect(err.code).toBe("VALIDATION_ERROR");
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
it("rejects --parent combined with --update", () => {
|
|
66
|
+
try {
|
|
67
|
+
validateFlags({ ...base, parent: "1AbC", update: "1XyZ" });
|
|
68
|
+
throw new Error("should have thrown");
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
expect(err).toBeInstanceOf(AxiError);
|
|
72
|
+
expect(err.code).toBe("VALIDATION_ERROR");
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
it("rejects --convert combined with --update", () => {
|
|
76
|
+
try {
|
|
77
|
+
validateFlags({ ...base, convert: true, update: "1XyZ" });
|
|
78
|
+
throw new Error("should have thrown");
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
expect(err).toBeInstanceOf(AxiError);
|
|
82
|
+
expect(err.code).toBe("VALIDATION_ERROR");
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
//# sourceMappingURL=upload.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload.test.js","sourceRoot":"","sources":["../../../../src/commands/drive/upload.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,7 @@ import { drivePermissionsCommand, PERMISSIONS_HELP, } from "./drive/permissions.
|
|
|
7
7
|
import { driveActivityCommand, ACTIVITY_HELP } from "./drive/activity.js";
|
|
8
8
|
import { driveRevisionsCommand, REVISIONS_HELP, } from "./drive/revisions.js";
|
|
9
9
|
import { driveSearchCommand, SEARCH_HELP } from "./drive/search.js";
|
|
10
|
+
import { driveUploadCommand, UPLOAD_HELP } from "./drive/upload.js";
|
|
10
11
|
// Drive `download` shares the docs/download.ts implementation — same code
|
|
11
12
|
// path handles native Google file export + uploaded-file media fetch.
|
|
12
13
|
const DOWNLOAD_HELP = `usage: gws-axi drive download <file-id> [flags]
|
|
@@ -77,6 +78,12 @@ const SUBCOMMANDS = [
|
|
|
77
78
|
help: ACTIVITY_HELP,
|
|
78
79
|
handler: driveActivityCommand,
|
|
79
80
|
},
|
|
81
|
+
{
|
|
82
|
+
name: "upload",
|
|
83
|
+
mutation: true,
|
|
84
|
+
help: UPLOAD_HELP,
|
|
85
|
+
handler: driveUploadCommand,
|
|
86
|
+
},
|
|
80
87
|
{ name: "create", mutation: true, help: CREATE_HELP },
|
|
81
88
|
{ name: "copy", mutation: true, help: COPY_HELP },
|
|
82
89
|
{ name: "move", mutation: true, help: MOVE_HELP },
|
|
@@ -109,20 +116,22 @@ writes[${writes.length}]:
|
|
|
109
116
|
notes:
|
|
110
117
|
Writes require --account <email> when 2+ accounts are authenticated.
|
|
111
118
|
Reads use the default account when --account is not provided.
|
|
112
|
-
|
|
113
|
-
NOT_IMPLEMENTED after account resolution runs.
|
|
119
|
+
upload is live; the remaining write subcommands are scaffolded for the
|
|
120
|
+
next slice and throw NOT_IMPLEMENTED after account resolution runs.
|
|
114
121
|
subcommand help:
|
|
115
122
|
gws-axi drive ls --help for folder listing (incl. --recursive)
|
|
116
123
|
gws-axi drive get --help for full file metadata
|
|
117
124
|
gws-axi drive search --help for full-text search
|
|
118
125
|
gws-axi drive permissions --help for access / sharing
|
|
119
126
|
gws-axi drive download --help for fetching bytes (alias of docs download)
|
|
127
|
+
gws-axi drive upload --help for uploading a local file (incl. --convert)
|
|
120
128
|
examples:
|
|
121
129
|
gws-axi drive ls
|
|
122
130
|
gws-axi drive ls <folder-id> --recursive
|
|
123
131
|
gws-axi drive search --query "project plan"
|
|
124
132
|
gws-axi drive get <file-id>
|
|
125
133
|
gws-axi drive permissions <file-id>
|
|
134
|
+
gws-axi drive upload ./report.pdf --account you@example.com
|
|
126
135
|
`;
|
|
127
136
|
export async function driveCommand(args) {
|
|
128
137
|
if (args.length === 0 || (args.length === 1 && args[0] === "--help")) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drive.js","sourceRoot":"","sources":["../../../src/commands/drive.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"drive.js","sourceRoot":"","sources":["../../../src/commands/drive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const DEFAULT_MIME_TYPE = "application/octet-stream";
|
|
2
|
+
/**
|
|
3
|
+
* Detect a MIME type from a file path's extension. Case-insensitive; returns
|
|
4
|
+
* `application/octet-stream` for unknown or absent extensions.
|
|
5
|
+
*/
|
|
6
|
+
export declare function detectMimeType(path: string): string;
|
|
7
|
+
export declare function googleConversionTarget(sourceMime: string): string | null;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { extname } from "node:path";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal extension → MIME table for `drive upload`. Node has no built-in
|
|
4
|
+
* MIME lookup, and pulling in a full database is overkill: this covers the
|
|
5
|
+
* office/document/text/image/archive types an agent actually uploads. Unknown
|
|
6
|
+
* extensions fall back to `application/octet-stream` (a safe generic binary
|
|
7
|
+
* type Drive accepts), so detection never throws — it only ever under-labels.
|
|
8
|
+
*/
|
|
9
|
+
const EXTENSION_MIME = {
|
|
10
|
+
// Office (OOXML)
|
|
11
|
+
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
12
|
+
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
13
|
+
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
14
|
+
// Office (legacy)
|
|
15
|
+
doc: "application/msword",
|
|
16
|
+
xls: "application/vnd.ms-excel",
|
|
17
|
+
ppt: "application/vnd.ms-powerpoint",
|
|
18
|
+
// Text & delimited
|
|
19
|
+
txt: "text/plain",
|
|
20
|
+
md: "text/markdown",
|
|
21
|
+
markdown: "text/markdown",
|
|
22
|
+
csv: "text/csv",
|
|
23
|
+
tsv: "text/tab-separated-values",
|
|
24
|
+
rtf: "application/rtf",
|
|
25
|
+
html: "text/html",
|
|
26
|
+
htm: "text/html",
|
|
27
|
+
json: "application/json",
|
|
28
|
+
xml: "application/xml",
|
|
29
|
+
yaml: "application/yaml",
|
|
30
|
+
yml: "application/yaml",
|
|
31
|
+
// Documents
|
|
32
|
+
pdf: "application/pdf",
|
|
33
|
+
// Images
|
|
34
|
+
png: "image/png",
|
|
35
|
+
jpg: "image/jpeg",
|
|
36
|
+
jpeg: "image/jpeg",
|
|
37
|
+
gif: "image/gif",
|
|
38
|
+
webp: "image/webp",
|
|
39
|
+
svg: "image/svg+xml",
|
|
40
|
+
bmp: "image/bmp",
|
|
41
|
+
tif: "image/tiff",
|
|
42
|
+
tiff: "image/tiff",
|
|
43
|
+
heic: "image/heic",
|
|
44
|
+
// Audio / video
|
|
45
|
+
mp3: "audio/mpeg",
|
|
46
|
+
wav: "audio/wav",
|
|
47
|
+
mp4: "video/mp4",
|
|
48
|
+
mov: "video/quicktime",
|
|
49
|
+
// Archives
|
|
50
|
+
zip: "application/zip",
|
|
51
|
+
gz: "application/gzip",
|
|
52
|
+
tar: "application/x-tar",
|
|
53
|
+
};
|
|
54
|
+
export const DEFAULT_MIME_TYPE = "application/octet-stream";
|
|
55
|
+
/**
|
|
56
|
+
* Detect a MIME type from a file path's extension. Case-insensitive; returns
|
|
57
|
+
* `application/octet-stream` for unknown or absent extensions.
|
|
58
|
+
*/
|
|
59
|
+
export function detectMimeType(path) {
|
|
60
|
+
const ext = extname(path).replace(/^\./, "").toLowerCase();
|
|
61
|
+
if (!ext)
|
|
62
|
+
return DEFAULT_MIME_TYPE;
|
|
63
|
+
return EXTENSION_MIME[ext] ?? DEFAULT_MIME_TYPE;
|
|
64
|
+
}
|
|
65
|
+
const GOOGLE_DOC = "application/vnd.google-apps.document";
|
|
66
|
+
const GOOGLE_SHEET = "application/vnd.google-apps.spreadsheet";
|
|
67
|
+
const GOOGLE_SLIDES = "application/vnd.google-apps.presentation";
|
|
68
|
+
/**
|
|
69
|
+
* Map a source MIME type to the native Google Workspace target Drive can
|
|
70
|
+
* convert it into on upload (the `--convert` flag). Returns `null` when the
|
|
71
|
+
* source has no sensible native target — the caller surfaces
|
|
72
|
+
* `UNSUPPORTED_CONVERSION`.
|
|
73
|
+
*/
|
|
74
|
+
const CONVERSION_TARGETS = {
|
|
75
|
+
// → Google Doc
|
|
76
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": GOOGLE_DOC,
|
|
77
|
+
"application/msword": GOOGLE_DOC,
|
|
78
|
+
"application/rtf": GOOGLE_DOC,
|
|
79
|
+
"text/rtf": GOOGLE_DOC,
|
|
80
|
+
"text/plain": GOOGLE_DOC,
|
|
81
|
+
"text/markdown": GOOGLE_DOC,
|
|
82
|
+
"text/html": GOOGLE_DOC,
|
|
83
|
+
// → Google Sheet
|
|
84
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": GOOGLE_SHEET,
|
|
85
|
+
"application/vnd.ms-excel": GOOGLE_SHEET,
|
|
86
|
+
"text/csv": GOOGLE_SHEET,
|
|
87
|
+
"text/tab-separated-values": GOOGLE_SHEET,
|
|
88
|
+
// → Google Slides
|
|
89
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation": GOOGLE_SLIDES,
|
|
90
|
+
"application/vnd.ms-powerpoint": GOOGLE_SLIDES,
|
|
91
|
+
};
|
|
92
|
+
export function googleConversionTarget(sourceMime) {
|
|
93
|
+
return CONVERSION_TARGETS[sourceMime.toLowerCase()] ?? null;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=mime-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mime-types.js","sourceRoot":"","sources":["../../../src/util/mime-types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;;;;;GAMG;AACH,MAAM,cAAc,GAA2B;IAC7C,iBAAiB;IACjB,IAAI,EAAE,yEAAyE;IAC/E,IAAI,EAAE,mEAAmE;IACzE,IAAI,EAAE,2EAA2E;IACjF,kBAAkB;IAClB,GAAG,EAAE,oBAAoB;IACzB,GAAG,EAAE,0BAA0B;IAC/B,GAAG,EAAE,+BAA+B;IACpC,mBAAmB;IACnB,GAAG,EAAE,YAAY;IACjB,EAAE,EAAE,eAAe;IACnB,QAAQ,EAAE,eAAe;IACzB,GAAG,EAAE,UAAU;IACf,GAAG,EAAE,2BAA2B;IAChC,GAAG,EAAE,iBAAiB;IACtB,IAAI,EAAE,WAAW;IACjB,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,kBAAkB;IACxB,GAAG,EAAE,iBAAiB;IACtB,IAAI,EAAE,kBAAkB;IACxB,GAAG,EAAE,kBAAkB;IACvB,YAAY;IACZ,GAAG,EAAE,iBAAiB;IACtB,SAAS;IACT,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,YAAY;IACjB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,eAAe;IACpB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,YAAY;IACjB,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,YAAY;IAClB,gBAAgB;IAChB,GAAG,EAAE,YAAY;IACjB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,iBAAiB;IACtB,WAAW;IACX,GAAG,EAAE,iBAAiB;IACtB,EAAE,EAAE,kBAAkB;IACtB,GAAG,EAAE,mBAAmB;CACzB,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,0BAA0B,CAAC;AAE5D;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3D,IAAI,CAAC,GAAG;QAAE,OAAO,iBAAiB,CAAC;IACnC,OAAO,cAAc,CAAC,GAAG,CAAC,IAAI,iBAAiB,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,GAAG,sCAAsC,CAAC;AAC1D,MAAM,YAAY,GAAG,yCAAyC,CAAC;AAC/D,MAAM,aAAa,GAAG,0CAA0C,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,kBAAkB,GAA2B;IACjD,eAAe;IACf,yEAAyE,EACvE,UAAU;IACZ,oBAAoB,EAAE,UAAU;IAChC,iBAAiB,EAAE,UAAU;IAC7B,UAAU,EAAE,UAAU;IACtB,YAAY,EAAE,UAAU;IACxB,eAAe,EAAE,UAAU;IAC3B,WAAW,EAAE,UAAU;IACvB,iBAAiB;IACjB,mEAAmE,EACjE,YAAY;IACd,0BAA0B,EAAE,YAAY;IACxC,UAAU,EAAE,YAAY;IACxB,2BAA2B,EAAE,YAAY;IACzC,kBAAkB;IAClB,2EAA2E,EACzE,aAAa;IACf,+BAA+B,EAAE,aAAa;CAC/C,CAAC;AAEF,MAAM,UAAU,sBAAsB,CAAC,UAAkB;IACvD,OAAO,kBAAkB,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,IAAI,IAAI,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { DEFAULT_MIME_TYPE, detectMimeType, googleConversionTarget, } from "./mime-types.js";
|
|
3
|
+
describe("detectMimeType", () => {
|
|
4
|
+
it("maps common office and document extensions", () => {
|
|
5
|
+
expect(detectMimeType("report.docx")).toBe("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
|
|
6
|
+
expect(detectMimeType("data.xlsx")).toBe("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
|
7
|
+
expect(detectMimeType("deck.pptx")).toBe("application/vnd.openxmlformats-officedocument.presentationml.presentation");
|
|
8
|
+
expect(detectMimeType("notes.pdf")).toBe("application/pdf");
|
|
9
|
+
expect(detectMimeType("rows.csv")).toBe("text/csv");
|
|
10
|
+
});
|
|
11
|
+
it("is case-insensitive on the extension", () => {
|
|
12
|
+
expect(detectMimeType("PHOTO.JPG")).toBe("image/jpeg");
|
|
13
|
+
expect(detectMimeType("Report.DOCX")).toBe("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
|
|
14
|
+
});
|
|
15
|
+
it("resolves full and relative paths by their extension", () => {
|
|
16
|
+
expect(detectMimeType("/home/me/pics/cat.png")).toBe("image/png");
|
|
17
|
+
expect(detectMimeType("./sub/dir/file.md")).toBe("text/markdown");
|
|
18
|
+
});
|
|
19
|
+
it("falls back to octet-stream for unknown or absent extensions", () => {
|
|
20
|
+
expect(detectMimeType("mystery.xyz")).toBe(DEFAULT_MIME_TYPE);
|
|
21
|
+
expect(detectMimeType("Makefile")).toBe(DEFAULT_MIME_TYPE);
|
|
22
|
+
expect(detectMimeType("archive.")).toBe(DEFAULT_MIME_TYPE);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
describe("googleConversionTarget", () => {
|
|
26
|
+
it("maps word-processing and text sources to Google Doc", () => {
|
|
27
|
+
expect(googleConversionTarget("application/vnd.openxmlformats-officedocument.wordprocessingml.document")).toBe("application/vnd.google-apps.document");
|
|
28
|
+
expect(googleConversionTarget("text/plain")).toBe("application/vnd.google-apps.document");
|
|
29
|
+
expect(googleConversionTarget("text/markdown")).toBe("application/vnd.google-apps.document");
|
|
30
|
+
});
|
|
31
|
+
it("maps spreadsheet and delimited sources to Google Sheet", () => {
|
|
32
|
+
expect(googleConversionTarget("text/csv")).toBe("application/vnd.google-apps.spreadsheet");
|
|
33
|
+
expect(googleConversionTarget("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")).toBe("application/vnd.google-apps.spreadsheet");
|
|
34
|
+
});
|
|
35
|
+
it("maps presentation sources to Google Slides", () => {
|
|
36
|
+
expect(googleConversionTarget("application/vnd.ms-powerpoint")).toBe("application/vnd.google-apps.presentation");
|
|
37
|
+
});
|
|
38
|
+
it("is case-insensitive on the source mime", () => {
|
|
39
|
+
expect(googleConversionTarget("TEXT/CSV")).toBe("application/vnd.google-apps.spreadsheet");
|
|
40
|
+
});
|
|
41
|
+
it("returns null for unsupported source types", () => {
|
|
42
|
+
expect(googleConversionTarget("application/pdf")).toBeNull();
|
|
43
|
+
expect(googleConversionTarget("image/png")).toBeNull();
|
|
44
|
+
expect(googleConversionTarget("application/zip")).toBeNull();
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
//# sourceMappingURL=mime-types.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mime-types.test.js","sourceRoot":"","sources":["../../../src/util/mime-types.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gws-axi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "AXI-compliant Google Workspace CLI — token-efficient TOON output, agent-guided auth setup, unified interface for Gmail, Calendar, Docs, Drive, Slides",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|