vslides 1.0.17 → 1.0.18
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/cli.js +174 -12
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -974,7 +974,7 @@ var require_command = __commonJS({
|
|
|
974
974
|
var { Help: Help2 } = require_help();
|
|
975
975
|
var { Option: Option2, DualOptions } = require_option();
|
|
976
976
|
var { suggestSimilar } = require_suggestSimilar();
|
|
977
|
-
var
|
|
977
|
+
var Command3 = class _Command extends EventEmitter {
|
|
978
978
|
/**
|
|
979
979
|
* Initialize a new `Command`.
|
|
980
980
|
*
|
|
@@ -3031,7 +3031,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3031
3031
|
return arg;
|
|
3032
3032
|
});
|
|
3033
3033
|
}
|
|
3034
|
-
exports2.Command =
|
|
3034
|
+
exports2.Command = Command3;
|
|
3035
3035
|
}
|
|
3036
3036
|
});
|
|
3037
3037
|
|
|
@@ -3039,15 +3039,15 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3039
3039
|
var require_commander = __commonJS({
|
|
3040
3040
|
"node_modules/commander/index.js"(exports2) {
|
|
3041
3041
|
var { Argument: Argument2 } = require_argument();
|
|
3042
|
-
var { Command:
|
|
3042
|
+
var { Command: Command3 } = require_command();
|
|
3043
3043
|
var { CommanderError: CommanderError2, InvalidArgumentError: InvalidArgumentError2 } = require_error();
|
|
3044
3044
|
var { Help: Help2 } = require_help();
|
|
3045
3045
|
var { Option: Option2 } = require_option();
|
|
3046
|
-
exports2.program = new
|
|
3047
|
-
exports2.createCommand = (name) => new
|
|
3046
|
+
exports2.program = new Command3();
|
|
3047
|
+
exports2.createCommand = (name) => new Command3(name);
|
|
3048
3048
|
exports2.createOption = (flags, description) => new Option2(flags, description);
|
|
3049
3049
|
exports2.createArgument = (name, description) => new Argument2(name, description);
|
|
3050
|
-
exports2.Command =
|
|
3050
|
+
exports2.Command = Command3;
|
|
3051
3051
|
exports2.Option = Option2;
|
|
3052
3052
|
exports2.Argument = Argument2;
|
|
3053
3053
|
exports2.Help = Help2;
|
|
@@ -3126,8 +3126,8 @@ function clearCLIAuth() {
|
|
|
3126
3126
|
if ((0, import_node_fs.existsSync)(AUTH_FILE)) {
|
|
3127
3127
|
try {
|
|
3128
3128
|
(0, import_node_fs.writeFileSync)(AUTH_FILE, "{}");
|
|
3129
|
-
const { unlinkSync:
|
|
3130
|
-
|
|
3129
|
+
const { unlinkSync: unlinkSync3 } = require("node:fs");
|
|
3130
|
+
unlinkSync3(AUTH_FILE);
|
|
3131
3131
|
} catch {
|
|
3132
3132
|
}
|
|
3133
3133
|
}
|
|
@@ -3362,6 +3362,34 @@ async function reconnectSession(slug, cliAuthToken) {
|
|
|
3362
3362
|
body: JSON.stringify({})
|
|
3363
3363
|
});
|
|
3364
3364
|
}
|
|
3365
|
+
async function getProfile(cliAuthToken) {
|
|
3366
|
+
return request("/api/auth/cli/profile", {
|
|
3367
|
+
headers: {
|
|
3368
|
+
"X-CLI-Auth-Token": cliAuthToken
|
|
3369
|
+
}
|
|
3370
|
+
});
|
|
3371
|
+
}
|
|
3372
|
+
async function setProfileField(cliAuthToken, field, value) {
|
|
3373
|
+
return request("/api/auth/cli/profile", {
|
|
3374
|
+
method: "POST",
|
|
3375
|
+
headers: {
|
|
3376
|
+
"X-CLI-Auth-Token": cliAuthToken,
|
|
3377
|
+
"Content-Type": "application/json"
|
|
3378
|
+
},
|
|
3379
|
+
body: JSON.stringify({ field, value })
|
|
3380
|
+
});
|
|
3381
|
+
}
|
|
3382
|
+
async function uploadProfileImage(cliAuthToken, filename, content) {
|
|
3383
|
+
return request("/api/auth/cli/profile/upload", {
|
|
3384
|
+
method: "POST",
|
|
3385
|
+
headers: {
|
|
3386
|
+
"X-CLI-Auth-Token": cliAuthToken,
|
|
3387
|
+
"X-Filename": filename,
|
|
3388
|
+
"Content-Type": "application/octet-stream"
|
|
3389
|
+
},
|
|
3390
|
+
body: content.toString("base64")
|
|
3391
|
+
});
|
|
3392
|
+
}
|
|
3365
3393
|
|
|
3366
3394
|
// src/lib/config.ts
|
|
3367
3395
|
var import_node_fs2 = require("node:fs");
|
|
@@ -3540,7 +3568,8 @@ var ExitCode = {
|
|
|
3540
3568
|
Conflict: 1,
|
|
3541
3569
|
AuthRequired: 2,
|
|
3542
3570
|
NetworkError: 3,
|
|
3543
|
-
ValidationError: 4
|
|
3571
|
+
ValidationError: 4,
|
|
3572
|
+
UsageError: 5
|
|
3544
3573
|
};
|
|
3545
3574
|
|
|
3546
3575
|
// src/commands/init.ts
|
|
@@ -4410,6 +4439,104 @@ async function logout() {
|
|
|
4410
4439
|
}
|
|
4411
4440
|
|
|
4412
4441
|
// src/commands/whoami.ts
|
|
4442
|
+
var import_node_fs6 = require("node:fs");
|
|
4443
|
+
var import_node_path5 = require("node:path");
|
|
4444
|
+
|
|
4445
|
+
// src/lib/profile.ts
|
|
4446
|
+
var import_node_fs5 = require("node:fs");
|
|
4447
|
+
var import_node_path4 = require("node:path");
|
|
4448
|
+
var import_node_os3 = require("node:os");
|
|
4449
|
+
var PROFILE_DIR = (0, import_node_path4.join)((0, import_node_os3.homedir)(), ".vslides");
|
|
4450
|
+
var PROFILE_FILE = (0, import_node_path4.join)(PROFILE_DIR, "profile.json");
|
|
4451
|
+
function ensureProfileDir() {
|
|
4452
|
+
if (!(0, import_node_fs5.existsSync)(PROFILE_DIR)) {
|
|
4453
|
+
(0, import_node_fs5.mkdirSync)(PROFILE_DIR, { mode: 448 });
|
|
4454
|
+
}
|
|
4455
|
+
}
|
|
4456
|
+
function getCachedProfile() {
|
|
4457
|
+
if (!(0, import_node_fs5.existsSync)(PROFILE_FILE)) {
|
|
4458
|
+
return null;
|
|
4459
|
+
}
|
|
4460
|
+
try {
|
|
4461
|
+
const content = (0, import_node_fs5.readFileSync)(PROFILE_FILE, "utf-8");
|
|
4462
|
+
const profile = JSON.parse(content);
|
|
4463
|
+
if (typeof profile !== "object" || profile === null) {
|
|
4464
|
+
return null;
|
|
4465
|
+
}
|
|
4466
|
+
return {
|
|
4467
|
+
name: profile.name ?? "",
|
|
4468
|
+
image: profile.image ?? "",
|
|
4469
|
+
role: profile.role ?? ""
|
|
4470
|
+
};
|
|
4471
|
+
} catch {
|
|
4472
|
+
return null;
|
|
4473
|
+
}
|
|
4474
|
+
}
|
|
4475
|
+
function saveCachedProfile(profile) {
|
|
4476
|
+
ensureProfileDir();
|
|
4477
|
+
(0, import_node_fs5.writeFileSync)(PROFILE_FILE, JSON.stringify(profile, null, 2) + "\n", { mode: 384 });
|
|
4478
|
+
(0, import_node_fs5.chmodSync)(PROFILE_FILE, 384);
|
|
4479
|
+
}
|
|
4480
|
+
|
|
4481
|
+
// src/commands/whoami.ts
|
|
4482
|
+
var VALID_FIELDS = ["name", "image", "role"];
|
|
4483
|
+
function isValidField(field) {
|
|
4484
|
+
return VALID_FIELDS.includes(field);
|
|
4485
|
+
}
|
|
4486
|
+
function isUrl(value) {
|
|
4487
|
+
return value.startsWith("http://") || value.startsWith("https://");
|
|
4488
|
+
}
|
|
4489
|
+
async function handleSet(token, field, value) {
|
|
4490
|
+
if (!isValidField(field)) {
|
|
4491
|
+
error(`Invalid field: ${field}`);
|
|
4492
|
+
info(`Valid fields: ${VALID_FIELDS.join(", ")}`);
|
|
4493
|
+
process.exit(ExitCode.UsageError);
|
|
4494
|
+
}
|
|
4495
|
+
if (field === "image") {
|
|
4496
|
+
if (isUrl(value)) {
|
|
4497
|
+
const result = await setProfileField(token, "image", value);
|
|
4498
|
+
if (!result.ok) {
|
|
4499
|
+
error("Failed to update profile");
|
|
4500
|
+
process.exit(ExitCode.NetworkError);
|
|
4501
|
+
}
|
|
4502
|
+
success(`Image updated to: ${value}`);
|
|
4503
|
+
saveCachedProfile({ name: result.data.name, image: result.data.image, role: result.data.role });
|
|
4504
|
+
} else {
|
|
4505
|
+
if (!(0, import_node_fs6.existsSync)(value)) {
|
|
4506
|
+
error(`File not found: ${value}`);
|
|
4507
|
+
process.exit(ExitCode.UsageError);
|
|
4508
|
+
}
|
|
4509
|
+
const content = (0, import_node_fs6.readFileSync)(value);
|
|
4510
|
+
const filename = (0, import_node_path5.basename)(value);
|
|
4511
|
+
info(`Uploading ${filename}...`);
|
|
4512
|
+
const uploadResult = await uploadProfileImage(token, filename, content);
|
|
4513
|
+
if (!uploadResult.ok) {
|
|
4514
|
+
const errorData = uploadResult.data;
|
|
4515
|
+
error(errorData.error || "Failed to upload image");
|
|
4516
|
+
info("Tip: You can also provide an image URL directly");
|
|
4517
|
+
process.exit(ExitCode.NetworkError);
|
|
4518
|
+
}
|
|
4519
|
+
success(`Image uploaded: ${uploadResult.data.url}`);
|
|
4520
|
+
const profileResult = await getProfile(token);
|
|
4521
|
+
if (profileResult.ok) {
|
|
4522
|
+
saveCachedProfile({
|
|
4523
|
+
name: profileResult.data.name,
|
|
4524
|
+
image: profileResult.data.image,
|
|
4525
|
+
role: profileResult.data.role
|
|
4526
|
+
});
|
|
4527
|
+
}
|
|
4528
|
+
}
|
|
4529
|
+
} else {
|
|
4530
|
+
const result = await setProfileField(token, field, value);
|
|
4531
|
+
if (!result.ok) {
|
|
4532
|
+
const errorData = result.data;
|
|
4533
|
+
error(errorData.error || "Failed to update profile");
|
|
4534
|
+
process.exit(ExitCode.NetworkError);
|
|
4535
|
+
}
|
|
4536
|
+
success(`${field.charAt(0).toUpperCase() + field.slice(1)} updated to: ${value}`);
|
|
4537
|
+
saveCachedProfile({ name: result.data.name, image: result.data.image, role: result.data.role });
|
|
4538
|
+
}
|
|
4539
|
+
}
|
|
4413
4540
|
async function whoami(options = {}) {
|
|
4414
4541
|
const cachedAuth = getCachedAuth();
|
|
4415
4542
|
if (!cachedAuth) {
|
|
@@ -4422,6 +4549,12 @@ async function whoami(options = {}) {
|
|
|
4422
4549
|
instructions(["Run `vslides login` to re-authenticate"]);
|
|
4423
4550
|
process.exit(ExitCode.AuthRequired);
|
|
4424
4551
|
}
|
|
4552
|
+
if (options.set && options.args && options.args.length >= 2) {
|
|
4553
|
+
const [field, ...valueParts] = options.args;
|
|
4554
|
+
const value = valueParts.join(" ");
|
|
4555
|
+
await handleSet(cachedAuth.token, field, value);
|
|
4556
|
+
return;
|
|
4557
|
+
}
|
|
4425
4558
|
if (options.validate) {
|
|
4426
4559
|
const result = await validateCLIAuth(cachedAuth.token);
|
|
4427
4560
|
if (!result.ok || !result.data.valid) {
|
|
@@ -4430,10 +4563,31 @@ async function whoami(options = {}) {
|
|
|
4430
4563
|
process.exit(ExitCode.AuthRequired);
|
|
4431
4564
|
}
|
|
4432
4565
|
}
|
|
4566
|
+
const profileResult = await getProfile(cachedAuth.token);
|
|
4567
|
+
let profile = getCachedProfile();
|
|
4568
|
+
if (profileResult.ok) {
|
|
4569
|
+
profile = {
|
|
4570
|
+
name: profileResult.data.name,
|
|
4571
|
+
image: profileResult.data.image,
|
|
4572
|
+
role: profileResult.data.role
|
|
4573
|
+
};
|
|
4574
|
+
saveCachedProfile(profile);
|
|
4575
|
+
} else if (!profile) {
|
|
4576
|
+
profile = { name: "", image: "", role: "" };
|
|
4577
|
+
}
|
|
4433
4578
|
const daysLeft = Math.ceil((cachedAuth.expiresAt - Date.now()) / (24 * 60 * 60 * 1e3));
|
|
4434
|
-
const expiresDate = new Date(cachedAuth.expiresAt).toLocaleDateString(
|
|
4435
|
-
|
|
4579
|
+
const expiresDate = new Date(cachedAuth.expiresAt).toLocaleDateString("en-US", {
|
|
4580
|
+
month: "short",
|
|
4581
|
+
day: "numeric",
|
|
4582
|
+
year: "numeric"
|
|
4583
|
+
});
|
|
4584
|
+
info(`Name: ${profile.name || "(not set)"}`);
|
|
4585
|
+
info(`Image: ${profile.image || "(not set)"}`);
|
|
4586
|
+
info(`Role: ${profile.role || "(not set)"}`);
|
|
4587
|
+
info(`Email: ${cachedAuth.email}`);
|
|
4436
4588
|
info(`Expires: ${expiresDate} (${daysLeft} day${daysLeft === 1 ? "" : "s"} remaining)`);
|
|
4589
|
+
newline();
|
|
4590
|
+
info("Tip: Use `vslides whoami --set <field> <value>` to update your profile");
|
|
4437
4591
|
}
|
|
4438
4592
|
|
|
4439
4593
|
// src/cli.ts
|
|
@@ -4456,7 +4610,15 @@ function wrapCommand(fn) {
|
|
|
4456
4610
|
program.name("vslides").description("CLI for Vercel Slides API").version("1.0.0");
|
|
4457
4611
|
program.command("login").description("Authenticate with Vercel (valid for 7 days)").option("--wait", "Wait for authentication to complete (2 min timeout)").action(wrapCommand((options) => login(options)));
|
|
4458
4612
|
program.command("logout").description("Sign out and revoke credentials").action(wrapCommand(logout));
|
|
4459
|
-
program.command("whoami").description("Show current authentication status").option("--validate", "Validate token with server").
|
|
4613
|
+
program.command("whoami").description("Show current authentication status").option("--validate", "Validate token with server").option("--set <field> <value...>", false).action(
|
|
4614
|
+
wrapCommand((options) => {
|
|
4615
|
+
if (options.set && Array.isArray(options.set)) {
|
|
4616
|
+
const [field, ...valueParts] = options.set;
|
|
4617
|
+
return whoami({ ...options, set: true, args: [field, ...valueParts] });
|
|
4618
|
+
}
|
|
4619
|
+
return whoami(options);
|
|
4620
|
+
})
|
|
4621
|
+
);
|
|
4460
4622
|
program.command("init").description("Create a new session").action(wrapCommand(init));
|
|
4461
4623
|
program.command("check").description("Check session status").option("--wait", "Poll until running (60s timeout)").action(wrapCommand((options) => check(options)));
|
|
4462
4624
|
program.command("join <url>").description("Join a shared session").action(wrapCommand(join3));
|