@insforge/cli 0.1.4 → 0.1.6
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/README.md +2 -0
- package/dist/index.js +434 -191
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { fileURLToPath } from "url";
|
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
|
|
9
9
|
// src/commands/login.ts
|
|
10
|
-
import * as
|
|
10
|
+
import * as clack3 from "@clack/prompts";
|
|
11
11
|
|
|
12
12
|
// src/lib/config.ts
|
|
13
13
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from "fs";
|
|
@@ -135,6 +135,7 @@ function getRootOpts(cmd) {
|
|
|
135
135
|
import { createServer } from "http";
|
|
136
136
|
import { randomBytes, createHash } from "crypto";
|
|
137
137
|
import { URL } from "url";
|
|
138
|
+
import * as clack from "@clack/prompts";
|
|
138
139
|
var DEFAULT_CLIENT_ID = "clf_NK8cMUs41gm8ZcfdtSguVw";
|
|
139
140
|
var OAUTH_SCOPES = "user:read organizations:read projects:read projects:write";
|
|
140
141
|
function generatePKCE() {
|
|
@@ -242,14 +243,77 @@ function startCallbackServer() {
|
|
|
242
243
|
}, 5 * 60 * 1e3).unref();
|
|
243
244
|
});
|
|
244
245
|
}
|
|
246
|
+
async function performOAuthLogin(apiUrl) {
|
|
247
|
+
const platformUrl = getPlatformApiUrl(apiUrl);
|
|
248
|
+
const config = getGlobalConfig();
|
|
249
|
+
const clientId = config.oauth_client_id ?? DEFAULT_CLIENT_ID;
|
|
250
|
+
const pkce = generatePKCE();
|
|
251
|
+
const state = generateState();
|
|
252
|
+
const { port, result, close } = await startCallbackServer();
|
|
253
|
+
const redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
254
|
+
const authUrl = buildAuthorizeUrl({
|
|
255
|
+
platformUrl,
|
|
256
|
+
clientId,
|
|
257
|
+
redirectUri,
|
|
258
|
+
codeChallenge: pkce.code_challenge,
|
|
259
|
+
state,
|
|
260
|
+
scopes: OAUTH_SCOPES
|
|
261
|
+
});
|
|
262
|
+
clack.log.info("Opening browser for authentication...");
|
|
263
|
+
clack.log.info(`If browser doesn't open, visit:
|
|
264
|
+
${authUrl}`);
|
|
265
|
+
try {
|
|
266
|
+
const open = (await import("open")).default;
|
|
267
|
+
await open(authUrl);
|
|
268
|
+
} catch {
|
|
269
|
+
clack.log.warn("Could not open browser. Please visit the URL above.");
|
|
270
|
+
}
|
|
271
|
+
const s = clack.spinner();
|
|
272
|
+
s.start("Waiting for authentication...");
|
|
273
|
+
try {
|
|
274
|
+
const callbackResult = await result;
|
|
275
|
+
close();
|
|
276
|
+
if (callbackResult.state !== state) {
|
|
277
|
+
s.stop("Authentication failed");
|
|
278
|
+
throw new Error("State mismatch. Possible CSRF attack.");
|
|
279
|
+
}
|
|
280
|
+
s.message("Exchanging authorization code...");
|
|
281
|
+
const tokens = await exchangeCodeForTokens({
|
|
282
|
+
platformUrl,
|
|
283
|
+
code: callbackResult.code,
|
|
284
|
+
redirectUri,
|
|
285
|
+
clientId,
|
|
286
|
+
codeVerifier: pkce.code_verifier
|
|
287
|
+
});
|
|
288
|
+
const creds = {
|
|
289
|
+
access_token: tokens.access_token,
|
|
290
|
+
refresh_token: tokens.refresh_token,
|
|
291
|
+
user: { id: "", name: "", email: "", avatar_url: null, email_verified: true }
|
|
292
|
+
};
|
|
293
|
+
saveCredentials(creds);
|
|
294
|
+
try {
|
|
295
|
+
const profile = await getProfile(apiUrl);
|
|
296
|
+
creds.user = profile;
|
|
297
|
+
saveCredentials(creds);
|
|
298
|
+
s.stop(`Authenticated as ${profile.email}`);
|
|
299
|
+
} catch {
|
|
300
|
+
s.stop("Authenticated successfully");
|
|
301
|
+
}
|
|
302
|
+
return creds;
|
|
303
|
+
} catch (err) {
|
|
304
|
+
close();
|
|
305
|
+
s.stop("Authentication failed");
|
|
306
|
+
throw err;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
245
309
|
|
|
246
310
|
// src/lib/credentials.ts
|
|
247
|
-
|
|
311
|
+
import * as clack2 from "@clack/prompts";
|
|
312
|
+
async function requireAuth(apiUrl) {
|
|
248
313
|
const creds = getCredentials();
|
|
249
|
-
if (
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
return creds;
|
|
314
|
+
if (creds && creds.access_token) return creds;
|
|
315
|
+
clack2.log.info("You need to log in to continue.");
|
|
316
|
+
return await performOAuthLogin(apiUrl);
|
|
253
317
|
}
|
|
254
318
|
async function refreshAccessToken(apiUrl) {
|
|
255
319
|
const creds = getCredentials();
|
|
@@ -371,7 +435,7 @@ function registerLoginCommand(program2) {
|
|
|
371
435
|
if (opts.email) {
|
|
372
436
|
await loginWithEmail(json, apiUrl);
|
|
373
437
|
} else {
|
|
374
|
-
await loginWithOAuth(json, apiUrl
|
|
438
|
+
await loginWithOAuth(json, apiUrl);
|
|
375
439
|
}
|
|
376
440
|
} catch (err) {
|
|
377
441
|
if (err instanceof Error && err.message.includes("cancelled")) {
|
|
@@ -383,28 +447,28 @@ function registerLoginCommand(program2) {
|
|
|
383
447
|
}
|
|
384
448
|
async function loginWithEmail(json, apiUrl) {
|
|
385
449
|
if (!json) {
|
|
386
|
-
|
|
450
|
+
clack3.intro("InsForge CLI");
|
|
387
451
|
}
|
|
388
|
-
const email = json ? process.env.INSFORGE_EMAIL : await
|
|
452
|
+
const email = json ? process.env.INSFORGE_EMAIL : await clack3.text({
|
|
389
453
|
message: "Email:",
|
|
390
454
|
validate: (v) => v.includes("@") ? void 0 : "Please enter a valid email"
|
|
391
455
|
});
|
|
392
|
-
if (
|
|
393
|
-
|
|
456
|
+
if (clack3.isCancel(email)) {
|
|
457
|
+
clack3.cancel("Login cancelled.");
|
|
394
458
|
throw new Error("cancelled");
|
|
395
459
|
}
|
|
396
|
-
const password2 = json ? process.env.INSFORGE_PASSWORD : await
|
|
460
|
+
const password2 = json ? process.env.INSFORGE_PASSWORD : await clack3.password({
|
|
397
461
|
message: "Password:"
|
|
398
462
|
});
|
|
399
|
-
if (
|
|
400
|
-
|
|
463
|
+
if (clack3.isCancel(password2)) {
|
|
464
|
+
clack3.cancel("Login cancelled.");
|
|
401
465
|
throw new Error("cancelled");
|
|
402
466
|
}
|
|
403
467
|
if (!email || !password2) {
|
|
404
468
|
throw new Error("Email and password are required. Set INSFORGE_EMAIL and INSFORGE_PASSWORD environment variables for non-interactive mode.");
|
|
405
469
|
}
|
|
406
470
|
if (!json) {
|
|
407
|
-
const s =
|
|
471
|
+
const s = clack3.spinner();
|
|
408
472
|
s.start("Authenticating...");
|
|
409
473
|
const result = await login(email, password2, apiUrl);
|
|
410
474
|
const creds = {
|
|
@@ -414,7 +478,7 @@ async function loginWithEmail(json, apiUrl) {
|
|
|
414
478
|
};
|
|
415
479
|
saveCredentials(creds);
|
|
416
480
|
s.stop(`Authenticated as ${result.user.email}`);
|
|
417
|
-
|
|
481
|
+
clack3.outro("Done");
|
|
418
482
|
} else {
|
|
419
483
|
const result = await login(email, password2, apiUrl);
|
|
420
484
|
const creds = {
|
|
@@ -426,105 +490,15 @@ async function loginWithEmail(json, apiUrl) {
|
|
|
426
490
|
console.log(JSON.stringify({ success: true, user: result.user }));
|
|
427
491
|
}
|
|
428
492
|
}
|
|
429
|
-
async function loginWithOAuth(json, apiUrl
|
|
430
|
-
const platformUrl = getPlatformApiUrl(apiUrl);
|
|
431
|
-
const config = getGlobalConfig();
|
|
432
|
-
const clientId = clientIdOverride ?? config.oauth_client_id ?? DEFAULT_CLIENT_ID;
|
|
433
|
-
const pkce = generatePKCE();
|
|
434
|
-
const state = generateState();
|
|
435
|
-
const { port, result, close } = await startCallbackServer();
|
|
436
|
-
const redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
437
|
-
const authUrl = buildAuthorizeUrl({
|
|
438
|
-
platformUrl,
|
|
439
|
-
clientId,
|
|
440
|
-
redirectUri,
|
|
441
|
-
codeChallenge: pkce.code_challenge,
|
|
442
|
-
state,
|
|
443
|
-
scopes: OAUTH_SCOPES
|
|
444
|
-
});
|
|
493
|
+
async function loginWithOAuth(json, apiUrl) {
|
|
445
494
|
if (!json) {
|
|
446
|
-
|
|
447
|
-
clack.log.info("Opening browser for authentication...");
|
|
448
|
-
clack.log.info(`If browser doesn't open, visit:
|
|
449
|
-
${authUrl}`);
|
|
450
|
-
}
|
|
451
|
-
try {
|
|
452
|
-
const open = (await import("open")).default;
|
|
453
|
-
await open(authUrl);
|
|
454
|
-
} catch {
|
|
455
|
-
if (!json) {
|
|
456
|
-
clack.log.warn(`Could not open browser. Please visit the URL above.`);
|
|
457
|
-
}
|
|
495
|
+
clack3.intro("InsForge CLI");
|
|
458
496
|
}
|
|
497
|
+
const creds = await performOAuthLogin(apiUrl);
|
|
459
498
|
if (!json) {
|
|
460
|
-
|
|
461
|
-
s.start("Waiting for authentication...");
|
|
462
|
-
try {
|
|
463
|
-
const callbackResult = await result;
|
|
464
|
-
close();
|
|
465
|
-
if (callbackResult.state !== state) {
|
|
466
|
-
s.stop("Authentication failed");
|
|
467
|
-
throw new Error("State mismatch. Possible CSRF attack.");
|
|
468
|
-
}
|
|
469
|
-
s.message("Exchanging authorization code...");
|
|
470
|
-
const tokens = await exchangeCodeForTokens({
|
|
471
|
-
platformUrl,
|
|
472
|
-
code: callbackResult.code,
|
|
473
|
-
redirectUri,
|
|
474
|
-
clientId,
|
|
475
|
-
codeVerifier: pkce.code_verifier
|
|
476
|
-
});
|
|
477
|
-
const creds = {
|
|
478
|
-
access_token: tokens.access_token,
|
|
479
|
-
refresh_token: tokens.refresh_token,
|
|
480
|
-
user: { id: "", name: "", email: "", avatar_url: null, email_verified: true }
|
|
481
|
-
};
|
|
482
|
-
saveCredentials(creds);
|
|
483
|
-
try {
|
|
484
|
-
const profile = await getProfile(apiUrl);
|
|
485
|
-
creds.user = profile;
|
|
486
|
-
saveCredentials(creds);
|
|
487
|
-
s.stop(`Authenticated as ${profile.email}`);
|
|
488
|
-
} catch {
|
|
489
|
-
s.stop("Authenticated successfully");
|
|
490
|
-
}
|
|
491
|
-
clack.outro("Done");
|
|
492
|
-
} catch (err) {
|
|
493
|
-
close();
|
|
494
|
-
s.stop("Authentication failed");
|
|
495
|
-
throw err;
|
|
496
|
-
}
|
|
499
|
+
clack3.outro("Done");
|
|
497
500
|
} else {
|
|
498
|
-
|
|
499
|
-
const callbackResult = await result;
|
|
500
|
-
close();
|
|
501
|
-
if (callbackResult.state !== state) {
|
|
502
|
-
throw new Error("State mismatch.");
|
|
503
|
-
}
|
|
504
|
-
const tokens = await exchangeCodeForTokens({
|
|
505
|
-
platformUrl,
|
|
506
|
-
code: callbackResult.code,
|
|
507
|
-
redirectUri,
|
|
508
|
-
clientId,
|
|
509
|
-
codeVerifier: pkce.code_verifier
|
|
510
|
-
});
|
|
511
|
-
const creds = {
|
|
512
|
-
access_token: tokens.access_token,
|
|
513
|
-
refresh_token: tokens.refresh_token,
|
|
514
|
-
user: { id: "", name: "", email: "", avatar_url: null, email_verified: true }
|
|
515
|
-
};
|
|
516
|
-
saveCredentials(creds);
|
|
517
|
-
try {
|
|
518
|
-
const profile = await getProfile(apiUrl);
|
|
519
|
-
creds.user = profile;
|
|
520
|
-
saveCredentials(creds);
|
|
521
|
-
} catch {
|
|
522
|
-
}
|
|
523
|
-
console.log(JSON.stringify({ success: true, user: creds.user }));
|
|
524
|
-
} catch (err) {
|
|
525
|
-
close();
|
|
526
|
-
throw err;
|
|
527
|
-
}
|
|
501
|
+
console.log(JSON.stringify({ success: true, user: creds.user }));
|
|
528
502
|
}
|
|
529
503
|
}
|
|
530
504
|
|
|
@@ -572,7 +546,7 @@ function registerWhoamiCommand(program2) {
|
|
|
572
546
|
program2.command("whoami").description("Show current authenticated user").action(async (_opts, cmd) => {
|
|
573
547
|
const { json, apiUrl } = getRootOpts(cmd);
|
|
574
548
|
try {
|
|
575
|
-
requireAuth();
|
|
549
|
+
await requireAuth(apiUrl);
|
|
576
550
|
const profile = await getProfile(apiUrl);
|
|
577
551
|
if (json) {
|
|
578
552
|
outputJson(profile);
|
|
@@ -592,7 +566,7 @@ function registerOrgsCommands(orgsCmd2) {
|
|
|
592
566
|
orgsCmd2.command("list").description("List all organizations").action(async (_opts, cmd) => {
|
|
593
567
|
const { json, apiUrl } = getRootOpts(cmd);
|
|
594
568
|
try {
|
|
595
|
-
requireAuth();
|
|
569
|
+
await requireAuth(apiUrl);
|
|
596
570
|
const orgs = await listOrganizations(apiUrl);
|
|
597
571
|
if (json) {
|
|
598
572
|
outputJson(orgs);
|
|
@@ -617,12 +591,12 @@ function registerOrgsCommands(orgsCmd2) {
|
|
|
617
591
|
}
|
|
618
592
|
|
|
619
593
|
// src/commands/projects/list.ts
|
|
620
|
-
import * as
|
|
594
|
+
import * as clack4 from "@clack/prompts";
|
|
621
595
|
function registerProjectsCommands(projectsCmd2) {
|
|
622
596
|
projectsCmd2.command("list").description("List all projects in an organization").option("--org-id <id>", "Organization ID (uses default if not specified)").action(async (opts, cmd) => {
|
|
623
597
|
const { json, apiUrl } = getRootOpts(cmd);
|
|
624
598
|
try {
|
|
625
|
-
requireAuth();
|
|
599
|
+
await requireAuth(apiUrl);
|
|
626
600
|
let orgId = opts.orgId ?? getGlobalConfig().default_org_id;
|
|
627
601
|
if (!orgId) {
|
|
628
602
|
const orgs = await listOrganizations(apiUrl);
|
|
@@ -632,14 +606,14 @@ function registerProjectsCommands(projectsCmd2) {
|
|
|
632
606
|
if (orgs.length === 1) {
|
|
633
607
|
orgId = orgs[0].id;
|
|
634
608
|
} else if (!json) {
|
|
635
|
-
const selected = await
|
|
609
|
+
const selected = await clack4.select({
|
|
636
610
|
message: "Select an organization:",
|
|
637
611
|
options: orgs.map((o) => ({
|
|
638
612
|
value: o.id,
|
|
639
613
|
label: o.name
|
|
640
614
|
}))
|
|
641
615
|
});
|
|
642
|
-
if (
|
|
616
|
+
if (clack4.isCancel(selected)) {
|
|
643
617
|
process.exit(0);
|
|
644
618
|
}
|
|
645
619
|
orgId = selected;
|
|
@@ -667,23 +641,23 @@ function registerProjectsCommands(projectsCmd2) {
|
|
|
667
641
|
}
|
|
668
642
|
|
|
669
643
|
// src/commands/projects/link.ts
|
|
670
|
-
import * as
|
|
644
|
+
import * as clack6 from "@clack/prompts";
|
|
671
645
|
|
|
672
646
|
// src/lib/skills.ts
|
|
673
647
|
import { exec } from "child_process";
|
|
674
648
|
import { promisify } from "util";
|
|
675
|
-
import * as
|
|
649
|
+
import * as clack5 from "@clack/prompts";
|
|
676
650
|
var execAsync = promisify(exec);
|
|
677
651
|
async function installSkills(json) {
|
|
678
652
|
try {
|
|
679
|
-
if (!json)
|
|
653
|
+
if (!json) clack5.log.info("Installing InsForge agent skills...");
|
|
680
654
|
await execAsync("npx skills add insforge/agent-skills -y -a antigravity -a augment -a claude-code -a cline -a codex -a cursor -a gemini-cli -a github-copilot -a kilo -a qoder -a qwen-code -a roo -a trae -a windsurf", {
|
|
681
655
|
cwd: process.cwd(),
|
|
682
656
|
timeout: 6e4
|
|
683
657
|
});
|
|
684
|
-
if (!json)
|
|
658
|
+
if (!json) clack5.log.success("InsForge agent skills installed.");
|
|
685
659
|
} catch {
|
|
686
|
-
if (!json)
|
|
660
|
+
if (!json) clack5.log.warn("Failed to install agent skills. You can run manually: npx skills add insforge/agent-skills");
|
|
687
661
|
}
|
|
688
662
|
}
|
|
689
663
|
|
|
@@ -695,7 +669,7 @@ function registerProjectLinkCommand(program2) {
|
|
|
695
669
|
program2.command("link").description("Link current directory to an InsForge project").option("--project-id <id>", "Project ID to link").option("--org-id <id>", "Organization ID").action(async (opts, cmd) => {
|
|
696
670
|
const { json, apiUrl } = getRootOpts(cmd);
|
|
697
671
|
try {
|
|
698
|
-
requireAuth();
|
|
672
|
+
await requireAuth(apiUrl);
|
|
699
673
|
let orgId = opts.orgId;
|
|
700
674
|
let projectId = opts.projectId;
|
|
701
675
|
if (!orgId) {
|
|
@@ -706,14 +680,14 @@ function registerProjectLinkCommand(program2) {
|
|
|
706
680
|
if (json) {
|
|
707
681
|
throw new CLIError("Specify --org-id in JSON mode.");
|
|
708
682
|
}
|
|
709
|
-
const selected = await
|
|
683
|
+
const selected = await clack6.select({
|
|
710
684
|
message: "Select an organization:",
|
|
711
685
|
options: orgs.map((o) => ({
|
|
712
686
|
value: o.id,
|
|
713
687
|
label: o.name
|
|
714
688
|
}))
|
|
715
689
|
});
|
|
716
|
-
if (
|
|
690
|
+
if (clack6.isCancel(selected)) process.exit(0);
|
|
717
691
|
orgId = selected;
|
|
718
692
|
}
|
|
719
693
|
const config = getGlobalConfig();
|
|
@@ -727,14 +701,14 @@ function registerProjectLinkCommand(program2) {
|
|
|
727
701
|
if (json) {
|
|
728
702
|
throw new CLIError("Specify --project-id in JSON mode.");
|
|
729
703
|
}
|
|
730
|
-
const selected = await
|
|
704
|
+
const selected = await clack6.select({
|
|
731
705
|
message: "Select a project to link:",
|
|
732
706
|
options: projects.map((p) => ({
|
|
733
707
|
value: p.id,
|
|
734
708
|
label: `${p.name} (${p.region}, ${p.status})`
|
|
735
709
|
}))
|
|
736
710
|
});
|
|
737
|
-
if (
|
|
711
|
+
if (clack6.isCancel(selected)) process.exit(0);
|
|
738
712
|
projectId = selected;
|
|
739
713
|
}
|
|
740
714
|
const [project, apiKey] = await Promise.all([
|
|
@@ -796,7 +770,7 @@ function registerDbCommands(dbCmd2) {
|
|
|
796
770
|
dbCmd2.command("query <sql>").description("Execute a SQL query against the database").option("--unrestricted", "Use unrestricted mode (allows system table access)").action(async (sql, opts, cmd) => {
|
|
797
771
|
const { json } = getRootOpts(cmd);
|
|
798
772
|
try {
|
|
799
|
-
requireAuth();
|
|
773
|
+
await requireAuth();
|
|
800
774
|
const endpoint = opts.unrestricted ? "/api/database/advance/rawsql/unrestricted" : "/api/database/advance/rawsql";
|
|
801
775
|
const res = await ossFetch(endpoint, {
|
|
802
776
|
method: "POST",
|
|
@@ -832,7 +806,7 @@ function registerDbTablesCommand(dbCmd2) {
|
|
|
832
806
|
dbCmd2.command("tables").description("List all database tables").action(async (_opts, cmd) => {
|
|
833
807
|
const { json } = getRootOpts(cmd);
|
|
834
808
|
try {
|
|
835
|
-
requireAuth();
|
|
809
|
+
await requireAuth();
|
|
836
810
|
const res = await ossFetch("/api/database/tables");
|
|
837
811
|
const tables = await res.json();
|
|
838
812
|
if (json) {
|
|
@@ -871,7 +845,7 @@ function registerDbFunctionsCommand(dbCmd2) {
|
|
|
871
845
|
dbCmd2.command("functions").description("List all database functions").action(async (_opts, cmd) => {
|
|
872
846
|
const { json } = getRootOpts(cmd);
|
|
873
847
|
try {
|
|
874
|
-
requireAuth();
|
|
848
|
+
await requireAuth();
|
|
875
849
|
const res = await ossFetch("/api/database/functions");
|
|
876
850
|
const raw = await res.json();
|
|
877
851
|
const functions = extractArray(raw);
|
|
@@ -911,7 +885,7 @@ function registerDbIndexesCommand(dbCmd2) {
|
|
|
911
885
|
dbCmd2.command("indexes").description("List all database indexes").action(async (_opts, cmd) => {
|
|
912
886
|
const { json } = getRootOpts(cmd);
|
|
913
887
|
try {
|
|
914
|
-
requireAuth();
|
|
888
|
+
await requireAuth();
|
|
915
889
|
const res = await ossFetch("/api/database/indexes");
|
|
916
890
|
const raw = await res.json();
|
|
917
891
|
const indexes = extractArray2(raw);
|
|
@@ -957,7 +931,7 @@ function registerDbPoliciesCommand(dbCmd2) {
|
|
|
957
931
|
dbCmd2.command("policies").description("List all RLS policies").action(async (_opts, cmd) => {
|
|
958
932
|
const { json } = getRootOpts(cmd);
|
|
959
933
|
try {
|
|
960
|
-
requireAuth();
|
|
934
|
+
await requireAuth();
|
|
961
935
|
const res = await ossFetch("/api/database/policies");
|
|
962
936
|
const raw = await res.json();
|
|
963
937
|
const policies = extractArray3(raw);
|
|
@@ -1004,7 +978,7 @@ function registerDbTriggersCommand(dbCmd2) {
|
|
|
1004
978
|
dbCmd2.command("triggers").description("List all database triggers").action(async (_opts, cmd) => {
|
|
1005
979
|
const { json } = getRootOpts(cmd);
|
|
1006
980
|
try {
|
|
1007
|
-
requireAuth();
|
|
981
|
+
await requireAuth();
|
|
1008
982
|
const res = await ossFetch("/api/database/triggers");
|
|
1009
983
|
const raw = await res.json();
|
|
1010
984
|
const triggers = extractArray4(raw);
|
|
@@ -1038,7 +1012,7 @@ function registerDbRpcCommand(dbCmd2) {
|
|
|
1038
1012
|
dbCmd2.command("rpc <functionName>").description("Call a database function via RPC").option("--data <json>", "JSON body to pass as function parameters").action(async (functionName, opts, cmd) => {
|
|
1039
1013
|
const { json } = getRootOpts(cmd);
|
|
1040
1014
|
try {
|
|
1041
|
-
requireAuth();
|
|
1015
|
+
await requireAuth();
|
|
1042
1016
|
const body = opts.data ? JSON.stringify(JSON.parse(opts.data)) : void 0;
|
|
1043
1017
|
const res = await ossFetch(`/api/database/rpc/${encodeURIComponent(functionName)}`, {
|
|
1044
1018
|
method: body ? "POST" : "GET",
|
|
@@ -1062,7 +1036,7 @@ function registerDbExportCommand(dbCmd2) {
|
|
|
1062
1036
|
dbCmd2.command("export").description("Export database schema and/or data").option("--format <format>", "Export format: sql or json", "sql").option("--tables <tables>", "Comma-separated list of tables to export (default: all)").option("--no-data", "Exclude table data (schema only)").option("--include-functions", "Include database functions").option("--include-sequences", "Include sequences").option("--include-views", "Include views").option("--row-limit <n>", "Maximum rows per table").option("-o, --output <file>", "Output file path (default: stdout)").action(async (opts, cmd) => {
|
|
1063
1037
|
const { json } = getRootOpts(cmd);
|
|
1064
1038
|
try {
|
|
1065
|
-
requireAuth();
|
|
1039
|
+
await requireAuth();
|
|
1066
1040
|
const body = {
|
|
1067
1041
|
format: opts.format,
|
|
1068
1042
|
includeData: opts.data !== false
|
|
@@ -1117,7 +1091,7 @@ function registerDbImportCommand(dbCmd2) {
|
|
|
1117
1091
|
dbCmd2.command("import <file>").description("Import database from a local SQL file").option("--truncate", "Truncate existing tables before import").action(async (file, opts, cmd) => {
|
|
1118
1092
|
const { json } = getRootOpts(cmd);
|
|
1119
1093
|
try {
|
|
1120
|
-
requireAuth();
|
|
1094
|
+
await requireAuth();
|
|
1121
1095
|
const config = getProjectConfig();
|
|
1122
1096
|
if (!config) throw new ProjectNotLinkedError();
|
|
1123
1097
|
const fileContent = readFileSync2(file);
|
|
@@ -1155,7 +1129,7 @@ function registerRecordsCommands(recordsCmd2) {
|
|
|
1155
1129
|
recordsCmd2.command("list <table>").description("List records from a table").option("--select <columns>", "Columns to select (comma-separated)").option("--filter <filter>", 'Filter expression (e.g. "name=eq.John")').option("--order <order>", 'Order by (e.g. "created_at.desc")').option("--limit <n>", "Limit number of records", parseInt).option("--offset <n>", "Offset for pagination", parseInt).action(async (table, opts, cmd) => {
|
|
1156
1130
|
const { json } = getRootOpts(cmd);
|
|
1157
1131
|
try {
|
|
1158
|
-
requireAuth();
|
|
1132
|
+
await requireAuth();
|
|
1159
1133
|
const params = new URLSearchParams();
|
|
1160
1134
|
if (opts.select) params.set("select", opts.select);
|
|
1161
1135
|
if (opts.filter) params.set(opts.filter.split("=")[0], opts.filter.split("=").slice(1).join("="));
|
|
@@ -1197,7 +1171,7 @@ function registerRecordsCreateCommand(recordsCmd2) {
|
|
|
1197
1171
|
recordsCmd2.command("create <table>").description("Create record(s) in a table").option("--data <json>", "JSON data to insert (object or array of objects)").action(async (table, opts, cmd) => {
|
|
1198
1172
|
const { json } = getRootOpts(cmd);
|
|
1199
1173
|
try {
|
|
1200
|
-
requireAuth();
|
|
1174
|
+
await requireAuth();
|
|
1201
1175
|
if (!opts.data) {
|
|
1202
1176
|
throw new CLIError(`--data is required. Example: --data '{"name":"John"}'`);
|
|
1203
1177
|
}
|
|
@@ -1233,7 +1207,7 @@ function registerRecordsUpdateCommand(recordsCmd2) {
|
|
|
1233
1207
|
recordsCmd2.command("update <table>").description("Update records in a table matching a filter").option("--filter <filter>", 'Filter expression (e.g. "id=eq.123")').option("--data <json>", "JSON data to update").action(async (table, opts, cmd) => {
|
|
1234
1208
|
const { json } = getRootOpts(cmd);
|
|
1235
1209
|
try {
|
|
1236
|
-
requireAuth();
|
|
1210
|
+
await requireAuth();
|
|
1237
1211
|
if (!opts.filter) {
|
|
1238
1212
|
throw new CLIError("--filter is required to prevent accidental updates to all rows.");
|
|
1239
1213
|
}
|
|
@@ -1274,7 +1248,7 @@ function registerRecordsDeleteCommand(recordsCmd2) {
|
|
|
1274
1248
|
recordsCmd2.command("delete <table>").description("Delete records from a table matching a filter").option("--filter <filter>", 'Filter expression (e.g. "id=eq.123")').action(async (table, opts, cmd) => {
|
|
1275
1249
|
const { json } = getRootOpts(cmd);
|
|
1276
1250
|
try {
|
|
1277
|
-
requireAuth();
|
|
1251
|
+
await requireAuth();
|
|
1278
1252
|
if (!opts.filter) {
|
|
1279
1253
|
throw new CLIError("--filter is required to prevent accidental deletion of all rows.");
|
|
1280
1254
|
}
|
|
@@ -1303,7 +1277,7 @@ function registerFunctionsCommands(functionsCmd2) {
|
|
|
1303
1277
|
functionsCmd2.command("list").description("List all edge functions").action(async (_opts, cmd) => {
|
|
1304
1278
|
const { json } = getRootOpts(cmd);
|
|
1305
1279
|
try {
|
|
1306
|
-
requireAuth();
|
|
1280
|
+
await requireAuth();
|
|
1307
1281
|
const res = await ossFetch("/api/functions");
|
|
1308
1282
|
const data = await res.json();
|
|
1309
1283
|
const functions = data.functions ?? [];
|
|
@@ -1337,7 +1311,7 @@ function registerFunctionsDeployCommand(functionsCmd2) {
|
|
|
1337
1311
|
functionsCmd2.command("deploy <slug>").description("Deploy an edge function (create or update)").option("--file <path>", "Path to the function source file").option("--name <name>", "Function display name").option("--description <desc>", "Function description").action(async (slug, opts, cmd) => {
|
|
1338
1312
|
const { json } = getRootOpts(cmd);
|
|
1339
1313
|
try {
|
|
1340
|
-
requireAuth();
|
|
1314
|
+
await requireAuth();
|
|
1341
1315
|
const filePath = opts.file ?? join2(process.cwd(), "insforge", "functions", slug, "index.ts");
|
|
1342
1316
|
if (!existsSync2(filePath)) {
|
|
1343
1317
|
throw new CLIError(
|
|
@@ -1382,7 +1356,7 @@ function registerFunctionsInvokeCommand(functionsCmd2) {
|
|
|
1382
1356
|
functionsCmd2.command("invoke <slug>").description("Invoke an edge function").option("--data <json>", "JSON body to send to the function").option("--method <method>", "HTTP method (GET, POST, PUT, PATCH, DELETE)", "POST").action(async (slug, opts, cmd) => {
|
|
1383
1357
|
const { json } = getRootOpts(cmd);
|
|
1384
1358
|
try {
|
|
1385
|
-
requireAuth();
|
|
1359
|
+
await requireAuth();
|
|
1386
1360
|
const config = getProjectConfig();
|
|
1387
1361
|
if (!config) throw new ProjectNotLinkedError();
|
|
1388
1362
|
const method = opts.method.toUpperCase();
|
|
@@ -1431,7 +1405,7 @@ function registerFunctionsCodeCommand(functionsCmd2) {
|
|
|
1431
1405
|
functionsCmd2.command("code <slug>").description("Fetch and display the source code of an edge function").action(async (slug, _opts, cmd) => {
|
|
1432
1406
|
const { json } = getRootOpts(cmd);
|
|
1433
1407
|
try {
|
|
1434
|
-
requireAuth();
|
|
1408
|
+
await requireAuth();
|
|
1435
1409
|
const res = await ossFetch(`/api/functions/${encodeURIComponent(slug)}`);
|
|
1436
1410
|
const fn = await res.json();
|
|
1437
1411
|
if (json) {
|
|
@@ -1455,7 +1429,7 @@ function registerStorageBucketsCommand(storageCmd2) {
|
|
|
1455
1429
|
storageCmd2.command("buckets").description("List all storage buckets").action(async (_opts, cmd) => {
|
|
1456
1430
|
const { json } = getRootOpts(cmd);
|
|
1457
1431
|
try {
|
|
1458
|
-
requireAuth();
|
|
1432
|
+
await requireAuth();
|
|
1459
1433
|
const res = await ossFetch("/api/storage/buckets");
|
|
1460
1434
|
const raw = await res.json();
|
|
1461
1435
|
let buckets;
|
|
@@ -1492,7 +1466,7 @@ function registerStorageUploadCommand(storageCmd2) {
|
|
|
1492
1466
|
storageCmd2.command("upload <file>").description("Upload a file to a storage bucket").requiredOption("--bucket <name>", "Target bucket name").option("--key <objectKey>", "Object key (defaults to filename)").action(async (file, opts, cmd) => {
|
|
1493
1467
|
const { json } = getRootOpts(cmd);
|
|
1494
1468
|
try {
|
|
1495
|
-
requireAuth();
|
|
1469
|
+
await requireAuth();
|
|
1496
1470
|
const config = getProjectConfig();
|
|
1497
1471
|
if (!config) throw new ProjectNotLinkedError();
|
|
1498
1472
|
if (!existsSync3(file)) {
|
|
@@ -1535,7 +1509,7 @@ function registerStorageDownloadCommand(storageCmd2) {
|
|
|
1535
1509
|
storageCmd2.command("download <objectKey>").description("Download a file from a storage bucket").requiredOption("--bucket <name>", "Source bucket name").option("--output <path>", "Output file path (defaults to current directory)").action(async (objectKey, opts, cmd) => {
|
|
1536
1510
|
const { json } = getRootOpts(cmd);
|
|
1537
1511
|
try {
|
|
1538
|
-
requireAuth();
|
|
1512
|
+
await requireAuth();
|
|
1539
1513
|
const config = getProjectConfig();
|
|
1540
1514
|
if (!config) throw new ProjectNotLinkedError();
|
|
1541
1515
|
const bucketName = opts.bucket;
|
|
@@ -1568,7 +1542,7 @@ function registerStorageCreateBucketCommand(storageCmd2) {
|
|
|
1568
1542
|
storageCmd2.command("create-bucket <name>").description("Create a new storage bucket").option("--public", "Make the bucket publicly accessible (default)").option("--private", "Make the bucket private").action(async (name, opts, cmd) => {
|
|
1569
1543
|
const { json } = getRootOpts(cmd);
|
|
1570
1544
|
try {
|
|
1571
|
-
requireAuth();
|
|
1545
|
+
await requireAuth();
|
|
1572
1546
|
const isPublic = !opts.private;
|
|
1573
1547
|
const res = await ossFetch("/api/storage/buckets", {
|
|
1574
1548
|
method: "POST",
|
|
@@ -1587,17 +1561,17 @@ function registerStorageCreateBucketCommand(storageCmd2) {
|
|
|
1587
1561
|
}
|
|
1588
1562
|
|
|
1589
1563
|
// src/commands/storage/delete-bucket.ts
|
|
1590
|
-
import * as
|
|
1564
|
+
import * as clack7 from "@clack/prompts";
|
|
1591
1565
|
function registerStorageDeleteBucketCommand(storageCmd2) {
|
|
1592
1566
|
storageCmd2.command("delete-bucket <name>").description("Delete a storage bucket and all its objects").action(async (name, _opts, cmd) => {
|
|
1593
1567
|
const { json, yes } = getRootOpts(cmd);
|
|
1594
1568
|
try {
|
|
1595
|
-
requireAuth();
|
|
1569
|
+
await requireAuth();
|
|
1596
1570
|
if (!yes && !json) {
|
|
1597
|
-
const
|
|
1571
|
+
const confirm5 = await clack7.confirm({
|
|
1598
1572
|
message: `Delete bucket "${name}" and all its objects? This cannot be undone.`
|
|
1599
1573
|
});
|
|
1600
|
-
if (!
|
|
1574
|
+
if (!confirm5 || clack7.isCancel(confirm5)) {
|
|
1601
1575
|
process.exit(0);
|
|
1602
1576
|
}
|
|
1603
1577
|
}
|
|
@@ -1626,7 +1600,7 @@ function registerStorageListObjectsCommand(storageCmd2) {
|
|
|
1626
1600
|
storageCmd2.command("list-objects <bucket>").description("List objects in a storage bucket").option("--limit <n>", "Maximum number of objects to return", "100").option("--offset <n>", "Number of objects to skip", "0").option("--prefix <prefix>", "Filter objects by key prefix").option("--search <term>", "Search objects by key (partial match)").option("--sort <field>", "Sort by field: key, size, uploadedAt (default: key)").action(async (bucket, opts, cmd) => {
|
|
1627
1601
|
const { json } = getRootOpts(cmd);
|
|
1628
1602
|
try {
|
|
1629
|
-
requireAuth();
|
|
1603
|
+
await requireAuth();
|
|
1630
1604
|
const params = new URLSearchParams();
|
|
1631
1605
|
params.set("limit", opts.limit);
|
|
1632
1606
|
params.set("offset", opts.offset);
|
|
@@ -1677,7 +1651,7 @@ import { tmpdir } from "os";
|
|
|
1677
1651
|
import { promisify as promisify2 } from "util";
|
|
1678
1652
|
import * as fs from "fs/promises";
|
|
1679
1653
|
import * as path from "path";
|
|
1680
|
-
import * as
|
|
1654
|
+
import * as clack8 from "@clack/prompts";
|
|
1681
1655
|
var execAsync2 = promisify2(exec2);
|
|
1682
1656
|
function buildOssHost2(appkey, region) {
|
|
1683
1657
|
return `https://${appkey}.${region}.insforge.app`;
|
|
@@ -1708,9 +1682,9 @@ function registerCreateCommand(program2) {
|
|
|
1708
1682
|
program2.command("create").description("Create a new InsForge project").option("--name <name>", "Project name").option("--org-id <id>", "Organization ID").option("--region <region>", "Deployment region (us-east, us-west, eu-central, ap-southeast)").option("--template <template>", "Template to use: react, nextjs, or empty").action(async (opts, cmd) => {
|
|
1709
1683
|
const { json, apiUrl } = getRootOpts(cmd);
|
|
1710
1684
|
try {
|
|
1711
|
-
requireAuth();
|
|
1685
|
+
await requireAuth(apiUrl);
|
|
1712
1686
|
if (!json) {
|
|
1713
|
-
|
|
1687
|
+
clack8.intro("Create a new InsForge project");
|
|
1714
1688
|
}
|
|
1715
1689
|
let orgId = opts.orgId;
|
|
1716
1690
|
if (!orgId) {
|
|
@@ -1721,14 +1695,14 @@ function registerCreateCommand(program2) {
|
|
|
1721
1695
|
if (json) {
|
|
1722
1696
|
throw new CLIError("Specify --org-id in JSON mode.");
|
|
1723
1697
|
}
|
|
1724
|
-
const selected = await
|
|
1698
|
+
const selected = await clack8.select({
|
|
1725
1699
|
message: "Select an organization:",
|
|
1726
1700
|
options: orgs.map((o) => ({
|
|
1727
1701
|
value: o.id,
|
|
1728
1702
|
label: o.name
|
|
1729
1703
|
}))
|
|
1730
1704
|
});
|
|
1731
|
-
if (
|
|
1705
|
+
if (clack8.isCancel(selected)) process.exit(0);
|
|
1732
1706
|
orgId = selected;
|
|
1733
1707
|
}
|
|
1734
1708
|
const globalConfig = getGlobalConfig();
|
|
@@ -1737,11 +1711,11 @@ function registerCreateCommand(program2) {
|
|
|
1737
1711
|
let projectName = opts.name;
|
|
1738
1712
|
if (!projectName) {
|
|
1739
1713
|
if (json) throw new CLIError("--name is required in JSON mode.");
|
|
1740
|
-
const name = await
|
|
1714
|
+
const name = await clack8.text({
|
|
1741
1715
|
message: "Project name:",
|
|
1742
1716
|
validate: (v) => v.length >= 2 ? void 0 : "Name must be at least 2 characters"
|
|
1743
1717
|
});
|
|
1744
|
-
if (
|
|
1718
|
+
if (clack8.isCancel(name)) process.exit(0);
|
|
1745
1719
|
projectName = name;
|
|
1746
1720
|
}
|
|
1747
1721
|
let template = opts.template;
|
|
@@ -1749,7 +1723,7 @@ function registerCreateCommand(program2) {
|
|
|
1749
1723
|
if (json) {
|
|
1750
1724
|
template = "empty";
|
|
1751
1725
|
} else {
|
|
1752
|
-
const selected = await
|
|
1726
|
+
const selected = await clack8.select({
|
|
1753
1727
|
message: "Choose a starter template:",
|
|
1754
1728
|
options: [
|
|
1755
1729
|
{ value: "react", label: "Web app template with React" },
|
|
@@ -1757,11 +1731,11 @@ function registerCreateCommand(program2) {
|
|
|
1757
1731
|
{ value: "empty", label: "Empty project" }
|
|
1758
1732
|
]
|
|
1759
1733
|
});
|
|
1760
|
-
if (
|
|
1734
|
+
if (clack8.isCancel(selected)) process.exit(0);
|
|
1761
1735
|
template = selected;
|
|
1762
1736
|
}
|
|
1763
1737
|
}
|
|
1764
|
-
const s = !json ?
|
|
1738
|
+
const s = !json ? clack8.spinner() : null;
|
|
1765
1739
|
s?.start("Creating project...");
|
|
1766
1740
|
const project = await createProject(orgId, projectName, opts.region, apiUrl);
|
|
1767
1741
|
s?.message("Waiting for project to become active...");
|
|
@@ -1789,7 +1763,7 @@ function registerCreateCommand(program2) {
|
|
|
1789
1763
|
template
|
|
1790
1764
|
});
|
|
1791
1765
|
} else {
|
|
1792
|
-
|
|
1766
|
+
clack8.outro("Done! Run `npm install` to get started.");
|
|
1793
1767
|
}
|
|
1794
1768
|
} catch (err) {
|
|
1795
1769
|
handleError(err, json);
|
|
@@ -1797,7 +1771,7 @@ function registerCreateCommand(program2) {
|
|
|
1797
1771
|
});
|
|
1798
1772
|
}
|
|
1799
1773
|
async function downloadTemplate(framework, projectConfig, projectName, json, _apiUrl) {
|
|
1800
|
-
const s = !json ?
|
|
1774
|
+
const s = !json ? clack8.spinner() : null;
|
|
1801
1775
|
s?.start("Downloading template...");
|
|
1802
1776
|
try {
|
|
1803
1777
|
const anonKey = await getAnonKey();
|
|
@@ -1827,8 +1801,8 @@ async function downloadTemplate(framework, projectConfig, projectName, json, _ap
|
|
|
1827
1801
|
} catch (err) {
|
|
1828
1802
|
s?.stop("Template download failed");
|
|
1829
1803
|
if (!json) {
|
|
1830
|
-
|
|
1831
|
-
|
|
1804
|
+
clack8.log.warn(`Failed to download template: ${err.message}`);
|
|
1805
|
+
clack8.log.info("You can manually set up the template later.");
|
|
1832
1806
|
}
|
|
1833
1807
|
}
|
|
1834
1808
|
}
|
|
@@ -1882,7 +1856,7 @@ function registerListCommand(program2) {
|
|
|
1882
1856
|
program2.command("list").description("List all organizations and their projects").action(async (_opts, cmd) => {
|
|
1883
1857
|
const { json, apiUrl } = getRootOpts(cmd);
|
|
1884
1858
|
try {
|
|
1885
|
-
requireAuth();
|
|
1859
|
+
await requireAuth(apiUrl);
|
|
1886
1860
|
const orgs = await listOrganizations(apiUrl);
|
|
1887
1861
|
if (orgs.length === 0) {
|
|
1888
1862
|
if (json) {
|
|
@@ -1942,7 +1916,7 @@ function registerListCommand(program2) {
|
|
|
1942
1916
|
// src/commands/deployments/deploy.ts
|
|
1943
1917
|
import * as path2 from "path";
|
|
1944
1918
|
import * as fs2 from "fs/promises";
|
|
1945
|
-
import * as
|
|
1919
|
+
import * as clack9 from "@clack/prompts";
|
|
1946
1920
|
import archiver from "archiver";
|
|
1947
1921
|
var POLL_INTERVAL_MS = 5e3;
|
|
1948
1922
|
var POLL_TIMEOUT_MS = 12e4;
|
|
@@ -1985,7 +1959,7 @@ function registerDeploymentsDeployCommand(deploymentsCmd2) {
|
|
|
1985
1959
|
deploymentsCmd2.command("deploy [directory]").description("Deploy a frontend project to Vercel").option("--env <vars>", `Environment variables as JSON (e.g. '{"KEY":"value"}')`).option("--meta <meta>", "Deployment metadata as JSON").action(async (directory, opts, cmd) => {
|
|
1986
1960
|
const { json } = getRootOpts(cmd);
|
|
1987
1961
|
try {
|
|
1988
|
-
requireAuth();
|
|
1962
|
+
await requireAuth();
|
|
1989
1963
|
const config = getProjectConfig();
|
|
1990
1964
|
if (!config) throw new ProjectNotLinkedError();
|
|
1991
1965
|
const sourceDir = path2.resolve(directory ?? ".");
|
|
@@ -1993,7 +1967,7 @@ function registerDeploymentsDeployCommand(deploymentsCmd2) {
|
|
|
1993
1967
|
if (!stats?.isDirectory()) {
|
|
1994
1968
|
throw new CLIError(`"${sourceDir}" is not a valid directory.`);
|
|
1995
1969
|
}
|
|
1996
|
-
const s = !json ?
|
|
1970
|
+
const s = !json ? clack9.spinner() : null;
|
|
1997
1971
|
s?.start("Creating deployment...");
|
|
1998
1972
|
const createRes = await ossFetch("/api/deployments", { method: "POST" });
|
|
1999
1973
|
const { id: deploymentId, uploadUrl, uploadFields } = await createRes.json();
|
|
@@ -2069,18 +2043,18 @@ function registerDeploymentsDeployCommand(deploymentsCmd2) {
|
|
|
2069
2043
|
} else {
|
|
2070
2044
|
const liveUrl = deployment?.deploymentUrl ?? deployment?.url;
|
|
2071
2045
|
if (liveUrl) {
|
|
2072
|
-
|
|
2046
|
+
clack9.log.success(`Live at: ${liveUrl}`);
|
|
2073
2047
|
}
|
|
2074
|
-
|
|
2048
|
+
clack9.log.info(`Deployment ID: ${deploymentId}`);
|
|
2075
2049
|
}
|
|
2076
2050
|
} else {
|
|
2077
2051
|
s?.stop("Deployment is still building");
|
|
2078
2052
|
if (json) {
|
|
2079
2053
|
outputJson({ id: deploymentId, status: deployment?.status ?? "building", timedOut: true });
|
|
2080
2054
|
} else {
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2055
|
+
clack9.log.info(`Deployment ID: ${deploymentId}`);
|
|
2056
|
+
clack9.log.warn("Deployment did not finish within 2 minutes.");
|
|
2057
|
+
clack9.log.info(`Check status with: insforge deployments status ${deploymentId}`);
|
|
2084
2058
|
}
|
|
2085
2059
|
}
|
|
2086
2060
|
} catch (err) {
|
|
@@ -2094,7 +2068,7 @@ function registerDeploymentsListCommand(deploymentsCmd2) {
|
|
|
2094
2068
|
deploymentsCmd2.command("list").description("List all deployments").option("--limit <n>", "Limit number of results", "20").option("--offset <n>", "Offset for pagination", "0").action(async (opts, cmd) => {
|
|
2095
2069
|
const { json } = getRootOpts(cmd);
|
|
2096
2070
|
try {
|
|
2097
|
-
requireAuth();
|
|
2071
|
+
await requireAuth();
|
|
2098
2072
|
if (!getProjectConfig()) throw new ProjectNotLinkedError();
|
|
2099
2073
|
const res = await ossFetch(`/api/deployments?limit=${opts.limit}&offset=${opts.offset}`);
|
|
2100
2074
|
const raw = await res.json();
|
|
@@ -2135,7 +2109,7 @@ function registerDeploymentsStatusCommand(deploymentsCmd2) {
|
|
|
2135
2109
|
deploymentsCmd2.command("status <id>").description("Get deployment details and sync status from Vercel").option("--sync", "Sync status from Vercel before showing").action(async (id, opts, cmd) => {
|
|
2136
2110
|
const { json } = getRootOpts(cmd);
|
|
2137
2111
|
try {
|
|
2138
|
-
requireAuth();
|
|
2112
|
+
await requireAuth();
|
|
2139
2113
|
if (!getProjectConfig()) throw new ProjectNotLinkedError();
|
|
2140
2114
|
if (opts.sync) {
|
|
2141
2115
|
await ossFetch(`/api/deployments/${id}/sync`, { method: "POST" });
|
|
@@ -2166,18 +2140,18 @@ function registerDeploymentsStatusCommand(deploymentsCmd2) {
|
|
|
2166
2140
|
}
|
|
2167
2141
|
|
|
2168
2142
|
// src/commands/deployments/cancel.ts
|
|
2169
|
-
import * as
|
|
2143
|
+
import * as clack10 from "@clack/prompts";
|
|
2170
2144
|
function registerDeploymentsCancelCommand(deploymentsCmd2) {
|
|
2171
2145
|
deploymentsCmd2.command("cancel <id>").description("Cancel a deployment").action(async (id, _opts, cmd) => {
|
|
2172
2146
|
const { json, yes } = getRootOpts(cmd);
|
|
2173
2147
|
try {
|
|
2174
|
-
requireAuth();
|
|
2148
|
+
await requireAuth();
|
|
2175
2149
|
if (!getProjectConfig()) throw new ProjectNotLinkedError();
|
|
2176
2150
|
if (!yes && !json) {
|
|
2177
|
-
const confirmed = await
|
|
2151
|
+
const confirmed = await clack10.confirm({
|
|
2178
2152
|
message: `Cancel deployment ${id}?`
|
|
2179
2153
|
});
|
|
2180
|
-
if (
|
|
2154
|
+
if (clack10.isCancel(confirmed) || !confirmed) process.exit(0);
|
|
2181
2155
|
}
|
|
2182
2156
|
const res = await ossFetch(`/api/deployments/${id}/cancel`, { method: "POST" });
|
|
2183
2157
|
const result = await res.json();
|
|
@@ -2208,7 +2182,7 @@ Examples:
|
|
|
2208
2182
|
insforge docs storage rest-api Show REST API storage docs`).action(async (feature, language, _opts, cmd) => {
|
|
2209
2183
|
const { json } = getRootOpts(cmd);
|
|
2210
2184
|
try {
|
|
2211
|
-
requireAuth();
|
|
2185
|
+
await requireAuth();
|
|
2212
2186
|
if (!feature) {
|
|
2213
2187
|
await listDocs(json);
|
|
2214
2188
|
return;
|
|
@@ -2264,7 +2238,7 @@ function registerSecretsListCommand(secretsCmd2) {
|
|
|
2264
2238
|
secretsCmd2.command("list").description("List secrets (metadata only, values are hidden)").option("--all", "Include inactive (deleted) secrets").action(async (opts, cmd) => {
|
|
2265
2239
|
const { json } = getRootOpts(cmd);
|
|
2266
2240
|
try {
|
|
2267
|
-
requireAuth();
|
|
2241
|
+
await requireAuth();
|
|
2268
2242
|
const res = await ossFetch("/api/secrets");
|
|
2269
2243
|
const data = await res.json();
|
|
2270
2244
|
let secrets = data.secrets ?? [];
|
|
@@ -2304,7 +2278,7 @@ function registerSecretsGetCommand(secretsCmd2) {
|
|
|
2304
2278
|
secretsCmd2.command("get <key>").description("Get the decrypted value of a secret").action(async (key, _opts, cmd) => {
|
|
2305
2279
|
const { json } = getRootOpts(cmd);
|
|
2306
2280
|
try {
|
|
2307
|
-
requireAuth();
|
|
2281
|
+
await requireAuth();
|
|
2308
2282
|
const res = await ossFetch(`/api/secrets/${encodeURIComponent(key)}`);
|
|
2309
2283
|
const data = await res.json();
|
|
2310
2284
|
if (json) {
|
|
@@ -2323,7 +2297,7 @@ function registerSecretsAddCommand(secretsCmd2) {
|
|
|
2323
2297
|
secretsCmd2.command("add <key> <value>").description("Create a new secret").option("--reserved", "Mark secret as protected from deletion").option("--expires <date>", "Expiration date (ISO 8601 format)").action(async (key, value, opts, cmd) => {
|
|
2324
2298
|
const { json } = getRootOpts(cmd);
|
|
2325
2299
|
try {
|
|
2326
|
-
requireAuth();
|
|
2300
|
+
await requireAuth();
|
|
2327
2301
|
const body = { key, value };
|
|
2328
2302
|
if (opts.reserved) body.isReserved = true;
|
|
2329
2303
|
if (opts.expires) body.expiresAt = opts.expires;
|
|
@@ -2348,7 +2322,7 @@ function registerSecretsUpdateCommand(secretsCmd2) {
|
|
|
2348
2322
|
secretsCmd2.command("update <key>").description("Update an existing secret").option("--value <value>", "New secret value").option("--active <bool>", "Set active status (true/false)").option("--reserved <bool>", "Set reserved status (true/false)").option("--expires <date>", 'Expiration date (ISO 8601, or "null" to remove)').action(async (key, opts, cmd) => {
|
|
2349
2323
|
const { json } = getRootOpts(cmd);
|
|
2350
2324
|
try {
|
|
2351
|
-
requireAuth();
|
|
2325
|
+
await requireAuth();
|
|
2352
2326
|
const body = {};
|
|
2353
2327
|
if (opts.value !== void 0) body.value = opts.value;
|
|
2354
2328
|
if (opts.active !== void 0) body.isActive = opts.active === "true";
|
|
@@ -2374,17 +2348,17 @@ function registerSecretsUpdateCommand(secretsCmd2) {
|
|
|
2374
2348
|
}
|
|
2375
2349
|
|
|
2376
2350
|
// src/commands/secrets/delete.ts
|
|
2377
|
-
import * as
|
|
2351
|
+
import * as clack11 from "@clack/prompts";
|
|
2378
2352
|
function registerSecretsDeleteCommand(secretsCmd2) {
|
|
2379
2353
|
secretsCmd2.command("delete <key>").description("Delete a secret").action(async (key, _opts, cmd) => {
|
|
2380
2354
|
const { json, yes } = getRootOpts(cmd);
|
|
2381
2355
|
try {
|
|
2382
|
-
requireAuth();
|
|
2356
|
+
await requireAuth();
|
|
2383
2357
|
if (!yes && !json) {
|
|
2384
|
-
const
|
|
2358
|
+
const confirm5 = await clack11.confirm({
|
|
2385
2359
|
message: `Delete secret "${key}"? This cannot be undone.`
|
|
2386
2360
|
});
|
|
2387
|
-
if (!
|
|
2361
|
+
if (!confirm5 || clack11.isCancel(confirm5)) {
|
|
2388
2362
|
process.exit(0);
|
|
2389
2363
|
}
|
|
2390
2364
|
}
|
|
@@ -2403,6 +2377,267 @@ function registerSecretsDeleteCommand(secretsCmd2) {
|
|
|
2403
2377
|
});
|
|
2404
2378
|
}
|
|
2405
2379
|
|
|
2380
|
+
// src/commands/schedules/list.ts
|
|
2381
|
+
function registerSchedulesListCommand(schedulesCmd2) {
|
|
2382
|
+
schedulesCmd2.command("list").description("List all schedules").action(async (_opts, cmd) => {
|
|
2383
|
+
const { json } = getRootOpts(cmd);
|
|
2384
|
+
try {
|
|
2385
|
+
await requireAuth();
|
|
2386
|
+
const res = await ossFetch("/api/schedules");
|
|
2387
|
+
const data = await res.json();
|
|
2388
|
+
const schedules = Array.isArray(data) ? data : data.schedules ?? [];
|
|
2389
|
+
if (json) {
|
|
2390
|
+
outputJson(schedules);
|
|
2391
|
+
} else {
|
|
2392
|
+
if (!schedules.length) {
|
|
2393
|
+
console.log("No schedules found.");
|
|
2394
|
+
return;
|
|
2395
|
+
}
|
|
2396
|
+
outputTable(
|
|
2397
|
+
["ID", "Name", "Cron", "URL", "Method", "Active", "Next Run"],
|
|
2398
|
+
schedules.map((s) => [
|
|
2399
|
+
String(s.id ?? "-"),
|
|
2400
|
+
String(s.name ?? "-"),
|
|
2401
|
+
String(s.cronSchedule ?? "-"),
|
|
2402
|
+
String(s.functionUrl ?? "-"),
|
|
2403
|
+
String(s.httpMethod ?? "-"),
|
|
2404
|
+
s.isActive === false ? "No" : "Yes",
|
|
2405
|
+
s.nextRun ? new Date(String(s.nextRun)).toLocaleString() : "-"
|
|
2406
|
+
])
|
|
2407
|
+
);
|
|
2408
|
+
}
|
|
2409
|
+
} catch (err) {
|
|
2410
|
+
handleError(err, json);
|
|
2411
|
+
}
|
|
2412
|
+
});
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
// src/commands/schedules/get.ts
|
|
2416
|
+
function registerSchedulesGetCommand(schedulesCmd2) {
|
|
2417
|
+
schedulesCmd2.command("get <id>").description("Get schedule details").action(async (id, _opts, cmd) => {
|
|
2418
|
+
const { json } = getRootOpts(cmd);
|
|
2419
|
+
try {
|
|
2420
|
+
await requireAuth();
|
|
2421
|
+
const res = await ossFetch(`/api/schedules/${encodeURIComponent(id)}`);
|
|
2422
|
+
const data = await res.json();
|
|
2423
|
+
if (json) {
|
|
2424
|
+
outputJson(data);
|
|
2425
|
+
} else {
|
|
2426
|
+
console.log(`
|
|
2427
|
+
Name: ${data.name ?? "-"}`);
|
|
2428
|
+
console.log(` ID: ${data.id ?? "-"}`);
|
|
2429
|
+
console.log(` Cron: ${data.cronSchedule ?? "-"}`);
|
|
2430
|
+
console.log(` URL: ${data.functionUrl ?? "-"}`);
|
|
2431
|
+
console.log(` Method: ${data.httpMethod ?? "-"}`);
|
|
2432
|
+
console.log(` Active: ${data.isActive === false ? "No" : "Yes"}`);
|
|
2433
|
+
if (data.headers) console.log(` Headers: ${JSON.stringify(data.headers)}`);
|
|
2434
|
+
if (data.body) console.log(` Body: ${JSON.stringify(data.body)}`);
|
|
2435
|
+
console.log(` Next Run: ${data.nextRun ? new Date(String(data.nextRun)).toLocaleString() : "-"}`);
|
|
2436
|
+
console.log(` Created: ${data.createdAt ? new Date(String(data.createdAt)).toLocaleString() : "-"}`);
|
|
2437
|
+
console.log("");
|
|
2438
|
+
}
|
|
2439
|
+
} catch (err) {
|
|
2440
|
+
handleError(err, json);
|
|
2441
|
+
}
|
|
2442
|
+
});
|
|
2443
|
+
}
|
|
2444
|
+
|
|
2445
|
+
// src/commands/schedules/create.ts
|
|
2446
|
+
function registerSchedulesCreateCommand(schedulesCmd2) {
|
|
2447
|
+
schedulesCmd2.command("create").description("Create a new schedule").requiredOption("--name <name>", "Schedule name").requiredOption("--cron <expression>", "Cron expression (5-field format)").requiredOption("--url <url>", "URL to invoke").requiredOption("--method <method>", "HTTP method (GET, POST, PUT, PATCH, DELETE)").option("--headers <json>", "HTTP headers as JSON").option("--body <json>", "Request body as JSON").action(async (opts, cmd) => {
|
|
2448
|
+
const { json } = getRootOpts(cmd);
|
|
2449
|
+
try {
|
|
2450
|
+
await requireAuth();
|
|
2451
|
+
const body = {
|
|
2452
|
+
name: opts.name,
|
|
2453
|
+
cronSchedule: opts.cron,
|
|
2454
|
+
functionUrl: opts.url,
|
|
2455
|
+
httpMethod: opts.method.toUpperCase()
|
|
2456
|
+
};
|
|
2457
|
+
if (opts.headers) {
|
|
2458
|
+
try {
|
|
2459
|
+
body.headers = JSON.parse(opts.headers);
|
|
2460
|
+
} catch {
|
|
2461
|
+
throw new CLIError("Invalid JSON for --headers");
|
|
2462
|
+
}
|
|
2463
|
+
}
|
|
2464
|
+
if (opts.body) {
|
|
2465
|
+
try {
|
|
2466
|
+
body.body = JSON.parse(opts.body);
|
|
2467
|
+
} catch {
|
|
2468
|
+
throw new CLIError("Invalid JSON for --body");
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2471
|
+
const res = await ossFetch("/api/schedules", {
|
|
2472
|
+
method: "POST",
|
|
2473
|
+
body: JSON.stringify(body)
|
|
2474
|
+
});
|
|
2475
|
+
const data = await res.json();
|
|
2476
|
+
if (json) {
|
|
2477
|
+
outputJson(data);
|
|
2478
|
+
} else {
|
|
2479
|
+
outputSuccess(`Schedule "${opts.name}" created (ID: ${data.id ?? "unknown"}).`);
|
|
2480
|
+
}
|
|
2481
|
+
} catch (err) {
|
|
2482
|
+
handleError(err, json);
|
|
2483
|
+
}
|
|
2484
|
+
});
|
|
2485
|
+
}
|
|
2486
|
+
|
|
2487
|
+
// src/commands/schedules/update.ts
|
|
2488
|
+
function registerSchedulesUpdateCommand(schedulesCmd2) {
|
|
2489
|
+
schedulesCmd2.command("update <id>").description("Update a schedule").option("--name <name>", "New schedule name").option("--cron <expression>", "New cron expression").option("--url <url>", "New URL to invoke").option("--method <method>", "New HTTP method").option("--headers <json>", "New HTTP headers as JSON").option("--body <json>", "New request body as JSON").option("--active <bool>", "Enable/disable schedule (true/false)").action(async (id, opts, cmd) => {
|
|
2490
|
+
const { json } = getRootOpts(cmd);
|
|
2491
|
+
try {
|
|
2492
|
+
await requireAuth();
|
|
2493
|
+
const body = {};
|
|
2494
|
+
if (opts.name !== void 0) body.name = opts.name;
|
|
2495
|
+
if (opts.cron !== void 0) body.cronSchedule = opts.cron;
|
|
2496
|
+
if (opts.url !== void 0) body.functionUrl = opts.url;
|
|
2497
|
+
if (opts.method !== void 0) body.httpMethod = opts.method.toUpperCase();
|
|
2498
|
+
if (opts.active !== void 0) body.isActive = opts.active === "true";
|
|
2499
|
+
if (opts.headers !== void 0) {
|
|
2500
|
+
try {
|
|
2501
|
+
body.headers = JSON.parse(opts.headers);
|
|
2502
|
+
} catch {
|
|
2503
|
+
throw new CLIError("Invalid JSON for --headers");
|
|
2504
|
+
}
|
|
2505
|
+
}
|
|
2506
|
+
if (opts.body !== void 0) {
|
|
2507
|
+
try {
|
|
2508
|
+
body.body = JSON.parse(opts.body);
|
|
2509
|
+
} catch {
|
|
2510
|
+
throw new CLIError("Invalid JSON for --body");
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
if (Object.keys(body).length === 0) {
|
|
2514
|
+
throw new CLIError("Provide at least one option to update (--name, --cron, --url, --method, --headers, --body, --active).");
|
|
2515
|
+
}
|
|
2516
|
+
const res = await ossFetch(`/api/schedules/${encodeURIComponent(id)}`, {
|
|
2517
|
+
method: "PATCH",
|
|
2518
|
+
body: JSON.stringify(body)
|
|
2519
|
+
});
|
|
2520
|
+
const data = await res.json();
|
|
2521
|
+
if (json) {
|
|
2522
|
+
outputJson(data);
|
|
2523
|
+
} else {
|
|
2524
|
+
outputSuccess(data.message ?? "Schedule updated.");
|
|
2525
|
+
}
|
|
2526
|
+
} catch (err) {
|
|
2527
|
+
handleError(err, json);
|
|
2528
|
+
}
|
|
2529
|
+
});
|
|
2530
|
+
}
|
|
2531
|
+
|
|
2532
|
+
// src/commands/schedules/delete.ts
|
|
2533
|
+
import * as clack12 from "@clack/prompts";
|
|
2534
|
+
function registerSchedulesDeleteCommand(schedulesCmd2) {
|
|
2535
|
+
schedulesCmd2.command("delete <id>").description("Delete a schedule").action(async (id, _opts, cmd) => {
|
|
2536
|
+
const { json, yes } = getRootOpts(cmd);
|
|
2537
|
+
try {
|
|
2538
|
+
await requireAuth();
|
|
2539
|
+
if (!yes && !json) {
|
|
2540
|
+
const confirm5 = await clack12.confirm({
|
|
2541
|
+
message: `Delete schedule "${id}"? This cannot be undone.`
|
|
2542
|
+
});
|
|
2543
|
+
if (!confirm5 || clack12.isCancel(confirm5)) {
|
|
2544
|
+
process.exit(0);
|
|
2545
|
+
}
|
|
2546
|
+
}
|
|
2547
|
+
const res = await ossFetch(`/api/schedules/${encodeURIComponent(id)}`, {
|
|
2548
|
+
method: "DELETE"
|
|
2549
|
+
});
|
|
2550
|
+
const data = await res.json();
|
|
2551
|
+
if (json) {
|
|
2552
|
+
outputJson(data);
|
|
2553
|
+
} else {
|
|
2554
|
+
outputSuccess(data.message ?? "Schedule deleted.");
|
|
2555
|
+
}
|
|
2556
|
+
} catch (err) {
|
|
2557
|
+
handleError(err, json);
|
|
2558
|
+
}
|
|
2559
|
+
});
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2562
|
+
// src/commands/schedules/logs.ts
|
|
2563
|
+
function registerSchedulesLogsCommand(schedulesCmd2) {
|
|
2564
|
+
schedulesCmd2.command("logs <id>").description("Get execution logs for a schedule").option("--limit <n>", "Max logs to return (default: 50, max: 100)", "50").option("--offset <n>", "Pagination offset", "0").action(async (id, opts, cmd) => {
|
|
2565
|
+
const { json } = getRootOpts(cmd);
|
|
2566
|
+
try {
|
|
2567
|
+
await requireAuth();
|
|
2568
|
+
const limit = parseInt(opts.limit, 10) || 50;
|
|
2569
|
+
const offset = parseInt(opts.offset, 10) || 0;
|
|
2570
|
+
const res = await ossFetch(`/api/schedules/${encodeURIComponent(id)}/logs?limit=${limit}&offset=${offset}`);
|
|
2571
|
+
const data = await res.json();
|
|
2572
|
+
const logs = data.logs ?? [];
|
|
2573
|
+
if (json) {
|
|
2574
|
+
outputJson(data);
|
|
2575
|
+
} else {
|
|
2576
|
+
if (!logs.length) {
|
|
2577
|
+
console.log("No execution logs found.");
|
|
2578
|
+
return;
|
|
2579
|
+
}
|
|
2580
|
+
outputTable(
|
|
2581
|
+
["Executed At", "Status", "Success", "Duration (ms)"],
|
|
2582
|
+
logs.map((l) => [
|
|
2583
|
+
l.executedAt ? new Date(String(l.executedAt)).toLocaleString() : "-",
|
|
2584
|
+
String(l.statusCode ?? "-"),
|
|
2585
|
+
l.success ? "Yes" : "No",
|
|
2586
|
+
String(l.durationMs ?? "-")
|
|
2587
|
+
])
|
|
2588
|
+
);
|
|
2589
|
+
if (data.totalCount > offset + logs.length) {
|
|
2590
|
+
console.log(`
|
|
2591
|
+
Showing ${offset + 1}-${offset + logs.length} of ${data.totalCount}. Use --offset to paginate.`);
|
|
2592
|
+
}
|
|
2593
|
+
}
|
|
2594
|
+
} catch (err) {
|
|
2595
|
+
handleError(err, json);
|
|
2596
|
+
}
|
|
2597
|
+
});
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
// src/commands/logs.ts
|
|
2601
|
+
var VALID_SOURCES = ["insforge.logs", "postgREST.logs", "postgres.logs", "function.logs"];
|
|
2602
|
+
var SOURCE_LOOKUP = new Map(VALID_SOURCES.map((s) => [s.toLowerCase(), s]));
|
|
2603
|
+
function registerLogsCommand(program2) {
|
|
2604
|
+
program2.command("logs <source>").description("Fetch backend container logs (insforge.logs | postgREST.logs | postgres.logs | function.logs)").option("--limit <n>", "Number of log entries to return", "20").action(async (source, opts, cmd) => {
|
|
2605
|
+
const { json } = getRootOpts(cmd);
|
|
2606
|
+
try {
|
|
2607
|
+
await requireAuth();
|
|
2608
|
+
const resolved = SOURCE_LOOKUP.get(source.toLowerCase());
|
|
2609
|
+
if (!resolved) {
|
|
2610
|
+
console.error(`Invalid log source "${source}". Valid sources: ${VALID_SOURCES.join(", ")}`);
|
|
2611
|
+
process.exit(1);
|
|
2612
|
+
}
|
|
2613
|
+
const limit = parseInt(opts.limit, 10) || 20;
|
|
2614
|
+
const res = await ossFetch(`/api/logs/${encodeURIComponent(resolved)}?limit=${limit}`);
|
|
2615
|
+
const data = await res.json();
|
|
2616
|
+
if (json) {
|
|
2617
|
+
outputJson(data);
|
|
2618
|
+
} else {
|
|
2619
|
+
const logs = Array.isArray(data) ? data : data.logs;
|
|
2620
|
+
if (!Array.isArray(logs) || !logs.length) {
|
|
2621
|
+
console.log("No logs found.");
|
|
2622
|
+
return;
|
|
2623
|
+
}
|
|
2624
|
+
for (const entry of logs) {
|
|
2625
|
+
if (typeof entry === "string") {
|
|
2626
|
+
console.log(entry);
|
|
2627
|
+
} else {
|
|
2628
|
+
const e = entry;
|
|
2629
|
+
const ts = e.timestamp ?? e.time ?? "";
|
|
2630
|
+
const msg = e.message ?? e.msg ?? e.log ?? JSON.stringify(e);
|
|
2631
|
+
console.log(`${ts} ${msg}`);
|
|
2632
|
+
}
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
} catch (err) {
|
|
2636
|
+
handleError(err, json);
|
|
2637
|
+
}
|
|
2638
|
+
});
|
|
2639
|
+
}
|
|
2640
|
+
|
|
2406
2641
|
// src/index.ts
|
|
2407
2642
|
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
2408
2643
|
var pkg = JSON.parse(readFileSync5(join5(__dirname, "../package.json"), "utf-8"));
|
|
@@ -2476,5 +2711,13 @@ registerSecretsGetCommand(secretsCmd);
|
|
|
2476
2711
|
registerSecretsAddCommand(secretsCmd);
|
|
2477
2712
|
registerSecretsUpdateCommand(secretsCmd);
|
|
2478
2713
|
registerSecretsDeleteCommand(secretsCmd);
|
|
2714
|
+
registerLogsCommand(program);
|
|
2715
|
+
var schedulesCmd = program.command("schedules").description("Manage scheduled tasks (cron jobs)");
|
|
2716
|
+
registerSchedulesListCommand(schedulesCmd);
|
|
2717
|
+
registerSchedulesGetCommand(schedulesCmd);
|
|
2718
|
+
registerSchedulesCreateCommand(schedulesCmd);
|
|
2719
|
+
registerSchedulesUpdateCommand(schedulesCmd);
|
|
2720
|
+
registerSchedulesDeleteCommand(schedulesCmd);
|
|
2721
|
+
registerSchedulesLogsCommand(schedulesCmd);
|
|
2479
2722
|
program.parse();
|
|
2480
2723
|
//# sourceMappingURL=index.js.map
|