@4ort/cli 0.2.0 → 0.4.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.
@@ -0,0 +1,5 @@
1
+ export declare function provisionService(service: string): Promise<void>;
2
+ export declare function provisionAll(): Promise<void>;
3
+ export declare function provisionStatus(service?: string): Promise<void>;
4
+ export declare function provisionCredentials(service?: string): Promise<void>;
5
+ export declare function listServices(): Promise<void>;
@@ -0,0 +1,106 @@
1
+ import { apiRequest } from "../api-client.js";
2
+ import { requireConfig } from "../config.js";
3
+ export async function provisionService(service) {
4
+ const config = requireConfig();
5
+ try {
6
+ const data = await apiRequest(config, "POST", `/api/provision/${service}`);
7
+ console.log(data.message);
8
+ console.log(`\nCheck status: 4ort provision status ${service}`);
9
+ }
10
+ catch (err) {
11
+ console.error(`Failed: ${err.message}`);
12
+ process.exit(1);
13
+ }
14
+ }
15
+ export async function provisionAll() {
16
+ const config = requireConfig();
17
+ try {
18
+ const data = await apiRequest(config, "POST", "/api/provision/all");
19
+ console.log(data.message);
20
+ console.log("");
21
+ for (const job of data.jobs) {
22
+ console.log(` ${job.slug}: ${job.status}`);
23
+ }
24
+ console.log(`\nCheck status: 4ort provision status`);
25
+ }
26
+ catch (err) {
27
+ console.error(`Failed: ${err.message}`);
28
+ process.exit(1);
29
+ }
30
+ }
31
+ export async function provisionStatus(service) {
32
+ const config = requireConfig();
33
+ try {
34
+ if (service) {
35
+ const data = await apiRequest(config, "GET", `/api/provision/status/${service}`);
36
+ console.log(`${data.service_name} (${data.service_slug})`);
37
+ console.log(` Status: ${data.status}`);
38
+ if (data.error)
39
+ console.log(` Error: ${data.error}`);
40
+ if (data.started_at)
41
+ console.log(` Started: ${data.started_at}`);
42
+ if (data.completed_at)
43
+ console.log(` Completed: ${data.completed_at}`);
44
+ }
45
+ else {
46
+ const data = await apiRequest(config, "GET", "/api/provision/status");
47
+ if (data.jobs.length === 0) {
48
+ console.log("No provisioning jobs. Run: 4ort provision <service>");
49
+ return;
50
+ }
51
+ console.log("Provisioning jobs:\n");
52
+ for (const job of data.jobs) {
53
+ const icon = job.status === "completed" ? "+" : job.status === "failed" ? "x" : job.status === "running" ? "~" : ".";
54
+ console.log(` [${icon}] ${job.service_name} (${job.service_slug}) — ${job.status}`);
55
+ if (job.error)
56
+ console.log(` Error: ${job.error}`);
57
+ }
58
+ }
59
+ }
60
+ catch (err) {
61
+ console.error(`Failed: ${err.message}`);
62
+ process.exit(1);
63
+ }
64
+ }
65
+ export async function provisionCredentials(service) {
66
+ const config = requireConfig();
67
+ try {
68
+ const path = service ? `/api/provision/credentials/${service}` : "/api/provision/credentials";
69
+ const data = await apiRequest(config, "GET", path);
70
+ if (data.credentials.length === 0) {
71
+ console.log("No credentials yet. Run: 4ort provision <service>");
72
+ return;
73
+ }
74
+ console.log("Credentials:\n");
75
+ for (const cred of data.credentials) {
76
+ console.log(` ${cred.service} (${cred.type})`);
77
+ console.log(` ${cred.value}`);
78
+ if (cred.metadata)
79
+ console.log(` Metadata: ${JSON.stringify(cred.metadata)}`);
80
+ if (cred.expiresAt)
81
+ console.log(` Expires: ${cred.expiresAt}`);
82
+ console.log("");
83
+ }
84
+ }
85
+ catch (err) {
86
+ console.error(`Failed: ${err.message}`);
87
+ process.exit(1);
88
+ }
89
+ }
90
+ export async function listServices() {
91
+ const config = requireConfig();
92
+ try {
93
+ const data = await apiRequest(config, "GET", "/api/provision/services");
94
+ console.log("Available services:\n");
95
+ for (const s of data.services) {
96
+ const status = s.enabled ? "" : " (disabled)";
97
+ const captcha = s.requires_captcha ? " [captcha]" : "";
98
+ console.log(` [${s.tier.toUpperCase()}] ${s.name} (${s.slug}) — ${s.category}${captcha}${status}`);
99
+ }
100
+ }
101
+ catch (err) {
102
+ console.error(`Failed: ${err.message}`);
103
+ process.exit(1);
104
+ }
105
+ }
106
+ //# sourceMappingURL=provision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provision.js","sourceRoot":"","sources":["../../src/commands/provision.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAe;IACpD,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAE/B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,kBAAkB,OAAO,EAAE,CAAC,CAAC;QAC3E,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,yCAAyC,OAAO,EAAE,CAAC,CAAC;IAClE,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAE/B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAgB;IACpD,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAE/B,IAAI,CAAC;QACH,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,yBAAyB,OAAO,EAAE,CAAC,CAAC;YACjF,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACxC,IAAI,IAAI,CAAC,KAAK;gBAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACtD,IAAI,IAAI,CAAC,UAAU;gBAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YAClE,IAAI,IAAI,CAAC,YAAY;gBAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC;QAC1E,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,uBAAuB,CAAC,CAAC;YACtE,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3B,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;gBACnE,OAAO;YACT,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;YACpC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC5B,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;gBACrH,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,KAAK,GAAG,CAAC,YAAY,KAAK,GAAG,CAAC,YAAY,OAAO,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;gBACrF,IAAI,GAAG,CAAC,KAAK;oBAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAAgB;IACzD,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAE/B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,8BAA8B,OAAO,EAAE,CAAC,CAAC,CAAC,4BAA4B,CAAC;QAC9F,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAEnD,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;YACjE,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC9B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACjC,IAAI,IAAI,CAAC,QAAQ;gBAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACjF,IAAI,IAAI,CAAC,SAAS;gBAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;YAClE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAE/B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,yBAAyB,CAAC,CAAC;QAExE,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACrC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;YAC9C,MAAM,OAAO,GAAG,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,QAAQ,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC,CAAC;QACtG,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ import { list } from "./commands/list.js";
6
6
  import { deleteSite } from "./commands/delete.js";
7
7
  import { whoami } from "./commands/whoami.js";
8
8
  import { checkMail, readMail, sendMail, deleteMail } from "./commands/mail.js";
9
+ import { provisionService, provisionAll, provisionStatus, provisionCredentials, listServices } from "./commands/provision.js";
9
10
  import { loadConfig, getConfigPath } from "./config.js";
10
11
  const program = new Command();
11
12
  program
@@ -54,6 +55,27 @@ mail
54
55
  .command("delete <id>")
55
56
  .description("Delete a message")
56
57
  .action(deleteMail);
58
+ const provision = program.command("provision").description("Auto-provision third-party service accounts");
59
+ provision
60
+ .command("run <service>")
61
+ .description("Provision a specific service")
62
+ .action(provisionService);
63
+ provision
64
+ .command("all")
65
+ .description("Provision all available Tier A services")
66
+ .action(provisionAll);
67
+ provision
68
+ .command("status [service]")
69
+ .description("Check provisioning status")
70
+ .action((service) => provisionStatus(service));
71
+ provision
72
+ .command("credentials [service]")
73
+ .description("Show stored credentials")
74
+ .action((service) => provisionCredentials(service));
75
+ provision
76
+ .command("services")
77
+ .description("List available services")
78
+ .action(listServices);
57
79
  program
58
80
  .command("config")
59
81
  .description("Show config location and current settings")
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@4ort/cli",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "4ort": "./dist/index.js"
@@ -0,0 +1,106 @@
1
+ import { apiRequest } from "../api-client.js";
2
+ import { requireConfig } from "../config.js";
3
+
4
+ export async function provisionService(service: string) {
5
+ const config = requireConfig();
6
+
7
+ try {
8
+ const data = await apiRequest(config, "POST", `/api/provision/${service}`);
9
+ console.log(data.message);
10
+ console.log(`\nCheck status: 4ort provision status ${service}`);
11
+ } catch (err: any) {
12
+ console.error(`Failed: ${err.message}`);
13
+ process.exit(1);
14
+ }
15
+ }
16
+
17
+ export async function provisionAll() {
18
+ const config = requireConfig();
19
+
20
+ try {
21
+ const data = await apiRequest(config, "POST", "/api/provision/all");
22
+ console.log(data.message);
23
+ console.log("");
24
+ for (const job of data.jobs) {
25
+ console.log(` ${job.slug}: ${job.status}`);
26
+ }
27
+ console.log(`\nCheck status: 4ort provision status`);
28
+ } catch (err: any) {
29
+ console.error(`Failed: ${err.message}`);
30
+ process.exit(1);
31
+ }
32
+ }
33
+
34
+ export async function provisionStatus(service?: string) {
35
+ const config = requireConfig();
36
+
37
+ try {
38
+ if (service) {
39
+ const data = await apiRequest(config, "GET", `/api/provision/status/${service}`);
40
+ console.log(`${data.service_name} (${data.service_slug})`);
41
+ console.log(` Status: ${data.status}`);
42
+ if (data.error) console.log(` Error: ${data.error}`);
43
+ if (data.started_at) console.log(` Started: ${data.started_at}`);
44
+ if (data.completed_at) console.log(` Completed: ${data.completed_at}`);
45
+ } else {
46
+ const data = await apiRequest(config, "GET", "/api/provision/status");
47
+ if (data.jobs.length === 0) {
48
+ console.log("No provisioning jobs. Run: 4ort provision <service>");
49
+ return;
50
+ }
51
+ console.log("Provisioning jobs:\n");
52
+ for (const job of data.jobs) {
53
+ const icon = job.status === "completed" ? "+" : job.status === "failed" ? "x" : job.status === "running" ? "~" : ".";
54
+ console.log(` [${icon}] ${job.service_name} (${job.service_slug}) — ${job.status}`);
55
+ if (job.error) console.log(` Error: ${job.error}`);
56
+ }
57
+ }
58
+ } catch (err: any) {
59
+ console.error(`Failed: ${err.message}`);
60
+ process.exit(1);
61
+ }
62
+ }
63
+
64
+ export async function provisionCredentials(service?: string) {
65
+ const config = requireConfig();
66
+
67
+ try {
68
+ const path = service ? `/api/provision/credentials/${service}` : "/api/provision/credentials";
69
+ const data = await apiRequest(config, "GET", path);
70
+
71
+ if (data.credentials.length === 0) {
72
+ console.log("No credentials yet. Run: 4ort provision <service>");
73
+ return;
74
+ }
75
+
76
+ console.log("Credentials:\n");
77
+ for (const cred of data.credentials) {
78
+ console.log(` ${cred.service} (${cred.type})`);
79
+ console.log(` ${cred.value}`);
80
+ if (cred.metadata) console.log(` Metadata: ${JSON.stringify(cred.metadata)}`);
81
+ if (cred.expiresAt) console.log(` Expires: ${cred.expiresAt}`);
82
+ console.log("");
83
+ }
84
+ } catch (err: any) {
85
+ console.error(`Failed: ${err.message}`);
86
+ process.exit(1);
87
+ }
88
+ }
89
+
90
+ export async function listServices() {
91
+ const config = requireConfig();
92
+
93
+ try {
94
+ const data = await apiRequest(config, "GET", "/api/provision/services");
95
+
96
+ console.log("Available services:\n");
97
+ for (const s of data.services) {
98
+ const status = s.enabled ? "" : " (disabled)";
99
+ const captcha = s.requires_captcha ? " [captcha]" : "";
100
+ console.log(` [${s.tier.toUpperCase()}] ${s.name} (${s.slug}) — ${s.category}${captcha}${status}`);
101
+ }
102
+ } catch (err: any) {
103
+ console.error(`Failed: ${err.message}`);
104
+ process.exit(1);
105
+ }
106
+ }
package/src/index.ts CHANGED
@@ -7,6 +7,7 @@ import { deleteSite } from "./commands/delete.js";
7
7
  import { whoami } from "./commands/whoami.js";
8
8
  import { recover } from "./commands/recover.js";
9
9
  import { checkMail, readMail, sendMail, deleteMail } from "./commands/mail.js";
10
+ import { provisionService, provisionAll, provisionStatus, provisionCredentials, listServices } from "./commands/provision.js";
10
11
  import { loadConfig, getConfigPath } from "./config.js";
11
12
 
12
13
  const program = new Command();
@@ -68,6 +69,33 @@ mail
68
69
  .description("Delete a message")
69
70
  .action(deleteMail);
70
71
 
72
+ const provision = program.command("provision").description("Auto-provision third-party service accounts");
73
+
74
+ provision
75
+ .command("run <service>")
76
+ .description("Provision a specific service")
77
+ .action(provisionService);
78
+
79
+ provision
80
+ .command("all")
81
+ .description("Provision all available Tier A services")
82
+ .action(provisionAll);
83
+
84
+ provision
85
+ .command("status [service]")
86
+ .description("Check provisioning status")
87
+ .action((service?: string) => provisionStatus(service));
88
+
89
+ provision
90
+ .command("credentials [service]")
91
+ .description("Show stored credentials")
92
+ .action((service?: string) => provisionCredentials(service));
93
+
94
+ provision
95
+ .command("services")
96
+ .description("List available services")
97
+ .action(listServices);
98
+
71
99
  program
72
100
  .command("config")
73
101
  .description("Show config location and current settings")