@forjio/storlaunch-cli 0.1.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.
Files changed (39) hide show
  1. package/LICENSE +21 -0
  2. package/bin/storlaunch.js +2 -0
  3. package/dist/commands/auth.d.ts +4 -0
  4. package/dist/commands/auth.d.ts.map +1 -0
  5. package/dist/commands/auth.js +78 -0
  6. package/dist/commands/auth.js.map +1 -0
  7. package/dist/commands/config.d.ts +4 -0
  8. package/dist/commands/config.d.ts.map +1 -0
  9. package/dist/commands/config.js +86 -0
  10. package/dist/commands/config.js.map +1 -0
  11. package/dist/commands/payment.d.ts +4 -0
  12. package/dist/commands/payment.d.ts.map +1 -0
  13. package/dist/commands/payment.js +738 -0
  14. package/dist/commands/payment.js.map +1 -0
  15. package/dist/commands/storefront.d.ts +4 -0
  16. package/dist/commands/storefront.d.ts.map +1 -0
  17. package/dist/commands/storefront.js +433 -0
  18. package/dist/commands/storefront.js.map +1 -0
  19. package/dist/commands/webhook.d.ts +4 -0
  20. package/dist/commands/webhook.d.ts.map +1 -0
  21. package/dist/commands/webhook.js +249 -0
  22. package/dist/commands/webhook.js.map +1 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +25 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/lib/api.d.ts +18 -0
  28. package/dist/lib/api.d.ts.map +1 -0
  29. package/dist/lib/api.js +62 -0
  30. package/dist/lib/api.js.map +1 -0
  31. package/dist/lib/config.d.ts +23 -0
  32. package/dist/lib/config.d.ts.map +1 -0
  33. package/dist/lib/config.js +58 -0
  34. package/dist/lib/config.js.map +1 -0
  35. package/dist/lib/output.d.ts +21 -0
  36. package/dist/lib/output.d.ts.map +1 -0
  37. package/dist/lib/output.js +66 -0
  38. package/dist/lib/output.js.map +1 -0
  39. package/package.json +34 -0
@@ -0,0 +1,249 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import { apiRequest, ApiClientError } from "../lib/api.js";
4
+ import { output } from "../lib/output.js";
5
+ function getExitCode(err) {
6
+ if (err instanceof ApiClientError) {
7
+ if (err.status === 401 || err.status === 403)
8
+ return 2;
9
+ if (err.status === 429)
10
+ return 3;
11
+ if (err.code === "QUOTA_EXCEEDED")
12
+ return 4;
13
+ }
14
+ return 1;
15
+ }
16
+ function handleError(err, json) {
17
+ if (json && err instanceof ApiClientError) {
18
+ console.error(JSON.stringify({ data: null, error: { code: err.code, message: err.message } }, null, 2));
19
+ }
20
+ else {
21
+ console.error(chalk.red(`Error: ${err instanceof Error ? err.message : String(err)}`));
22
+ }
23
+ process.exit(getExitCode(err));
24
+ }
25
+ // ─── Endpoints ───────────────────────────────────────────────
26
+ const endpoints = new Command("endpoints").description("Manage webhook endpoints");
27
+ endpoints
28
+ .command("create")
29
+ .description("Create a webhook endpoint")
30
+ .requiredOption("--url <url>", "HTTPS URL to receive events")
31
+ .requiredOption("--events <events>", 'Comma-separated event types, or "*" for all')
32
+ .option("--description <text>", "Human-readable label")
33
+ .action(async (opts, cmd) => {
34
+ const g = cmd.optsWithGlobals();
35
+ try {
36
+ const events = opts.events === "*" ? ["*"] : opts.events.split(",").map((s) => s.trim());
37
+ const body = {
38
+ url: opts.url,
39
+ events,
40
+ };
41
+ if (opts.description)
42
+ body["description"] = opts.description;
43
+ const result = await apiRequest("/payment/webhook-endpoints", {
44
+ method: "POST",
45
+ body,
46
+ sandbox: g.sandbox,
47
+ });
48
+ if (g.json) {
49
+ output(result, { json: true });
50
+ }
51
+ else {
52
+ console.log(`Webhook endpoint created: ${chalk.bold(String(result["id"]))}`);
53
+ console.log(`URL: ${result["url"]}`);
54
+ console.log(`Events: ${Array.isArray(result["events"]) ? result["events"].join(", ") : result["events"]}`);
55
+ if (result["secret"]) {
56
+ console.log(`Secret: ${chalk.yellow(String(result["secret"]))} ${chalk.dim("<- Save this! Not shown again.")}`);
57
+ }
58
+ }
59
+ }
60
+ catch (err) {
61
+ handleError(err, g.json);
62
+ }
63
+ });
64
+ endpoints
65
+ .command("list")
66
+ .description("List webhook endpoints")
67
+ .action(async (_, cmd) => {
68
+ const g = cmd.optsWithGlobals();
69
+ try {
70
+ const result = await apiRequest("/payment/webhook-endpoints", {
71
+ sandbox: g.sandbox,
72
+ });
73
+ if (g.json) {
74
+ output(result, { json: true });
75
+ }
76
+ else {
77
+ const cols = [
78
+ { key: "id", header: "ID", width: 20 },
79
+ { key: "url", header: "URL", width: 40 },
80
+ { key: "active", header: "Active" },
81
+ { key: "createdAt", header: "Created" },
82
+ ];
83
+ output((result["data"] ?? result), { columns: cols });
84
+ }
85
+ }
86
+ catch (err) {
87
+ handleError(err, g.json);
88
+ }
89
+ });
90
+ endpoints
91
+ .command("get <id>")
92
+ .description("Get a webhook endpoint")
93
+ .action(async (id, _, cmd) => {
94
+ const g = cmd.optsWithGlobals();
95
+ try {
96
+ const result = await apiRequest(`/payment/webhook-endpoints/${id}`, {
97
+ sandbox: g.sandbox,
98
+ });
99
+ output(result, { json: g.json });
100
+ }
101
+ catch (err) {
102
+ handleError(err, g.json);
103
+ }
104
+ });
105
+ endpoints
106
+ .command("update <id>")
107
+ .description("Update a webhook endpoint")
108
+ .option("--url <url>", "New URL")
109
+ .option("--events <events>", "New event types (comma-separated)")
110
+ .option("--active", "Enable the endpoint")
111
+ .option("--no-active", "Disable the endpoint")
112
+ .action(async (id, opts, cmd) => {
113
+ const g = cmd.optsWithGlobals();
114
+ try {
115
+ const body = {};
116
+ if (opts.url)
117
+ body["url"] = opts.url;
118
+ if (opts.events) {
119
+ body["events"] = opts.events === "*" ? ["*"] : opts.events.split(",").map((s) => s.trim());
120
+ }
121
+ if (opts.active !== undefined)
122
+ body["active"] = opts.active;
123
+ const result = await apiRequest(`/payment/webhook-endpoints/${id}`, {
124
+ method: "PATCH",
125
+ body,
126
+ sandbox: g.sandbox,
127
+ });
128
+ if (g.json) {
129
+ output(result, { json: true });
130
+ }
131
+ else {
132
+ console.log(chalk.green(`Webhook endpoint ${id} updated.`));
133
+ }
134
+ }
135
+ catch (err) {
136
+ handleError(err, g.json);
137
+ }
138
+ });
139
+ endpoints
140
+ .command("delete <id>")
141
+ .description("Delete a webhook endpoint")
142
+ .action(async (id, _, cmd) => {
143
+ const g = cmd.optsWithGlobals();
144
+ try {
145
+ await apiRequest(`/payment/webhook-endpoints/${id}`, { method: "DELETE", sandbox: g.sandbox });
146
+ if (g.json) {
147
+ output({ deleted: true, id }, { json: true });
148
+ }
149
+ else {
150
+ console.log(chalk.green(`Webhook endpoint ${id} deleted.`));
151
+ }
152
+ }
153
+ catch (err) {
154
+ handleError(err, g.json);
155
+ }
156
+ });
157
+ // ─── Events ──────────────────────────────────────────────────
158
+ const events = new Command("events").description("Manage webhook events");
159
+ events
160
+ .command("list")
161
+ .description("List webhook events")
162
+ .option("--type <type>", "Filter by event type")
163
+ .option("--endpoint <id>", "Filter by endpoint ID")
164
+ .option("--status <status>", "Filter: pending, sent, failed")
165
+ .option("--limit <n>", "Items per page", parseInt)
166
+ .option("--cursor <cursor>", "Pagination cursor")
167
+ .action(async (opts, cmd) => {
168
+ const g = cmd.optsWithGlobals();
169
+ try {
170
+ const result = await apiRequest("/payment/webhook-events", {
171
+ query: { type: opts.type, endpoint: opts.endpoint, status: opts.status, limit: opts.limit, cursor: opts.cursor },
172
+ sandbox: g.sandbox,
173
+ });
174
+ if (g.json) {
175
+ output(result, { json: true });
176
+ }
177
+ else {
178
+ const cols = [
179
+ { key: "id", header: "ID", width: 20 },
180
+ { key: "type", header: "Type", width: 30 },
181
+ { key: "status", header: "Status" },
182
+ { key: "createdAt", header: "Created" },
183
+ ];
184
+ output((result["data"] ?? result), { columns: cols });
185
+ }
186
+ }
187
+ catch (err) {
188
+ handleError(err, g.json);
189
+ }
190
+ });
191
+ events
192
+ .command("get <id>")
193
+ .description("Get a webhook event")
194
+ .action(async (id, _, cmd) => {
195
+ const g = cmd.optsWithGlobals();
196
+ try {
197
+ const result = await apiRequest(`/payment/webhook-events/${id}`, {
198
+ sandbox: g.sandbox,
199
+ });
200
+ output(result, { json: g.json });
201
+ }
202
+ catch (err) {
203
+ handleError(err, g.json);
204
+ }
205
+ });
206
+ events
207
+ .command("resend <id>")
208
+ .description("Resend a webhook event")
209
+ .action(async (id, _, cmd) => {
210
+ const g = cmd.optsWithGlobals();
211
+ try {
212
+ const result = await apiRequest(`/payment/webhook-events/${id}/resend`, {
213
+ method: "POST",
214
+ sandbox: g.sandbox,
215
+ });
216
+ if (g.json) {
217
+ output(result, { json: true });
218
+ }
219
+ else {
220
+ console.log(chalk.green(`Webhook event ${id} resent.`));
221
+ }
222
+ }
223
+ catch (err) {
224
+ handleError(err, g.json);
225
+ }
226
+ });
227
+ // ─── Listen ──────────────────────────────────────────────────
228
+ const listenCommand = new Command("listen")
229
+ .description("Start a local webhook listener for development")
230
+ .option("--port <port>", "Local port to forward events to", parseInt, 3000)
231
+ .option("--path <path>", "Local path to forward to", "/")
232
+ .action(async (opts, cmd) => {
233
+ const g = cmd.optsWithGlobals();
234
+ console.log(`Listening for webhook events on localhost:${opts.port}${opts.path}`);
235
+ console.log(chalk.green("Ready! Events will be forwarded in real-time."));
236
+ console.log(chalk.dim("Press Ctrl+C to stop.\n"));
237
+ // The listen command would typically establish a WebSocket/tunnel connection
238
+ // For MVP, we inform the user this requires a tunnel service
239
+ console.error(chalk.yellow("Note: webhook listen requires the Storlaunch tunnel service (coming soon)."));
240
+ console.error(chalk.yellow("For now, use `webhook endpoints create` with a public URL."));
241
+ process.exit(0);
242
+ });
243
+ // ─── Top-level webhook command ───────────────────────────────
244
+ const webhook = new Command("webhook").description("Manage webhooks and event delivery");
245
+ webhook.addCommand(listenCommand);
246
+ webhook.addCommand(endpoints);
247
+ webhook.addCommand(events);
248
+ export { webhook };
249
+ //# sourceMappingURL=webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../src/commands/webhook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,25 @@
1
+ import { Command } from "commander";
2
+ import { createRequire } from "node:module";
3
+ const require = createRequire(import.meta.url);
4
+ const pkg = require("../package.json");
5
+ const program = new Command();
6
+ program
7
+ .name("storlaunch")
8
+ .version(pkg.version)
9
+ .description(pkg.description)
10
+ .option("--json", "Output in JSON format")
11
+ .option("--sandbox", "Use sandbox/test API key");
12
+ // ─── Register command groups ─────────────────────────────────
13
+ import { auth } from "./commands/auth.js";
14
+ import { payment } from "./commands/payment.js";
15
+ import { storefront } from "./commands/storefront.js";
16
+ import { webhook } from "./commands/webhook.js";
17
+ import { config } from "./commands/config.js";
18
+ program.addCommand(auth);
19
+ program.addCommand(payment);
20
+ program.addCommand(storefront);
21
+ program.addCommand(webhook);
22
+ program.addCommand(config);
23
+ // ─── Parse ───────────────────────────────────────────────────
24
+ program.parse();
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAA6C,CAAC;AAEnF,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;KACpB,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC;KAC5B,MAAM,CAAC,QAAQ,EAAE,uBAAuB,CAAC;KACzC,MAAM,CAAC,WAAW,EAAE,0BAA0B,CAAC,CAAC;AAEnD,gEAAgE;AAEhE,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AACzB,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AAC5B,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAC/B,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AAC5B,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;AAE3B,gEAAgE;AAEhE,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,18 @@
1
+ export interface ApiRequestOptions {
2
+ method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
3
+ body?: unknown;
4
+ query?: Record<string, string | number | boolean | undefined>;
5
+ sandbox?: boolean;
6
+ }
7
+ export interface ApiError {
8
+ status: number;
9
+ message: string;
10
+ code?: string;
11
+ }
12
+ export declare class ApiClientError extends Error {
13
+ readonly status: number;
14
+ readonly code?: string;
15
+ constructor(error: ApiError);
16
+ }
17
+ export declare function apiRequest<T = unknown>(path: string, options?: ApiRequestOptions): Promise<T>;
18
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACrD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;IAC9D,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,cAAe,SAAQ,KAAK;IACvC,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,IAAI,CAAC,EAAE,MAAM,CAAC;gBAElB,KAAK,EAAE,QAAQ;CAM5B;AAED,wBAAsB,UAAU,CAAC,CAAC,GAAG,OAAO,EAC1C,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,CAAC,CAAC,CA0DZ"}
@@ -0,0 +1,62 @@
1
+ import { resolveApiKey, resolveApiUrl } from "./config.js";
2
+ export class ApiClientError extends Error {
3
+ status;
4
+ code;
5
+ constructor(error) {
6
+ super(error.message);
7
+ this.name = "ApiClientError";
8
+ this.status = error.status;
9
+ this.code = error.code;
10
+ }
11
+ }
12
+ export async function apiRequest(path, options = {}) {
13
+ const { method = "GET", body, query, sandbox } = options;
14
+ const token = resolveApiKey({ sandbox });
15
+ if (!token) {
16
+ throw new ApiClientError({
17
+ status: 401,
18
+ message: "Not authenticated. Run `storlaunch auth login --key <api-key>` first.",
19
+ code: "AUTH_REQUIRED",
20
+ });
21
+ }
22
+ const baseUrl = resolveApiUrl();
23
+ const url = new URL(path, baseUrl.endsWith("/") ? baseUrl : baseUrl + "/");
24
+ if (query) {
25
+ for (const [key, value] of Object.entries(query)) {
26
+ if (value !== undefined) {
27
+ url.searchParams.set(key, String(value));
28
+ }
29
+ }
30
+ }
31
+ const headers = {
32
+ Authorization: `Bearer ${token}`,
33
+ Accept: "application/json",
34
+ };
35
+ if (body) {
36
+ headers["Content-Type"] = "application/json";
37
+ }
38
+ const response = await fetch(url.toString(), {
39
+ method,
40
+ headers,
41
+ body: body ? JSON.stringify(body) : undefined,
42
+ });
43
+ if (!response.ok) {
44
+ let errorBody = {};
45
+ try {
46
+ errorBody = (await response.json());
47
+ }
48
+ catch {
49
+ // response body not JSON
50
+ }
51
+ throw new ApiClientError({
52
+ status: response.status,
53
+ message: errorBody.message ?? `API request failed with status ${response.status}`,
54
+ code: errorBody.code,
55
+ });
56
+ }
57
+ if (response.status === 204) {
58
+ return undefined;
59
+ }
60
+ return (await response.json());
61
+ }
62
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAe3D,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvB,MAAM,CAAS;IACf,IAAI,CAAU;IAE9B,YAAY,KAAe;QACzB,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAY,EACZ,UAA6B,EAAE;IAE/B,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAEzD,MAAM,KAAK,GAAG,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IACzC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,cAAc,CAAC;YACvB,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,uEAAuE;YAChF,IAAI,EAAE,eAAe;SACtB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAChC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC,CAAC;IAE3E,IAAI,KAAK,EAAE,CAAC;QACV,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACjD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAA2B;QACtC,aAAa,EAAE,UAAU,KAAK,EAAE;QAChC,MAAM,EAAE,kBAAkB;KAC3B,CAAC;IAEF,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;IAC/C,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;QAC3C,MAAM;QACN,OAAO;QACP,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;KAC9C,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,IAAI,SAAS,GAAwC,EAAE,CAAC;QACxD,IAAI,CAAC;YACH,SAAS,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAwC,CAAC;QAC7E,CAAC;QAAC,MAAM,CAAC;YACP,yBAAyB;QAC3B,CAAC;QAED,MAAM,IAAI,cAAc,CAAC;YACvB,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,OAAO,EAAE,SAAS,CAAC,OAAO,IAAI,kCAAkC,QAAQ,CAAC,MAAM,EAAE;YACjF,IAAI,EAAE,SAAS,CAAC,IAAI;SACrB,CAAC,CAAC;IACL,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC5B,OAAO,SAAc,CAAC;IACxB,CAAC;IAED,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;AACtC,CAAC"}
@@ -0,0 +1,23 @@
1
+ export interface StorlaunchConfig {
2
+ api_url: string;
3
+ token: string;
4
+ testApiKey?: string;
5
+ }
6
+ export declare function getConfigPath(): string;
7
+ export declare function getConfig(): StorlaunchConfig | null;
8
+ export declare function setConfig(updates: Partial<StorlaunchConfig>): StorlaunchConfig;
9
+ export declare function clearConfig(): void;
10
+ /**
11
+ * Resolves the active API key using the precedence chain:
12
+ * 1. STORLAUNCH_API_KEY env var
13
+ * 2. --sandbox flag (uses testApiKey)
14
+ * 3. Stored token in config
15
+ */
16
+ export declare function resolveApiKey(options?: {
17
+ sandbox?: boolean;
18
+ }): string | null;
19
+ /**
20
+ * Resolves the API base URL from config or default.
21
+ */
22
+ export declare function resolveApiUrl(): string;
23
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAOD,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,SAAS,IAAI,gBAAgB,GAAG,IAAI,CAWnD;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAQ9E;AAED,wBAAgB,WAAW,IAAI,IAAI,CAIlC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,GAAG,IAAI,CAY5E;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
@@ -0,0 +1,58 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, unlinkSync, existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { homedir } from "node:os";
4
+ const CONFIG_DIR = join(homedir(), ".storlaunch");
5
+ const CONFIG_FILE = join(CONFIG_DIR, "config.json");
6
+ const DEFAULT_API_URL = "https://storlaunch.forjio.com/api/v1";
7
+ export function getConfigPath() {
8
+ return CONFIG_FILE;
9
+ }
10
+ export function getConfig() {
11
+ if (!existsSync(CONFIG_FILE)) {
12
+ return null;
13
+ }
14
+ try {
15
+ const raw = readFileSync(CONFIG_FILE, "utf-8");
16
+ return JSON.parse(raw);
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ }
22
+ export function setConfig(updates) {
23
+ mkdirSync(CONFIG_DIR, { recursive: true });
24
+ const existing = getConfig() ?? { api_url: DEFAULT_API_URL, token: "" };
25
+ const config = { ...existing, ...updates };
26
+ writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n", "utf-8");
27
+ return config;
28
+ }
29
+ export function clearConfig() {
30
+ if (existsSync(CONFIG_FILE)) {
31
+ unlinkSync(CONFIG_FILE);
32
+ }
33
+ }
34
+ /**
35
+ * Resolves the active API key using the precedence chain:
36
+ * 1. STORLAUNCH_API_KEY env var
37
+ * 2. --sandbox flag (uses testApiKey)
38
+ * 3. Stored token in config
39
+ */
40
+ export function resolveApiKey(options) {
41
+ const envKey = process.env["STORLAUNCH_API_KEY"];
42
+ if (envKey)
43
+ return envKey;
44
+ const config = getConfig();
45
+ if (!config)
46
+ return null;
47
+ if (options?.sandbox && config.testApiKey) {
48
+ return config.testApiKey;
49
+ }
50
+ return config.token || null;
51
+ }
52
+ /**
53
+ * Resolves the API base URL from config or default.
54
+ */
55
+ export function resolveApiUrl() {
56
+ return getConfig()?.api_url ?? DEFAULT_API_URL;
57
+ }
58
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAQlC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;AAClD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEpD,MAAM,eAAe,GAAG,sCAAsC,CAAC;AAE/D,MAAM,UAAU,aAAa;IAC3B,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAkC;IAC1D,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3C,MAAM,QAAQ,GAAG,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IACxE,MAAM,MAAM,GAAqB,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAC;IAE7D,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5E,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,UAAU,CAAC,WAAW,CAAC,CAAC;IAC1B,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,OAA+B;IAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACjD,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,IAAI,OAAO,EAAE,OAAO,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAC1C,OAAO,MAAM,CAAC,UAAU,CAAC;IAC3B,CAAC;IAED,OAAO,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,SAAS,EAAE,EAAE,OAAO,IAAI,eAAe,CAAC;AACjD,CAAC"}
@@ -0,0 +1,21 @@
1
+ export interface Column {
2
+ key: string;
3
+ header: string;
4
+ width?: number;
5
+ }
6
+ /**
7
+ * Formats data as a table for terminal output.
8
+ */
9
+ export declare function formatTable(data: Record<string, unknown>[], columns: Column[]): string;
10
+ /**
11
+ * Formats data as JSON (for --json flag).
12
+ */
13
+ export declare function formatJson(data: unknown): string;
14
+ /**
15
+ * Outputs data in the appropriate format based on the --json flag.
16
+ */
17
+ export declare function output(data: unknown, options?: {
18
+ json?: boolean;
19
+ columns?: Column[];
20
+ }): void;
21
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAkCtF;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CA2B5F"}
@@ -0,0 +1,66 @@
1
+ import chalk from "chalk";
2
+ /**
3
+ * Formats data as a table for terminal output.
4
+ */
5
+ export function formatTable(data, columns) {
6
+ if (data.length === 0) {
7
+ return chalk.dim("No results.");
8
+ }
9
+ // Calculate column widths
10
+ const widths = columns.map((col) => {
11
+ const headerLen = col.header.length;
12
+ const maxDataLen = data.reduce((max, row) => {
13
+ const val = String(row[col.key] ?? "");
14
+ return Math.max(max, val.length);
15
+ }, 0);
16
+ return col.width ?? Math.max(headerLen, Math.min(maxDataLen, 40));
17
+ });
18
+ // Header row
19
+ const header = columns
20
+ .map((col, i) => chalk.bold(col.header.padEnd(widths[i])))
21
+ .join(" ");
22
+ // Separator
23
+ const separator = widths.map((w) => "─".repeat(w)).join("──");
24
+ // Data rows
25
+ const rows = data.map((row) => columns
26
+ .map((col, i) => {
27
+ const val = String(row[col.key] ?? "");
28
+ return val.length > widths[i] ? val.slice(0, widths[i] - 1) + "…" : val.padEnd(widths[i]);
29
+ })
30
+ .join(" "));
31
+ return [header, separator, ...rows].join("\n");
32
+ }
33
+ /**
34
+ * Formats data as JSON (for --json flag).
35
+ */
36
+ export function formatJson(data) {
37
+ return JSON.stringify(data, null, 2);
38
+ }
39
+ /**
40
+ * Outputs data in the appropriate format based on the --json flag.
41
+ */
42
+ export function output(data, options) {
43
+ if (options?.json) {
44
+ console.log(formatJson(data));
45
+ return;
46
+ }
47
+ if (Array.isArray(data) && options?.columns) {
48
+ console.log(formatTable(data, options.columns));
49
+ return;
50
+ }
51
+ if (typeof data === "string") {
52
+ console.log(data);
53
+ return;
54
+ }
55
+ // Fallback: key-value display for objects
56
+ if (data && typeof data === "object" && !Array.isArray(data)) {
57
+ const entries = Object.entries(data);
58
+ const maxKeyLen = Math.max(...entries.map(([k]) => k.length));
59
+ for (const [key, value] of entries) {
60
+ console.log(`${chalk.bold(key.padEnd(maxKeyLen))} ${value}`);
61
+ }
62
+ return;
63
+ }
64
+ console.log(formatJson(data));
65
+ }
66
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/lib/output.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@forjio/storlaunch-cli",
3
+ "version": "0.1.0",
4
+ "description": "Storlaunch CLI — manage payments, subscriptions, storefronts, and webhooks from the terminal",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "storlaunch": "./bin/storlaunch.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc --watch",
13
+ "test": "vitest run --exclude src/__tests__/e2e/**",
14
+ "test:watch": "vitest --exclude src/__tests__/e2e/**",
15
+ "test:e2e": "BACKEND_URL=https://storlaunch.forjio.com/api/v1 vitest run src/__tests__/e2e/"
16
+ },
17
+ "dependencies": {
18
+ "chalk": "^5.3.0",
19
+ "commander": "^12.1.0"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^22.0.0",
23
+ "typescript": "^5.6.0",
24
+ "vitest": "^2.1.0"
25
+ },
26
+ "files": [
27
+ "dist",
28
+ "bin"
29
+ ],
30
+ "engines": {
31
+ "node": ">=18.0.0"
32
+ },
33
+ "license": "MIT"
34
+ }