@toneflix/paystack-cli 0.1.2 → 0.1.4

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 (3) hide show
  1. package/bin/cli.cjs +106 -31
  2. package/bin/cli.js +91 -21
  3. package/package.json +5 -5
package/bin/cli.cjs CHANGED
@@ -22,8 +22,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  }) : target, mod));
23
23
 
24
24
  //#endregion
25
+ let path = require("path");
26
+ path = __toESM(path);
25
27
  let better_sqlite3 = require("better-sqlite3");
26
28
  better_sqlite3 = __toESM(better_sqlite3);
29
+ let url = require("url");
30
+ url = __toESM(url);
31
+ let fs = require("fs");
32
+ fs = __toESM(fs);
27
33
  let __h3ravel_shared = require("@h3ravel/shared");
28
34
  __h3ravel_shared = __toESM(__h3ravel_shared);
29
35
  let axios = require("axios");
@@ -32,17 +38,44 @@ let __h3ravel_musket = require("@h3ravel/musket");
32
38
  __h3ravel_musket = __toESM(__h3ravel_musket);
33
39
  let ora = require("ora");
34
40
  ora = __toESM(ora);
41
+ let module$1 = require("module");
42
+ module$1 = __toESM(module$1);
43
+ let os = require("os");
44
+ os = __toESM(os);
35
45
  let crypto = require("crypto");
36
46
  crypto = __toESM(crypto);
37
47
  let __ngrok_ngrok = require("@ngrok/ngrok");
38
48
  __ngrok_ngrok = __toESM(__ngrok_ngrok);
39
49
 
40
50
  //#region src/db.ts
41
- const db = new better_sqlite3.default("app.db");
42
- db.pragma("journal_mode = WAL");
43
- function init(table = "json_store") {
44
- return db.exec(`
45
- CREATE TABLE IF NOT EXISTS ${table} (
51
+ let db;
52
+ const __dirname$1 = (0, path.dirname)((0, url.fileURLToPath)(require("url").pathToFileURL(__filename).href));
53
+ const dirPath = path.default.normalize(path.default.join(__dirname$1, "..", "data"));
54
+ (0, fs.mkdirSync)(dirPath, { recursive: true });
55
+ const useDbPath = () => [dirPath];
56
+ /**
57
+ * Hook to get or set the database instance.
58
+ *
59
+ * @returns
60
+ */
61
+ const useDb = () => {
62
+ return [() => db, (newDb) => {
63
+ db = newDb;
64
+ const [{ journal_mode }] = db.pragma("journal_mode");
65
+ if (journal_mode !== "wal") db.pragma("journal_mode = WAL");
66
+ }];
67
+ };
68
+ const [getDatabase, setDatabase] = useDb();
69
+ setDatabase(new better_sqlite3.default(path.default.join(dirPath, "app.db")));
70
+ /**
71
+ * Initialize the database
72
+ *
73
+ * @param table
74
+ * @returns
75
+ */
76
+ function init() {
77
+ return getDatabase().exec(`
78
+ CREATE TABLE IF NOT EXISTS json_store (
46
79
  id INTEGER PRIMARY KEY AUTOINCREMENT,
47
80
  key TEXT UNIQUE,
48
81
  value TEXT
@@ -56,16 +89,24 @@ function init(table = "json_store") {
56
89
  * @param value
57
90
  * @returns
58
91
  */
59
- function write(key, value, table = "json_store") {
92
+ function write(key, value) {
93
+ const db$1 = getDatabase();
60
94
  if (typeof value === "boolean") value = value ? "1" : "0";
61
95
  if (value instanceof Object) value = JSON.stringify(value);
62
- return db.prepare(`INSERT INTO ${table} (key, value)
96
+ return db$1.prepare(`INSERT INTO json_store (key, value)
63
97
  VALUES (?, ?)
64
98
  ON CONFLICT(key) DO UPDATE SET value=excluded.value
65
99
  `).run(key, value).lastInsertRowid;
66
100
  }
67
- function remove(key, table = "json_store") {
68
- return db.prepare(`DELETE FROM ${table} WHERE key = ?`).run(key).lastInsertRowid;
101
+ /**
102
+ * Remove a value from the database
103
+ *
104
+ * @param key
105
+ * @param table
106
+ * @returns
107
+ */
108
+ function remove(key) {
109
+ return getDatabase().prepare("DELETE FROM json_store WHERE key = ?").run(key).lastInsertRowid;
69
110
  }
70
111
  /**
71
112
  * Read a value from the database
@@ -73,13 +114,16 @@ function remove(key, table = "json_store") {
73
114
  * @param key
74
115
  * @returns
75
116
  */
76
- function read(key, table = "json_store") {
77
- const row = db.prepare(`SELECT * FROM ${table} WHERE key = ?`).get(key);
78
- if (row) try {
79
- return JSON.parse(row.value);
80
- } catch {
81
- return row.value;
82
- }
117
+ function read(key) {
118
+ const db$1 = getDatabase();
119
+ try {
120
+ const row = db$1.prepare("SELECT * FROM json_store WHERE key = ?").get(key);
121
+ if (row) try {
122
+ return JSON.parse(row.value);
123
+ } catch {
124
+ return row.value;
125
+ }
126
+ } catch {}
83
127
  return null;
84
128
  }
85
129
 
@@ -260,14 +304,14 @@ async function executeSchema(schema, options) {
260
304
  if (schema.method == "GET") params = options;
261
305
  if (schema.method == "POST") data = options;
262
306
  const pathVars = [...schema.endpoint.matchAll(/\{([^}]+)\}/g)].map((match) => match[1]);
263
- if (pathVars.length >= 0) for (const path of pathVars) schema.endpoint = schema.endpoint.replace("{" + path + "}", options[path]);
264
- const url = new URL(schema.endpoint, config.apiBaseURL || "https://api.paystack.co");
307
+ if (pathVars.length >= 0) for (const path$2 of pathVars) schema.endpoint = schema.endpoint.replace("{" + path$2 + "}", options[path$2]);
308
+ const url$1 = new URL(schema.endpoint, config.apiBaseURL || "https://api.paystack.co");
265
309
  params = {
266
310
  ...params,
267
- ...Object.fromEntries(url.searchParams.entries())
311
+ ...Object.fromEntries(url$1.searchParams.entries())
268
312
  };
269
313
  axios_default.request({
270
- url: url.pathname,
314
+ url: url$1.pathname,
271
315
  method: schema.method,
272
316
  params,
273
317
  data,
@@ -2536,10 +2580,7 @@ var Commands_default = () => {
2536
2580
  for (const param of schema.params) if (param.required && !this.argument(param.parameter)) return void this.newLine().error(`Missing required argument: ${param.parameter}`).newLine();
2537
2581
  const selected_integration = read("selected_integration")?.id;
2538
2582
  const user = read("user")?.id;
2539
- if (!selected_integration || !user) {
2540
- this.error("ERROR: You're not signed in, please run the [login] command before you begin").newLine();
2541
- return;
2542
- }
2583
+ if (!selected_integration || !user) return void this.error("ERROR: You're not signed in, please run the [login] command before you begin").newLine();
2543
2584
  this.newLine();
2544
2585
  const spinner = (0, ora.default)("Loading...\n").start();
2545
2586
  const [err, result] = await promiseWrapper(executeSchema(schema, {
@@ -2632,6 +2673,39 @@ var ConfigCommand = class extends __h3ravel_musket.Command {
2632
2673
  }
2633
2674
  };
2634
2675
 
2676
+ //#endregion
2677
+ //#region src/Commands/InfoCommand.ts
2678
+ var InfoCommand = class extends __h3ravel_musket.Command {
2679
+ signature = "info";
2680
+ description = "Display application runtime information.";
2681
+ async handle() {
2682
+ const require$1 = (0, module$1.createRequire)(require("url").pathToFileURL(__filename).href);
2683
+ const [_, setCommand] = useCommand();
2684
+ const [dbPath] = useDbPath();
2685
+ setCommand(this);
2686
+ init();
2687
+ const pkg = require$1("../../package.json");
2688
+ const spinner = (0, ora.default)("Gathering application information...\n").start();
2689
+ wait(500, () => {
2690
+ spinner.stop();
2691
+ dataRenderer({
2692
+ appVersion: pkg.version,
2693
+ platform: os.default.platform(),
2694
+ arch: os.default.arch(),
2695
+ cpus: os.default.cpus().length,
2696
+ hostname: os.default.hostname(),
2697
+ totalMemory: os.default.totalmem(),
2698
+ freeMemory: os.default.freemem(),
2699
+ uptime: os.default.uptime(),
2700
+ username: os.default.userInfo().username,
2701
+ database: dbPath + "/app.db",
2702
+ dependencies: Object.keys(pkg.dependencies).join(", ")
2703
+ });
2704
+ this.newLine();
2705
+ });
2706
+ }
2707
+ };
2708
+
2635
2709
  //#endregion
2636
2710
  //#region src/Commands/InitCommand.ts
2637
2711
  var InitCommand = class extends __h3ravel_musket.Command {
@@ -2895,10 +2969,10 @@ async function refreshIntegration() {
2895
2969
  * @param domain
2896
2970
  * @returns
2897
2971
  */
2898
- function setWebhook(url, token, integrationId, domain = "test") {
2972
+ function setWebhook(url$1, token, integrationId, domain = "test") {
2899
2973
  return new Promise((resolve, reject) => {
2900
2974
  const data = {
2901
- [domain + "_webhook_endpoint"]: url,
2975
+ [domain + "_webhook_endpoint"]: url$1,
2902
2976
  integration: integrationId
2903
2977
  };
2904
2978
  axios_default.put("/integration/webhooks", data, { headers: {
@@ -2908,7 +2982,7 @@ function setWebhook(url, token, integrationId, domain = "test") {
2908
2982
  const integration = read("selected_integration");
2909
2983
  write("selected_integration", {
2910
2984
  ...integration,
2911
- [domain + "_webhook_endpoint"]: url
2985
+ [domain + "_webhook_endpoint"]: url$1
2912
2986
  });
2913
2987
  resolve(resp.data.message);
2914
2988
  }).catch((err) => {
@@ -3209,16 +3283,16 @@ var WebhookCommand = class extends __h3ravel_musket.Command {
3209
3283
  this.error("ERROR: Your session has expired. Please run the `login` command to sign in again.");
3210
3284
  return;
3211
3285
  }
3212
- const url = parseURL(local_route);
3213
- if (!url.port) url.port = "8000";
3214
- if (!url.search || url.search == "?") url.search = "";
3286
+ const url$1 = parseURL(local_route);
3287
+ if (!url$1.port) url$1.port = "8000";
3288
+ if (!url$1.search || url$1.search == "?") url$1.search = "";
3215
3289
  try {
3216
3290
  await __ngrok_ngrok.default.kill();
3217
3291
  } catch {
3218
3292
  this.debug("No existing ngrok process found to kill.");
3219
3293
  }
3220
3294
  const ngrokURL = (await __ngrok_ngrok.default.forward({
3221
- addr: url.port,
3295
+ addr: url$1.port,
3222
3296
  authtoken: config.ngrokAuthToken || process.env.NGROK_AUTH_TOKEN,
3223
3297
  domain: process.env.NGROK_DOMAIN
3224
3298
  })).url();
@@ -3265,6 +3339,7 @@ __h3ravel_musket.Kernel.init(new Application(), {
3265
3339
  console.error(config.debug ? exception : exception.message);
3266
3340
  },
3267
3341
  baseCommands: [
3342
+ InfoCommand,
3268
3343
  InitCommand,
3269
3344
  LoginCommand,
3270
3345
  LogoutCommand,
package/bin/cli.js CHANGED
@@ -1,18 +1,46 @@
1
1
  #!/usr/bin/env node
2
+ import path, { dirname } from "path";
2
3
  import Database from "better-sqlite3";
4
+ import { fileURLToPath } from "url";
5
+ import { mkdirSync } from "fs";
3
6
  import { Logger } from "@h3ravel/shared";
4
7
  import axios from "axios";
5
8
  import { Command, Kernel } from "@h3ravel/musket";
6
9
  import ora from "ora";
10
+ import { createRequire } from "module";
11
+ import os from "os";
7
12
  import crypto from "crypto";
8
13
  import ngrok from "@ngrok/ngrok";
9
14
 
10
15
  //#region src/db.ts
11
- const db = new Database("app.db");
12
- db.pragma("journal_mode = WAL");
13
- function init(table = "json_store") {
14
- return db.exec(`
15
- CREATE TABLE IF NOT EXISTS ${table} (
16
+ let db;
17
+ const __dirname = dirname(fileURLToPath(import.meta.url));
18
+ const dirPath = path.normalize(path.join(__dirname, "..", "data"));
19
+ mkdirSync(dirPath, { recursive: true });
20
+ const useDbPath = () => [dirPath];
21
+ /**
22
+ * Hook to get or set the database instance.
23
+ *
24
+ * @returns
25
+ */
26
+ const useDb = () => {
27
+ return [() => db, (newDb) => {
28
+ db = newDb;
29
+ const [{ journal_mode }] = db.pragma("journal_mode");
30
+ if (journal_mode !== "wal") db.pragma("journal_mode = WAL");
31
+ }];
32
+ };
33
+ const [getDatabase, setDatabase] = useDb();
34
+ setDatabase(new Database(path.join(dirPath, "app.db")));
35
+ /**
36
+ * Initialize the database
37
+ *
38
+ * @param table
39
+ * @returns
40
+ */
41
+ function init() {
42
+ return getDatabase().exec(`
43
+ CREATE TABLE IF NOT EXISTS json_store (
16
44
  id INTEGER PRIMARY KEY AUTOINCREMENT,
17
45
  key TEXT UNIQUE,
18
46
  value TEXT
@@ -26,16 +54,24 @@ function init(table = "json_store") {
26
54
  * @param value
27
55
  * @returns
28
56
  */
29
- function write(key, value, table = "json_store") {
57
+ function write(key, value) {
58
+ const db$1 = getDatabase();
30
59
  if (typeof value === "boolean") value = value ? "1" : "0";
31
60
  if (value instanceof Object) value = JSON.stringify(value);
32
- return db.prepare(`INSERT INTO ${table} (key, value)
61
+ return db$1.prepare(`INSERT INTO json_store (key, value)
33
62
  VALUES (?, ?)
34
63
  ON CONFLICT(key) DO UPDATE SET value=excluded.value
35
64
  `).run(key, value).lastInsertRowid;
36
65
  }
37
- function remove(key, table = "json_store") {
38
- return db.prepare(`DELETE FROM ${table} WHERE key = ?`).run(key).lastInsertRowid;
66
+ /**
67
+ * Remove a value from the database
68
+ *
69
+ * @param key
70
+ * @param table
71
+ * @returns
72
+ */
73
+ function remove(key) {
74
+ return getDatabase().prepare("DELETE FROM json_store WHERE key = ?").run(key).lastInsertRowid;
39
75
  }
40
76
  /**
41
77
  * Read a value from the database
@@ -43,13 +79,16 @@ function remove(key, table = "json_store") {
43
79
  * @param key
44
80
  * @returns
45
81
  */
46
- function read(key, table = "json_store") {
47
- const row = db.prepare(`SELECT * FROM ${table} WHERE key = ?`).get(key);
48
- if (row) try {
49
- return JSON.parse(row.value);
50
- } catch {
51
- return row.value;
52
- }
82
+ function read(key) {
83
+ const db$1 = getDatabase();
84
+ try {
85
+ const row = db$1.prepare("SELECT * FROM json_store WHERE key = ?").get(key);
86
+ if (row) try {
87
+ return JSON.parse(row.value);
88
+ } catch {
89
+ return row.value;
90
+ }
91
+ } catch {}
53
92
  return null;
54
93
  }
55
94
 
@@ -230,7 +269,7 @@ async function executeSchema(schema, options) {
230
269
  if (schema.method == "GET") params = options;
231
270
  if (schema.method == "POST") data = options;
232
271
  const pathVars = [...schema.endpoint.matchAll(/\{([^}]+)\}/g)].map((match) => match[1]);
233
- if (pathVars.length >= 0) for (const path of pathVars) schema.endpoint = schema.endpoint.replace("{" + path + "}", options[path]);
272
+ if (pathVars.length >= 0) for (const path$1 of pathVars) schema.endpoint = schema.endpoint.replace("{" + path$1 + "}", options[path$1]);
234
273
  const url = new URL(schema.endpoint, config.apiBaseURL || "https://api.paystack.co");
235
274
  params = {
236
275
  ...params,
@@ -2506,10 +2545,7 @@ var Commands_default = () => {
2506
2545
  for (const param of schema.params) if (param.required && !this.argument(param.parameter)) return void this.newLine().error(`Missing required argument: ${param.parameter}`).newLine();
2507
2546
  const selected_integration = read("selected_integration")?.id;
2508
2547
  const user = read("user")?.id;
2509
- if (!selected_integration || !user) {
2510
- this.error("ERROR: You're not signed in, please run the [login] command before you begin").newLine();
2511
- return;
2512
- }
2548
+ if (!selected_integration || !user) return void this.error("ERROR: You're not signed in, please run the [login] command before you begin").newLine();
2513
2549
  this.newLine();
2514
2550
  const spinner = ora("Loading...\n").start();
2515
2551
  const [err, result] = await promiseWrapper(executeSchema(schema, {
@@ -2602,6 +2638,39 @@ var ConfigCommand = class extends Command {
2602
2638
  }
2603
2639
  };
2604
2640
 
2641
+ //#endregion
2642
+ //#region src/Commands/InfoCommand.ts
2643
+ var InfoCommand = class extends Command {
2644
+ signature = "info";
2645
+ description = "Display application runtime information.";
2646
+ async handle() {
2647
+ const require = createRequire(import.meta.url);
2648
+ const [_, setCommand] = useCommand();
2649
+ const [dbPath] = useDbPath();
2650
+ setCommand(this);
2651
+ init();
2652
+ const pkg = require("../../package.json");
2653
+ const spinner = ora("Gathering application information...\n").start();
2654
+ wait(500, () => {
2655
+ spinner.stop();
2656
+ dataRenderer({
2657
+ appVersion: pkg.version,
2658
+ platform: os.platform(),
2659
+ arch: os.arch(),
2660
+ cpus: os.cpus().length,
2661
+ hostname: os.hostname(),
2662
+ totalMemory: os.totalmem(),
2663
+ freeMemory: os.freemem(),
2664
+ uptime: os.uptime(),
2665
+ username: os.userInfo().username,
2666
+ database: dbPath + "/app.db",
2667
+ dependencies: Object.keys(pkg.dependencies).join(", ")
2668
+ });
2669
+ this.newLine();
2670
+ });
2671
+ }
2672
+ };
2673
+
2605
2674
  //#endregion
2606
2675
  //#region src/Commands/InitCommand.ts
2607
2676
  var InitCommand = class extends Command {
@@ -3235,6 +3304,7 @@ Kernel.init(new Application(), {
3235
3304
  console.error(config.debug ? exception : exception.message);
3236
3305
  },
3237
3306
  baseCommands: [
3307
+ InfoCommand,
3238
3308
  InitCommand,
3239
3309
  LoginCommand,
3240
3310
  LogoutCommand,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@toneflix/paystack-cli",
3
3
  "type": "module",
4
- "version": "0.1.2",
4
+ "version": "0.1.4",
5
5
  "description": "Interact with the Paystack API, test webhooks locally, and manage your integration settings without leaving your command line.",
6
6
  "main": "bin/cli.js",
7
7
  "private": false,
@@ -37,18 +37,18 @@
37
37
  "toneflix"
38
38
  ],
39
39
  "dependencies": {
40
- "@eslint/js": "^9.39.2",
41
- "@eslint/markdown": "^7.5.1",
42
40
  "@h3ravel/musket": "^0.6.18",
43
41
  "@h3ravel/shared": "^0.28.4",
44
42
  "@ngrok/ngrok": "^1.7.0",
45
43
  "axios": "^1.13.2",
46
44
  "better-sqlite3": "^12.6.2",
47
45
  "ora": "^9.0.0",
48
- "tsdown": "^0.15.4",
49
- "typescript-eslint": "^8.53.0"
46
+ "tsdown": "^0.15.4"
50
47
  },
51
48
  "devDependencies": {
49
+ "@eslint/js": "^9.39.2",
50
+ "typescript-eslint": "^8.53.0",
51
+ "@eslint/markdown": "^7.5.1",
52
52
  "sass-embedded": "^1.90.0",
53
53
  "@changesets/cli": "^2.29.5",
54
54
  "@swc/core": "^1.6.1",