@bagdock/cli 0.1.3 → 0.2.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/bagdock.js +571 -141
- package/package.json +12 -2
package/dist/bagdock.js
CHANGED
|
@@ -3158,6 +3158,200 @@ var init_open = __esm(() => {
|
|
|
3158
3158
|
open_default = open;
|
|
3159
3159
|
});
|
|
3160
3160
|
|
|
3161
|
+
// src/auth.ts
|
|
3162
|
+
function setApiKeyOverride(key) {
|
|
3163
|
+
apiKeyOverride = key;
|
|
3164
|
+
}
|
|
3165
|
+
function getAuthToken() {
|
|
3166
|
+
if (apiKeyOverride)
|
|
3167
|
+
return apiKeyOverride;
|
|
3168
|
+
if (process.env.BAGDOCK_API_KEY)
|
|
3169
|
+
return process.env.BAGDOCK_API_KEY;
|
|
3170
|
+
if (process.env.BAGDOCK_TOKEN)
|
|
3171
|
+
return process.env.BAGDOCK_TOKEN;
|
|
3172
|
+
const creds = loadCredentials();
|
|
3173
|
+
return creds?.accessToken ?? null;
|
|
3174
|
+
}
|
|
3175
|
+
async function login() {
|
|
3176
|
+
const existing = loadCredentials();
|
|
3177
|
+
if (existing?.accessToken && existing.expiresAt && existing.expiresAt > Date.now()) {
|
|
3178
|
+
console.log(source_default.green("Already logged in as"), source_default.bold(existing.email ?? "unknown"));
|
|
3179
|
+
console.log("Run", source_default.cyan("bagdock logout"), "to sign out first.");
|
|
3180
|
+
return;
|
|
3181
|
+
}
|
|
3182
|
+
console.log(source_default.cyan(`
|
|
3183
|
+
Requesting device authorization...
|
|
3184
|
+
`));
|
|
3185
|
+
const deviceRes = await fetch(`${API_BASE}/oauth2/device/authorize`, {
|
|
3186
|
+
method: "POST",
|
|
3187
|
+
headers: { "Content-Type": "application/json" },
|
|
3188
|
+
body: JSON.stringify({ client_id: CLIENT_ID, scope: "developer:read developer:write" })
|
|
3189
|
+
});
|
|
3190
|
+
if (!deviceRes.ok) {
|
|
3191
|
+
const err = await deviceRes.text();
|
|
3192
|
+
console.log(source_default.red("Failed to start login:"), err);
|
|
3193
|
+
process.exit(1);
|
|
3194
|
+
}
|
|
3195
|
+
const device = await deviceRes.json();
|
|
3196
|
+
const pollInterval = (device.interval ?? 5) * 1000;
|
|
3197
|
+
console.log(` Visit ${source_default.bold(device.verification_uri)} and enter code:
|
|
3198
|
+
`);
|
|
3199
|
+
console.log(` ${source_default.bold.cyan(device.user_code)}
|
|
3200
|
+
`);
|
|
3201
|
+
const open2 = (await Promise.resolve().then(() => (init_open(), exports_open))).default;
|
|
3202
|
+
await open2(device.verification_uri_complete).catch(() => {});
|
|
3203
|
+
console.log(source_default.dim(" Waiting for authorization..."));
|
|
3204
|
+
const startedAt = Date.now();
|
|
3205
|
+
while (Date.now() - startedAt < MAX_POLL_DURATION_MS) {
|
|
3206
|
+
await sleep(pollInterval);
|
|
3207
|
+
const tokenRes = await fetch(`${API_BASE}/oauth2/token`, {
|
|
3208
|
+
method: "POST",
|
|
3209
|
+
headers: { "Content-Type": "application/json" },
|
|
3210
|
+
body: JSON.stringify({
|
|
3211
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
3212
|
+
client_id: CLIENT_ID,
|
|
3213
|
+
device_code: device.device_code
|
|
3214
|
+
})
|
|
3215
|
+
});
|
|
3216
|
+
if (tokenRes.ok) {
|
|
3217
|
+
const tokens = await tokenRes.json();
|
|
3218
|
+
saveCredentials({
|
|
3219
|
+
accessToken: tokens.access_token,
|
|
3220
|
+
refreshToken: tokens.refresh_token,
|
|
3221
|
+
expiresAt: tokens.expires_in ? Date.now() + tokens.expires_in * 1000 : undefined,
|
|
3222
|
+
email: tokens.email,
|
|
3223
|
+
operatorId: tokens.operator_id
|
|
3224
|
+
});
|
|
3225
|
+
console.log(source_default.green(`
|
|
3226
|
+
Logged in successfully!`));
|
|
3227
|
+
if (tokens.email)
|
|
3228
|
+
console.log(" Email:", source_default.bold(tokens.email));
|
|
3229
|
+
if (tokens.operator_id)
|
|
3230
|
+
console.log(" Operator:", source_default.bold(tokens.operator_id));
|
|
3231
|
+
return;
|
|
3232
|
+
}
|
|
3233
|
+
const error = await tokenRes.json().catch(() => ({ error: "unknown" }));
|
|
3234
|
+
if (error.error === "authorization_pending") {
|
|
3235
|
+
continue;
|
|
3236
|
+
}
|
|
3237
|
+
if (error.error === "slow_down") {
|
|
3238
|
+
await sleep(pollInterval);
|
|
3239
|
+
continue;
|
|
3240
|
+
}
|
|
3241
|
+
if (error.error === "expired_token") {
|
|
3242
|
+
console.log(source_default.red(`
|
|
3243
|
+
Device code expired. Please try again.`));
|
|
3244
|
+
process.exit(1);
|
|
3245
|
+
}
|
|
3246
|
+
if (error.error === "access_denied") {
|
|
3247
|
+
console.log(source_default.red(`
|
|
3248
|
+
Authorization denied.`));
|
|
3249
|
+
process.exit(1);
|
|
3250
|
+
}
|
|
3251
|
+
console.log(source_default.red(`
|
|
3252
|
+
Login failed:`), error.error_description ?? error.error);
|
|
3253
|
+
process.exit(1);
|
|
3254
|
+
}
|
|
3255
|
+
console.log(source_default.red(`
|
|
3256
|
+
Login timed out. Please try again.`));
|
|
3257
|
+
process.exit(1);
|
|
3258
|
+
}
|
|
3259
|
+
async function logout() {
|
|
3260
|
+
clearCredentials();
|
|
3261
|
+
console.log(source_default.green("Logged out."));
|
|
3262
|
+
}
|
|
3263
|
+
async function whoami() {
|
|
3264
|
+
const token = getAuthToken();
|
|
3265
|
+
if (!token) {
|
|
3266
|
+
console.log(source_default.yellow("Not logged in."), "Run", source_default.cyan("bagdock login"));
|
|
3267
|
+
process.exit(1);
|
|
3268
|
+
}
|
|
3269
|
+
try {
|
|
3270
|
+
const res = await fetch(`${API_BASE}/v1/auth/me`, {
|
|
3271
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
3272
|
+
});
|
|
3273
|
+
if (!res.ok) {
|
|
3274
|
+
console.log(source_default.red("Session expired or invalid."), "Run", source_default.cyan("bagdock login"));
|
|
3275
|
+
process.exit(1);
|
|
3276
|
+
}
|
|
3277
|
+
const user = await res.json();
|
|
3278
|
+
console.log(source_default.green("Logged in as"), source_default.bold(user.email));
|
|
3279
|
+
if (user.operator_id)
|
|
3280
|
+
console.log("Operator:", source_default.bold(user.operator_id));
|
|
3281
|
+
if (user.name)
|
|
3282
|
+
console.log("Name:", user.name);
|
|
3283
|
+
} catch (err) {
|
|
3284
|
+
console.log(source_default.red("Failed to reach API:"), err.message);
|
|
3285
|
+
process.exit(1);
|
|
3286
|
+
}
|
|
3287
|
+
}
|
|
3288
|
+
function sleep(ms) {
|
|
3289
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
3290
|
+
}
|
|
3291
|
+
var apiKeyOverride, CLIENT_ID = "bagdock-cli", MAX_POLL_DURATION_MS = 300000;
|
|
3292
|
+
var init_auth = __esm(() => {
|
|
3293
|
+
init_config();
|
|
3294
|
+
init_source();
|
|
3295
|
+
});
|
|
3296
|
+
|
|
3297
|
+
// src/output.ts
|
|
3298
|
+
function setOutputMode(opts) {
|
|
3299
|
+
if (opts.quiet) {
|
|
3300
|
+
quiet = true;
|
|
3301
|
+
forceJson = true;
|
|
3302
|
+
}
|
|
3303
|
+
if (opts.json) {
|
|
3304
|
+
forceJson = true;
|
|
3305
|
+
}
|
|
3306
|
+
}
|
|
3307
|
+
function isJsonMode() {
|
|
3308
|
+
return forceJson || !process.stdout.isTTY;
|
|
3309
|
+
}
|
|
3310
|
+
function isQuiet() {
|
|
3311
|
+
return quiet;
|
|
3312
|
+
}
|
|
3313
|
+
function outputSuccess(data) {
|
|
3314
|
+
if (isJsonMode()) {
|
|
3315
|
+
process.stdout.write(JSON.stringify(data, null, 2) + `
|
|
3316
|
+
`);
|
|
3317
|
+
}
|
|
3318
|
+
}
|
|
3319
|
+
function outputError(code, message, details) {
|
|
3320
|
+
if (isJsonMode()) {
|
|
3321
|
+
const err = { error: { code, message } };
|
|
3322
|
+
if (details)
|
|
3323
|
+
err.error.details = details;
|
|
3324
|
+
process.stderr.write(JSON.stringify(err) + `
|
|
3325
|
+
`);
|
|
3326
|
+
process.exit(1);
|
|
3327
|
+
} else {
|
|
3328
|
+
console.error(source_default.red(`Error [${code}]:`), message);
|
|
3329
|
+
if (details)
|
|
3330
|
+
console.error(details);
|
|
3331
|
+
process.exit(1);
|
|
3332
|
+
}
|
|
3333
|
+
}
|
|
3334
|
+
function outputList(objectType, data, hasMore) {
|
|
3335
|
+
if (isJsonMode()) {
|
|
3336
|
+
process.stdout.write(JSON.stringify({ object: "list", data, has_more: hasMore }, null, 2) + `
|
|
3337
|
+
`);
|
|
3338
|
+
}
|
|
3339
|
+
}
|
|
3340
|
+
function status(message) {
|
|
3341
|
+
if (!isQuiet() && !isJsonMode()) {
|
|
3342
|
+
console.log(source_default.dim(message));
|
|
3343
|
+
}
|
|
3344
|
+
}
|
|
3345
|
+
function success(message) {
|
|
3346
|
+
if (!isQuiet() && !isJsonMode()) {
|
|
3347
|
+
console.log(source_default.green(message));
|
|
3348
|
+
}
|
|
3349
|
+
}
|
|
3350
|
+
var forceJson = false, quiet = false;
|
|
3351
|
+
var init_output = __esm(() => {
|
|
3352
|
+
init_source();
|
|
3353
|
+
});
|
|
3354
|
+
|
|
3161
3355
|
// src/dev.ts
|
|
3162
3356
|
var exports_dev = {};
|
|
3163
3357
|
__export(exports_dev, {
|
|
@@ -3251,9 +3445,9 @@ async function deploy(opts) {
|
|
|
3251
3445
|
console.error(source_default.red("No bagdock.json found. Run"), source_default.cyan("bagdock init"), source_default.red("first."));
|
|
3252
3446
|
process.exit(1);
|
|
3253
3447
|
}
|
|
3254
|
-
const
|
|
3255
|
-
if (!
|
|
3256
|
-
console.error(source_default.red("Not authenticated. Run"), source_default.cyan("bagdock login"), source_default.red("
|
|
3448
|
+
const token = getAuthToken();
|
|
3449
|
+
if (!token) {
|
|
3450
|
+
console.error(source_default.red("Not authenticated. Run"), source_default.cyan("bagdock login"), source_default.red("or set BAGDOCK_API_KEY."));
|
|
3257
3451
|
process.exit(1);
|
|
3258
3452
|
}
|
|
3259
3453
|
let environment = opts.env ?? "staging";
|
|
@@ -3318,7 +3512,7 @@ Deploying ${config.slug}@${config.version} → ${envLabel}
|
|
|
3318
3512
|
const res = await fetch(`${API_BASE}/api/v1/developer/apps/${config.slug}/deploy`, {
|
|
3319
3513
|
method: "POST",
|
|
3320
3514
|
headers: {
|
|
3321
|
-
Authorization: `Bearer ${
|
|
3515
|
+
Authorization: `Bearer ${token}`
|
|
3322
3516
|
},
|
|
3323
3517
|
body: formData
|
|
3324
3518
|
});
|
|
@@ -3374,6 +3568,7 @@ function confirm(prompt) {
|
|
|
3374
3568
|
var init_deploy = __esm(() => {
|
|
3375
3569
|
init_source();
|
|
3376
3570
|
init_config();
|
|
3571
|
+
init_auth();
|
|
3377
3572
|
});
|
|
3378
3573
|
|
|
3379
3574
|
// src/submit.ts
|
|
@@ -3387,9 +3582,9 @@ async function submit() {
|
|
|
3387
3582
|
console.error(source_default.red("No bagdock.json found. Run"), source_default.cyan("bagdock init"), source_default.red("first."));
|
|
3388
3583
|
process.exit(1);
|
|
3389
3584
|
}
|
|
3390
|
-
const
|
|
3391
|
-
if (!
|
|
3392
|
-
console.error(source_default.red("Not authenticated. Run"), source_default.cyan("bagdock login"), source_default.red("
|
|
3585
|
+
const token = getAuthToken();
|
|
3586
|
+
if (!token) {
|
|
3587
|
+
console.error(source_default.red("Not authenticated. Run"), source_default.cyan("bagdock login"), source_default.red("or set BAGDOCK_API_KEY."));
|
|
3393
3588
|
process.exit(1);
|
|
3394
3589
|
}
|
|
3395
3590
|
console.log(source_default.cyan(`
|
|
@@ -3399,7 +3594,7 @@ Submitting ${source_default.bold(config.slug)} for marketplace review...
|
|
|
3399
3594
|
const res = await fetch(`${API_BASE}/api/v1/developer/apps/${config.slug}/submit`, {
|
|
3400
3595
|
method: "POST",
|
|
3401
3596
|
headers: {
|
|
3402
|
-
Authorization: `Bearer ${
|
|
3597
|
+
Authorization: `Bearer ${token}`,
|
|
3403
3598
|
"Content-Type": "application/json"
|
|
3404
3599
|
}
|
|
3405
3600
|
});
|
|
@@ -3427,6 +3622,7 @@ Submitting ${source_default.bold(config.slug)} for marketplace review...
|
|
|
3427
3622
|
var init_submit = __esm(() => {
|
|
3428
3623
|
init_source();
|
|
3429
3624
|
init_config();
|
|
3625
|
+
init_auth();
|
|
3430
3626
|
});
|
|
3431
3627
|
|
|
3432
3628
|
// src/env-cmd.ts
|
|
@@ -3437,12 +3633,12 @@ __export(exports_env_cmd, {
|
|
|
3437
3633
|
envList: () => envList
|
|
3438
3634
|
});
|
|
3439
3635
|
function requireAuth() {
|
|
3440
|
-
const
|
|
3441
|
-
if (!
|
|
3442
|
-
console.error(source_default.red("Not authenticated. Run"), source_default.cyan("bagdock login"));
|
|
3636
|
+
const token = getAuthToken();
|
|
3637
|
+
if (!token) {
|
|
3638
|
+
console.error(source_default.red("Not authenticated. Run"), source_default.cyan("bagdock login"), source_default.red("or set BAGDOCK_API_KEY."));
|
|
3443
3639
|
process.exit(1);
|
|
3444
3640
|
}
|
|
3445
|
-
return
|
|
3641
|
+
return token;
|
|
3446
3642
|
}
|
|
3447
3643
|
function requireConfig() {
|
|
3448
3644
|
const config = loadBagdockJson(process.cwd());
|
|
@@ -3453,11 +3649,11 @@ function requireConfig() {
|
|
|
3453
3649
|
return config;
|
|
3454
3650
|
}
|
|
3455
3651
|
async function envList() {
|
|
3456
|
-
const
|
|
3652
|
+
const token = requireAuth();
|
|
3457
3653
|
const config = requireConfig();
|
|
3458
3654
|
try {
|
|
3459
3655
|
const res = await fetch(`${API_BASE}/v1/developer/apps/${config.slug}/env`, {
|
|
3460
|
-
headers: { Authorization: `Bearer ${
|
|
3656
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
3461
3657
|
});
|
|
3462
3658
|
if (!res.ok) {
|
|
3463
3659
|
console.error(source_default.red(`Failed to list env vars (${res.status})`));
|
|
@@ -3482,14 +3678,14 @@ Environment variables for ${config.slug}:
|
|
|
3482
3678
|
}
|
|
3483
3679
|
}
|
|
3484
3680
|
async function envSet(key, value) {
|
|
3485
|
-
const
|
|
3681
|
+
const token = requireAuth();
|
|
3486
3682
|
const config = requireConfig();
|
|
3487
3683
|
try {
|
|
3488
3684
|
const res = await fetch(`${API_BASE}/v1/developer/apps/${config.slug}/env`, {
|
|
3489
3685
|
method: "PUT",
|
|
3490
3686
|
headers: {
|
|
3491
3687
|
"Content-Type": "application/json",
|
|
3492
|
-
Authorization: `Bearer ${
|
|
3688
|
+
Authorization: `Bearer ${token}`
|
|
3493
3689
|
},
|
|
3494
3690
|
body: JSON.stringify({ key, value })
|
|
3495
3691
|
});
|
|
@@ -3505,12 +3701,12 @@ async function envSet(key, value) {
|
|
|
3505
3701
|
}
|
|
3506
3702
|
}
|
|
3507
3703
|
async function envRemove(key) {
|
|
3508
|
-
const
|
|
3704
|
+
const token = requireAuth();
|
|
3509
3705
|
const config = requireConfig();
|
|
3510
3706
|
try {
|
|
3511
3707
|
const res = await fetch(`${API_BASE}/v1/developer/apps/${config.slug}/env/${key}`, {
|
|
3512
3708
|
method: "DELETE",
|
|
3513
|
-
headers: { Authorization: `Bearer ${
|
|
3709
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
3514
3710
|
});
|
|
3515
3711
|
if (!res.ok) {
|
|
3516
3712
|
console.error(source_default.red(`Failed to remove ${key} (${res.status})`));
|
|
@@ -3525,146 +3721,339 @@ async function envRemove(key) {
|
|
|
3525
3721
|
var init_env_cmd = __esm(() => {
|
|
3526
3722
|
init_source();
|
|
3527
3723
|
init_config();
|
|
3724
|
+
init_auth();
|
|
3528
3725
|
});
|
|
3529
3726
|
|
|
3530
|
-
//
|
|
3531
|
-
var
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
Argument,
|
|
3542
|
-
Option,
|
|
3543
|
-
Help
|
|
3544
|
-
} = import__.default;
|
|
3545
|
-
|
|
3546
|
-
// src/auth.ts
|
|
3547
|
-
init_config();
|
|
3548
|
-
init_source();
|
|
3549
|
-
var CLIENT_ID = "bagdock-cli";
|
|
3550
|
-
var MAX_POLL_DURATION_MS = 300000;
|
|
3551
|
-
async function login() {
|
|
3552
|
-
const existing = loadCredentials();
|
|
3553
|
-
if (existing?.accessToken && existing.expiresAt && existing.expiresAt > Date.now()) {
|
|
3554
|
-
console.log(source_default.green("Already logged in as"), source_default.bold(existing.email ?? "unknown"));
|
|
3555
|
-
console.log("Run", source_default.cyan("bagdock logout"), "to sign out first.");
|
|
3556
|
-
return;
|
|
3727
|
+
// src/keys.ts
|
|
3728
|
+
var exports_keys = {};
|
|
3729
|
+
__export(exports_keys, {
|
|
3730
|
+
keysList: () => keysList,
|
|
3731
|
+
keysDelete: () => keysDelete,
|
|
3732
|
+
keysCreate: () => keysCreate
|
|
3733
|
+
});
|
|
3734
|
+
async function apiRequest(method, path2, body) {
|
|
3735
|
+
const token = getAuthToken();
|
|
3736
|
+
if (!token) {
|
|
3737
|
+
outputError("UNAUTHENTICATED", "Not logged in. Run `bagdock login` or set BAGDOCK_API_KEY.");
|
|
3557
3738
|
}
|
|
3558
|
-
|
|
3559
|
-
|
|
3739
|
+
const headers = { Authorization: `Bearer ${token}` };
|
|
3740
|
+
const init2 = { method, headers };
|
|
3741
|
+
if (body) {
|
|
3742
|
+
headers["Content-Type"] = "application/json";
|
|
3743
|
+
init2.body = JSON.stringify(body);
|
|
3744
|
+
}
|
|
3745
|
+
const res = await fetch(`${API_BASE}${path2}`, init2);
|
|
3746
|
+
return res;
|
|
3747
|
+
}
|
|
3748
|
+
async function keysCreate(opts) {
|
|
3749
|
+
status("Creating API key...");
|
|
3750
|
+
const res = await apiRequest("POST", "/api/v1/operator/api-keys", {
|
|
3751
|
+
name: opts.name,
|
|
3752
|
+
key_type: opts.type || "secret",
|
|
3753
|
+
key_category: opts.category || "standard",
|
|
3754
|
+
environment: opts.environment || "live",
|
|
3755
|
+
scopes: opts.scopes || []
|
|
3756
|
+
});
|
|
3757
|
+
if (!res.ok) {
|
|
3758
|
+
const err = await res.json().catch(() => ({ error: { message: res.statusText } }));
|
|
3759
|
+
outputError(err.error?.code || "API_ERROR", err.error?.message || `HTTP ${res.status}`);
|
|
3760
|
+
}
|
|
3761
|
+
const data = await res.json();
|
|
3762
|
+
if (isJsonMode()) {
|
|
3763
|
+
outputSuccess(data);
|
|
3764
|
+
} else {
|
|
3765
|
+
console.log(source_default.green(`
|
|
3766
|
+
API key created successfully!
|
|
3560
3767
|
`));
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3768
|
+
console.log(` ${source_default.bold("Name:")} ${data.name}`);
|
|
3769
|
+
console.log(` ${source_default.bold("Key:")} ${source_default.yellow(data.key)}`);
|
|
3770
|
+
console.log(` ${source_default.bold("ID:")} ${data.id}`);
|
|
3771
|
+
console.log(` ${source_default.bold("Environment:")} ${data.environment}`);
|
|
3772
|
+
console.log(` ${source_default.bold("Type:")} ${data.key_type}`);
|
|
3773
|
+
console.log(` ${source_default.bold("Category:")} ${data.key_category}`);
|
|
3774
|
+
if (data.scopes?.length) {
|
|
3775
|
+
console.log(` ${source_default.bold("Scopes:")} ${data.scopes.join(", ")}`);
|
|
3776
|
+
}
|
|
3777
|
+
console.log();
|
|
3778
|
+
console.log(source_default.yellow(" Save this key — it will not be shown again."));
|
|
3779
|
+
console.log();
|
|
3780
|
+
}
|
|
3781
|
+
}
|
|
3782
|
+
async function keysList(opts) {
|
|
3783
|
+
status("Fetching API keys...");
|
|
3784
|
+
let path2 = "/api/v1/operator/api-keys";
|
|
3785
|
+
if (opts.environment)
|
|
3786
|
+
path2 += `?environment=${opts.environment}`;
|
|
3787
|
+
const res = await apiRequest("GET", path2);
|
|
3788
|
+
if (!res.ok) {
|
|
3789
|
+
const err = await res.json().catch(() => ({ error: { message: res.statusText } }));
|
|
3790
|
+
outputError(err.error?.code || "API_ERROR", err.error?.message || `HTTP ${res.status}`);
|
|
3791
|
+
}
|
|
3792
|
+
const result = await res.json();
|
|
3793
|
+
if (isJsonMode()) {
|
|
3794
|
+
outputList("api_key", result.data, result.has_more);
|
|
3795
|
+
} else {
|
|
3796
|
+
if (!result.data.length) {
|
|
3797
|
+
console.log(source_default.yellow(`
|
|
3798
|
+
No API keys found.
|
|
3799
|
+
`));
|
|
3800
|
+
return;
|
|
3801
|
+
}
|
|
3802
|
+
console.log();
|
|
3803
|
+
for (const key of result.data) {
|
|
3804
|
+
const usedAt = key.last_used_at ? new Date(key.last_used_at).toLocaleDateString() : "never";
|
|
3805
|
+
console.log(` ${source_default.bold(key.name)}`);
|
|
3806
|
+
console.log(` ${source_default.dim("Prefix:")} ${key.key_prefix}... ${source_default.dim("Env:")} ${key.environment} ${source_default.dim("Last used:")} ${usedAt}`);
|
|
3807
|
+
console.log(` ${source_default.dim("ID:")} ${key.id} ${source_default.dim("Category:")} ${key.key_category}`);
|
|
3808
|
+
console.log();
|
|
3809
|
+
}
|
|
3810
|
+
}
|
|
3811
|
+
}
|
|
3812
|
+
async function keysDelete(id, opts) {
|
|
3813
|
+
if (!opts.yes && !process.stdout.isTTY) {
|
|
3814
|
+
outputError("CONFIRMATION_REQUIRED", "Pass --yes to confirm deletion in non-interactive mode.");
|
|
3815
|
+
}
|
|
3816
|
+
status(`Revoking API key ${id}...`);
|
|
3817
|
+
const res = await apiRequest("DELETE", `/api/v1/operator/api-keys/${id}`, {
|
|
3818
|
+
reason: opts.reason
|
|
3565
3819
|
});
|
|
3566
|
-
if (!
|
|
3567
|
-
const err = await
|
|
3568
|
-
|
|
3569
|
-
process.exit(1);
|
|
3820
|
+
if (!res.ok) {
|
|
3821
|
+
const err = await res.json().catch(() => ({ error: { message: res.statusText } }));
|
|
3822
|
+
outputError(err.error?.code || "API_ERROR", err.error?.message || `HTTP ${res.status}`);
|
|
3570
3823
|
}
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3824
|
+
if (isJsonMode()) {
|
|
3825
|
+
outputSuccess({ id, status: "revoked" });
|
|
3826
|
+
} else {
|
|
3827
|
+
success(`
|
|
3828
|
+
API key ${id} revoked.
|
|
3574
3829
|
`);
|
|
3575
|
-
|
|
3830
|
+
}
|
|
3831
|
+
}
|
|
3832
|
+
var init_keys = __esm(() => {
|
|
3833
|
+
init_source();
|
|
3834
|
+
init_config();
|
|
3835
|
+
init_auth();
|
|
3836
|
+
init_output();
|
|
3837
|
+
});
|
|
3838
|
+
|
|
3839
|
+
// src/apps.ts
|
|
3840
|
+
var exports_apps = {};
|
|
3841
|
+
__export(exports_apps, {
|
|
3842
|
+
appsList: () => appsList,
|
|
3843
|
+
appsGet: () => appsGet
|
|
3844
|
+
});
|
|
3845
|
+
async function apiRequest2(method, path2) {
|
|
3846
|
+
const token = getAuthToken();
|
|
3847
|
+
if (!token) {
|
|
3848
|
+
outputError("UNAUTHENTICATED", "Not logged in. Run `bagdock login` or set BAGDOCK_API_KEY.");
|
|
3849
|
+
}
|
|
3850
|
+
return fetch(`${API_BASE}${path2}`, {
|
|
3851
|
+
method,
|
|
3852
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
3853
|
+
});
|
|
3854
|
+
}
|
|
3855
|
+
async function appsList() {
|
|
3856
|
+
status("Fetching apps...");
|
|
3857
|
+
const res = await apiRequest2("GET", "/api/v1/developer/apps");
|
|
3858
|
+
if (!res.ok) {
|
|
3859
|
+
const err = await res.json().catch(() => ({ error: { message: res.statusText } }));
|
|
3860
|
+
outputError(err.error?.code || "API_ERROR", err.error?.message || `HTTP ${res.status}`);
|
|
3861
|
+
}
|
|
3862
|
+
const result = await res.json();
|
|
3863
|
+
if (isJsonMode()) {
|
|
3864
|
+
outputList("app", result.data, false);
|
|
3865
|
+
} else {
|
|
3866
|
+
if (!result.data.length) {
|
|
3867
|
+
console.log(source_default.yellow(`
|
|
3868
|
+
No apps found. Create one with`), source_default.cyan("bagdock init"), `
|
|
3576
3869
|
`);
|
|
3577
|
-
const open2 = (await Promise.resolve().then(() => (init_open(), exports_open))).default;
|
|
3578
|
-
await open2(device.verification_uri_complete).catch(() => {});
|
|
3579
|
-
console.log(source_default.dim(" Waiting for authorization..."));
|
|
3580
|
-
const startedAt = Date.now();
|
|
3581
|
-
while (Date.now() - startedAt < MAX_POLL_DURATION_MS) {
|
|
3582
|
-
await sleep(pollInterval);
|
|
3583
|
-
const tokenRes = await fetch(`${API_BASE}/oauth2/token`, {
|
|
3584
|
-
method: "POST",
|
|
3585
|
-
headers: { "Content-Type": "application/json" },
|
|
3586
|
-
body: JSON.stringify({
|
|
3587
|
-
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
3588
|
-
client_id: CLIENT_ID,
|
|
3589
|
-
device_code: device.device_code
|
|
3590
|
-
})
|
|
3591
|
-
});
|
|
3592
|
-
if (tokenRes.ok) {
|
|
3593
|
-
const tokens = await tokenRes.json();
|
|
3594
|
-
saveCredentials({
|
|
3595
|
-
accessToken: tokens.access_token,
|
|
3596
|
-
refreshToken: tokens.refresh_token,
|
|
3597
|
-
expiresAt: tokens.expires_in ? Date.now() + tokens.expires_in * 1000 : undefined,
|
|
3598
|
-
email: tokens.email,
|
|
3599
|
-
operatorId: tokens.operator_id
|
|
3600
|
-
});
|
|
3601
|
-
console.log(source_default.green(`
|
|
3602
|
-
Logged in successfully!`));
|
|
3603
|
-
if (tokens.email)
|
|
3604
|
-
console.log(" Email:", source_default.bold(tokens.email));
|
|
3605
|
-
if (tokens.operator_id)
|
|
3606
|
-
console.log(" Operator:", source_default.bold(tokens.operator_id));
|
|
3607
3870
|
return;
|
|
3608
3871
|
}
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
}
|
|
3617
|
-
|
|
3618
|
-
console.log(
|
|
3619
|
-
Device code expired. Please try again.`));
|
|
3620
|
-
process.exit(1);
|
|
3621
|
-
}
|
|
3622
|
-
if (error.error === "access_denied") {
|
|
3623
|
-
console.log(source_default.red(`
|
|
3624
|
-
Authorization denied.`));
|
|
3625
|
-
process.exit(1);
|
|
3872
|
+
console.log();
|
|
3873
|
+
for (const app of result.data) {
|
|
3874
|
+
const status2 = app.is_active ? source_default.green("active") : source_default.dim("inactive");
|
|
3875
|
+
const review = app.review_status ? source_default.dim(`[${app.review_status}]`) : "";
|
|
3876
|
+
console.log(` ${source_default.bold(app.name)} ${source_default.dim(`(${app.slug})`)} ${status2} ${review}`);
|
|
3877
|
+
console.log(` ${source_default.dim("Type:")} ${app.type}/${app.category} ${source_default.dim("Version:")} ${app.version}`);
|
|
3878
|
+
if (app.worker_url) {
|
|
3879
|
+
console.log(` ${source_default.dim("URL:")} ${app.worker_url}`);
|
|
3880
|
+
}
|
|
3881
|
+
console.log();
|
|
3626
3882
|
}
|
|
3627
|
-
console.log(source_default.red(`
|
|
3628
|
-
Login failed:`), error.error_description ?? error.error);
|
|
3629
|
-
process.exit(1);
|
|
3630
3883
|
}
|
|
3631
|
-
console.log(source_default.red(`
|
|
3632
|
-
Login timed out. Please try again.`));
|
|
3633
|
-
process.exit(1);
|
|
3634
3884
|
}
|
|
3635
|
-
async function
|
|
3636
|
-
|
|
3637
|
-
|
|
3885
|
+
async function appsGet(slug) {
|
|
3886
|
+
status(`Fetching app ${slug}...`);
|
|
3887
|
+
const res = await apiRequest2("GET", `/api/v1/developer/apps/${slug}`);
|
|
3888
|
+
if (!res.ok) {
|
|
3889
|
+
if (res.status === 404) {
|
|
3890
|
+
outputError("NOT_FOUND", `App "${slug}" not found`);
|
|
3891
|
+
}
|
|
3892
|
+
const err = await res.json().catch(() => ({ error: { message: res.statusText } }));
|
|
3893
|
+
outputError(err.error?.code || "API_ERROR", err.error?.message || `HTTP ${res.status}`);
|
|
3894
|
+
}
|
|
3895
|
+
const result = await res.json();
|
|
3896
|
+
const app = result.data;
|
|
3897
|
+
if (isJsonMode()) {
|
|
3898
|
+
outputSuccess(app);
|
|
3899
|
+
} else {
|
|
3900
|
+
console.log();
|
|
3901
|
+
console.log(` ${source_default.bold(app.name)} ${source_default.dim(`(${app.slug})`)}`);
|
|
3902
|
+
console.log(` ${source_default.dim("ID:")} ${app.id}`);
|
|
3903
|
+
console.log(` ${source_default.dim("Type:")} ${app.type}`);
|
|
3904
|
+
console.log(` ${source_default.dim("Category:")} ${app.category}`);
|
|
3905
|
+
console.log(` ${source_default.dim("Kind:")} ${app.kind ?? "-"}`);
|
|
3906
|
+
console.log(` ${source_default.dim("Version:")} ${app.version}`);
|
|
3907
|
+
console.log(` ${source_default.dim("Visibility:")} ${app.visibility}`);
|
|
3908
|
+
console.log(` ${source_default.dim("Maintainer:")} ${app.maintainer}`);
|
|
3909
|
+
console.log(` ${source_default.dim("Review:")} ${app.review_status ?? "draft"}`);
|
|
3910
|
+
console.log(` ${source_default.dim("Active:")} ${app.is_active ? "yes" : "no"}`);
|
|
3911
|
+
if (app.worker_url) {
|
|
3912
|
+
console.log(` ${source_default.dim("Worker URL:")} ${app.worker_url}`);
|
|
3913
|
+
}
|
|
3914
|
+
console.log(` ${source_default.dim("Created:")} ${app.created_at}`);
|
|
3915
|
+
console.log(` ${source_default.dim("Updated:")} ${app.updated_at}`);
|
|
3916
|
+
console.log();
|
|
3917
|
+
}
|
|
3638
3918
|
}
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3919
|
+
var init_apps = __esm(() => {
|
|
3920
|
+
init_source();
|
|
3921
|
+
init_config();
|
|
3922
|
+
init_auth();
|
|
3923
|
+
init_output();
|
|
3924
|
+
});
|
|
3925
|
+
|
|
3926
|
+
// src/logs.ts
|
|
3927
|
+
var exports_logs = {};
|
|
3928
|
+
__export(exports_logs, {
|
|
3929
|
+
logsTail: () => logsTail,
|
|
3930
|
+
logsList: () => logsList,
|
|
3931
|
+
logsGet: () => logsGet
|
|
3932
|
+
});
|
|
3933
|
+
async function apiRequest3(method, path2) {
|
|
3934
|
+
const token = getAuthToken();
|
|
3935
|
+
if (!token) {
|
|
3936
|
+
outputError("UNAUTHENTICATED", "Not logged in. Run `bagdock login` or set BAGDOCK_API_KEY.");
|
|
3645
3937
|
}
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
|
|
3938
|
+
return fetch(`${API_BASE}${path2}`, {
|
|
3939
|
+
method,
|
|
3940
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
3941
|
+
});
|
|
3942
|
+
}
|
|
3943
|
+
function resolveSlug(slug) {
|
|
3944
|
+
if (slug)
|
|
3945
|
+
return slug;
|
|
3946
|
+
const config = loadBagdockJson(process.cwd());
|
|
3947
|
+
if (config?.slug)
|
|
3948
|
+
return config.slug;
|
|
3949
|
+
outputError("MISSING_CONFIG", "No slug specified and no bagdock.json found. Pass --app <slug> or run from a project directory.");
|
|
3950
|
+
return "";
|
|
3951
|
+
}
|
|
3952
|
+
async function logsList(opts) {
|
|
3953
|
+
const slug = resolveSlug(opts.app);
|
|
3954
|
+
const limit = opts.limit || "50";
|
|
3955
|
+
status(`Fetching logs for ${slug}...`);
|
|
3956
|
+
const res = await apiRequest3("GET", `/api/v1/developer/apps/${slug}/logs?limit=${limit}`);
|
|
3957
|
+
if (!res.ok) {
|
|
3958
|
+
if (res.status === 404) {
|
|
3959
|
+
outputError("NOT_FOUND", `App "${slug}" not found or no logs available`);
|
|
3960
|
+
}
|
|
3961
|
+
const err = await res.json().catch(() => ({ error: { message: res.statusText } }));
|
|
3962
|
+
outputError(err.error?.code || "API_ERROR", err.error?.message || `HTTP ${res.status}`);
|
|
3963
|
+
}
|
|
3964
|
+
const result = await res.json();
|
|
3965
|
+
if (isJsonMode()) {
|
|
3966
|
+
outputList("log_entry", result.data, false);
|
|
3967
|
+
} else {
|
|
3968
|
+
if (!result.data?.length) {
|
|
3969
|
+
console.log(source_default.yellow(`
|
|
3970
|
+
No logs found for ${slug}.
|
|
3971
|
+
`));
|
|
3972
|
+
return;
|
|
3653
3973
|
}
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
console.log(source_default.red("Failed to reach API:"), err.message);
|
|
3662
|
-
process.exit(1);
|
|
3974
|
+
console.log();
|
|
3975
|
+
for (const entry of result.data) {
|
|
3976
|
+
const ts = source_default.dim(new Date(entry.timestamp).toISOString());
|
|
3977
|
+
const level = entry.level === "error" ? source_default.red(entry.level) : source_default.dim(entry.level);
|
|
3978
|
+
console.log(` ${ts} ${level} ${entry.message}`);
|
|
3979
|
+
}
|
|
3980
|
+
console.log();
|
|
3663
3981
|
}
|
|
3664
3982
|
}
|
|
3665
|
-
function
|
|
3666
|
-
|
|
3983
|
+
async function logsGet(id, opts) {
|
|
3984
|
+
const slug = resolveSlug(opts.app);
|
|
3985
|
+
status(`Fetching log entry ${id}...`);
|
|
3986
|
+
const res = await apiRequest3("GET", `/api/v1/developer/apps/${slug}/logs/${id}`);
|
|
3987
|
+
if (!res.ok) {
|
|
3988
|
+
const err = await res.json().catch(() => ({ error: { message: res.statusText } }));
|
|
3989
|
+
outputError(err.error?.code || "API_ERROR", err.error?.message || `HTTP ${res.status}`);
|
|
3990
|
+
}
|
|
3991
|
+
const data = await res.json();
|
|
3992
|
+
if (isJsonMode()) {
|
|
3993
|
+
outputSuccess(data);
|
|
3994
|
+
} else {
|
|
3995
|
+
console.log(JSON.stringify(data, null, 2));
|
|
3996
|
+
}
|
|
3667
3997
|
}
|
|
3998
|
+
async function logsTail(opts) {
|
|
3999
|
+
const slug = resolveSlug(opts.app);
|
|
4000
|
+
if (isJsonMode()) {
|
|
4001
|
+
outputError("UNSUPPORTED", "Log tailing is not supported in JSON mode. Use `logs list` instead.");
|
|
4002
|
+
}
|
|
4003
|
+
console.log(source_default.cyan(`
|
|
4004
|
+
Tailing logs for ${slug}... (Ctrl+C to stop)
|
|
4005
|
+
`));
|
|
4006
|
+
let lastTimestamp = new Date().toISOString();
|
|
4007
|
+
const poll = async () => {
|
|
4008
|
+
try {
|
|
4009
|
+
const res = await apiRequest3("GET", `/api/v1/developer/apps/${slug}/logs?since=${encodeURIComponent(lastTimestamp)}&limit=100`);
|
|
4010
|
+
if (res.ok) {
|
|
4011
|
+
const result = await res.json();
|
|
4012
|
+
for (const entry of result.data || []) {
|
|
4013
|
+
const ts = source_default.dim(new Date(entry.timestamp).toISOString());
|
|
4014
|
+
const level = entry.level === "error" ? source_default.red(entry.level) : source_default.dim(entry.level);
|
|
4015
|
+
console.log(` ${ts} ${level} ${entry.message}`);
|
|
4016
|
+
lastTimestamp = entry.timestamp;
|
|
4017
|
+
}
|
|
4018
|
+
}
|
|
4019
|
+
} catch {}
|
|
4020
|
+
};
|
|
4021
|
+
const interval = setInterval(poll, 2000);
|
|
4022
|
+
await poll();
|
|
4023
|
+
process.on("SIGINT", () => {
|
|
4024
|
+
clearInterval(interval);
|
|
4025
|
+
console.log(source_default.dim(`
|
|
4026
|
+
Stopped tailing.
|
|
4027
|
+
`));
|
|
4028
|
+
process.exit(0);
|
|
4029
|
+
});
|
|
4030
|
+
await new Promise(() => {});
|
|
4031
|
+
}
|
|
4032
|
+
var init_logs = __esm(() => {
|
|
4033
|
+
init_source();
|
|
4034
|
+
init_config();
|
|
4035
|
+
init_auth();
|
|
4036
|
+
init_output();
|
|
4037
|
+
});
|
|
4038
|
+
|
|
4039
|
+
// node_modules/commander/esm.mjs
|
|
4040
|
+
var import__ = __toESM(require_commander(), 1);
|
|
4041
|
+
var {
|
|
4042
|
+
program,
|
|
4043
|
+
createCommand,
|
|
4044
|
+
createArgument,
|
|
4045
|
+
createOption,
|
|
4046
|
+
CommanderError,
|
|
4047
|
+
InvalidArgumentError,
|
|
4048
|
+
InvalidOptionArgumentError,
|
|
4049
|
+
Command,
|
|
4050
|
+
Argument,
|
|
4051
|
+
Option,
|
|
4052
|
+
Help
|
|
4053
|
+
} = import__.default;
|
|
4054
|
+
|
|
4055
|
+
// bin/bagdock.ts
|
|
4056
|
+
init_auth();
|
|
3668
4057
|
|
|
3669
4058
|
// src/init.ts
|
|
3670
4059
|
init_source();
|
|
@@ -3914,8 +4303,14 @@ function toPascalCase(s) {
|
|
|
3914
4303
|
}
|
|
3915
4304
|
|
|
3916
4305
|
// bin/bagdock.ts
|
|
4306
|
+
init_output();
|
|
3917
4307
|
var program2 = new Command;
|
|
3918
|
-
program2.name("bagdock").description("Bagdock developer CLI").version("0.1.
|
|
4308
|
+
program2.name("bagdock").description("Bagdock developer CLI").version("0.1.4").option("--json", "Force JSON output (auto-enabled in non-TTY)").option("-q, --quiet", "Suppress status messages (implies --json)").option("--api-key <key>", "API key to use for this invocation").hook("preAction", (_thisCommand, actionCommand) => {
|
|
4309
|
+
const opts = program2.opts();
|
|
4310
|
+
setOutputMode({ json: opts.json, quiet: opts.quiet });
|
|
4311
|
+
if (opts.apiKey)
|
|
4312
|
+
setApiKeyOverride(opts.apiKey);
|
|
4313
|
+
});
|
|
3919
4314
|
program2.command("login").description("Authenticate with Bagdock (opens browser)").action(login);
|
|
3920
4315
|
program2.command("logout").description("Clear stored credentials").action(logout);
|
|
3921
4316
|
program2.command("whoami").description("Show current authenticated user").action(whoami);
|
|
@@ -3924,7 +4319,7 @@ program2.command("dev").description("Start local dev server").option("-p, --port
|
|
|
3924
4319
|
const { dev: dev2 } = await Promise.resolve().then(() => (init_dev(), exports_dev));
|
|
3925
4320
|
await dev2(opts);
|
|
3926
4321
|
});
|
|
3927
|
-
program2.command("deploy").description("Build locally and deploy via Bagdock API
|
|
4322
|
+
program2.command("deploy").description("Build locally and deploy via Bagdock API").option("--env <environment>", "Target environment (preview, staging, production)", "staging").option("--preview", "Deploy an ephemeral preview ({slug}-{hash}.pre.bdok.dev)").option("--production", "Deploy to production ({slug}.bdok.dev)").option("-y, --yes", "Skip confirmation prompts").action(async (opts) => {
|
|
3928
4323
|
const { deploy: deploy2 } = await Promise.resolve().then(() => (init_deploy(), exports_deploy));
|
|
3929
4324
|
await deploy2(opts);
|
|
3930
4325
|
});
|
|
@@ -3945,4 +4340,39 @@ envCmd.command("remove <key>").description("Remove an environment variable").act
|
|
|
3945
4340
|
const { envRemove: envRemove2 } = await Promise.resolve().then(() => (init_env_cmd(), exports_env_cmd));
|
|
3946
4341
|
await envRemove2(key);
|
|
3947
4342
|
});
|
|
4343
|
+
var keysCmd = program2.command("keys").description("Manage operator API keys");
|
|
4344
|
+
keysCmd.command("create").description("Create a new API key (raw key shown once)").requiredOption("--name <name>", "Key name").option("--type <type>", "Key type (secret, publishable)", "secret").option("--category <category>", "Key category (standard, restricted, personal)", "standard").option("--environment <env>", "Environment (live, test)", "live").option("--scopes <scopes...>", "Permission scopes").action(async (opts) => {
|
|
4345
|
+
const { keysCreate: keysCreate2 } = await Promise.resolve().then(() => (init_keys(), exports_keys));
|
|
4346
|
+
await keysCreate2(opts);
|
|
4347
|
+
});
|
|
4348
|
+
keysCmd.command("list").description("List API keys").option("--environment <env>", "Filter by environment (live, test)").action(async (opts) => {
|
|
4349
|
+
const { keysList: keysList2 } = await Promise.resolve().then(() => (init_keys(), exports_keys));
|
|
4350
|
+
await keysList2(opts);
|
|
4351
|
+
});
|
|
4352
|
+
keysCmd.command("delete <id>").description("Revoke an API key").option("-y, --yes", "Skip confirmation (required in non-TTY)").option("--reason <reason>", "Revocation reason").action(async (id, opts) => {
|
|
4353
|
+
const { keysDelete: keysDelete2 } = await Promise.resolve().then(() => (init_keys(), exports_keys));
|
|
4354
|
+
await keysDelete2(id, opts);
|
|
4355
|
+
});
|
|
4356
|
+
var appsCmd = program2.command("apps").description("List and inspect deployed apps and edges");
|
|
4357
|
+
appsCmd.command("list").description("List all apps for the authenticated operator").action(async () => {
|
|
4358
|
+
const { appsList: appsList2 } = await Promise.resolve().then(() => (init_apps(), exports_apps));
|
|
4359
|
+
await appsList2();
|
|
4360
|
+
});
|
|
4361
|
+
appsCmd.command("get <slug>").description("Get details for a specific app").action(async (slug) => {
|
|
4362
|
+
const { appsGet: appsGet2 } = await Promise.resolve().then(() => (init_apps(), exports_apps));
|
|
4363
|
+
await appsGet2(slug);
|
|
4364
|
+
});
|
|
4365
|
+
var logsCmd = program2.command("logs").description("View execution logs for deployed apps");
|
|
4366
|
+
logsCmd.command("list").description("List recent log entries").option("--app <slug>", "App slug (defaults to bagdock.json slug)").option("--limit <n>", "Number of entries", "50").action(async (opts) => {
|
|
4367
|
+
const { logsList: logsList2 } = await Promise.resolve().then(() => (init_logs(), exports_logs));
|
|
4368
|
+
await logsList2(opts);
|
|
4369
|
+
});
|
|
4370
|
+
logsCmd.command("get <id>").description("Get a specific log entry").option("--app <slug>", "App slug (defaults to bagdock.json slug)").action(async (id, opts) => {
|
|
4371
|
+
const { logsGet: logsGet2 } = await Promise.resolve().then(() => (init_logs(), exports_logs));
|
|
4372
|
+
await logsGet2(id, opts);
|
|
4373
|
+
});
|
|
4374
|
+
logsCmd.command("tail").description("Stream logs in real-time").option("--app <slug>", "App slug (defaults to bagdock.json slug)").action(async (opts) => {
|
|
4375
|
+
const { logsTail: logsTail2 } = await Promise.resolve().then(() => (init_logs(), exports_logs));
|
|
4376
|
+
await logsTail2(opts);
|
|
4377
|
+
});
|
|
3948
4378
|
program2.parse();
|
package/package.json
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bagdock/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Bagdock developer CLI — build, test, and deploy apps and edges on the Bagdock platform",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"bagdock",
|
|
7
|
+
"cli",
|
|
8
|
+
"self-storage",
|
|
9
|
+
"developer-tools",
|
|
10
|
+
"deploy",
|
|
11
|
+
"serverless",
|
|
12
|
+
"integrations",
|
|
13
|
+
"adapters"
|
|
14
|
+
],
|
|
5
15
|
"license": "MIT",
|
|
6
16
|
"repository": {
|
|
7
17
|
"type": "git",
|
|
@@ -13,7 +23,7 @@
|
|
|
13
23
|
},
|
|
14
24
|
"type": "module",
|
|
15
25
|
"bin": {
|
|
16
|
-
"bagdock": "
|
|
26
|
+
"bagdock": "dist/bagdock.js"
|
|
17
27
|
},
|
|
18
28
|
"files": [
|
|
19
29
|
"dist",
|