dodopayments-cli 2.2.0 → 3.0.1

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,27 @@
1
+ ; Query from: https://raw.githubusercontent.com/nvim-treesitter/nvim-treesitter/refs/heads/master/queries/markdown/injections.scm
2
+ (fenced_code_block
3
+ (info_string
4
+ (language) @_lang)
5
+ (code_fence_content) @injection.content
6
+ (#set-lang-from-info-string! @_lang))
7
+
8
+ ((html_block) @injection.content
9
+ (#set! injection.language "html")
10
+ (#set! injection.combined)
11
+ (#set! injection.include-children))
12
+
13
+ ((minus_metadata) @injection.content
14
+ (#set! injection.language "yaml")
15
+ (#offset! @injection.content 1 0 -1 0)
16
+ (#set! injection.include-children))
17
+
18
+ ((plus_metadata) @injection.content
19
+ (#set! injection.language "toml")
20
+ (#offset! @injection.content 1 0 -1 0)
21
+ (#set! injection.include-children))
22
+
23
+ ([
24
+ (inline)
25
+ (pipe_table_cell)
26
+ ] @injection.content
27
+ (#set! injection.language "markdown_inline"))
Binary file
package/package.json CHANGED
@@ -1,10 +1,28 @@
1
1
  {
2
2
  "name": "dodopayments-cli",
3
- "version": "2.2.0",
4
- "description": "A CLI for Dodo Payments",
3
+ "version": "3.0.1",
4
+ "description": "Official Dodo Payments CLI — manage payments, customers, products, subscriptions, and webhooks from your terminal. Includes an interactive TUI, an AI assistant powered by MCP, and offline webhook testing.",
5
5
  "keywords": [
6
6
  "dodopayments",
7
- "cli"
7
+ "dodo-payments",
8
+ "cli",
9
+ "command-line",
10
+ "terminal",
11
+ "tui",
12
+ "payments",
13
+ "billing",
14
+ "subscriptions",
15
+ "checkout",
16
+ "saas",
17
+ "developer-tools",
18
+ "webhooks",
19
+ "webhook-testing",
20
+ "ai",
21
+ "mcp",
22
+ "typescript",
23
+ "bun",
24
+ "opentui",
25
+ "stripe-alternative"
8
26
  ],
9
27
  "homepage": "https://github.com/dodopayments/dodopayments-cli#readme",
10
28
  "bugs": {
@@ -14,7 +32,7 @@
14
32
  "type": "git",
15
33
  "url": "git+https://github.com/dodopayments/dodopayments-cli.git"
16
34
  },
17
- "license": "ISC",
35
+ "license": "GPL-3.0-or-later",
18
36
  "author": "Dodo Payments",
19
37
  "type": "module",
20
38
  "main": "index.ts",
@@ -23,15 +41,29 @@
23
41
  "dodopayments": "dist/index.js"
24
42
  },
25
43
  "scripts": {
26
- "build": "bun build ./src/index.ts --minify --target node --outfile ./dist/index.js",
27
- "build-native": "bun run build-binaries.ts"
44
+ "build": "bun run scripts/build.ts",
45
+ "build-native": "bun run build-binaries.ts",
46
+ "dev": "bun src/index.ts"
28
47
  },
29
48
  "dependencies": {
49
+ "@ai-sdk/mcp": "^1.0.36",
50
+ "@ai-sdk/openai": "^3.0.54",
51
+ "@modelcontextprotocol/sdk": "^1.29.0",
52
+ "@openrouter/ai-sdk-provider": "^2.8.0",
53
+ "@opentui/core": "^0.2.3",
54
+ "@opentui/solid": "^0.2.3",
55
+ "ai": "^6.0.168",
56
+ "chalk": "^5.6.2",
30
57
  "dodopayments": "^2.19.0",
31
- "inquirer": "^13.2.2",
32
- "open": "^11.0.0"
58
+ "keytar": "^7.9.0",
59
+ "open": "^11.0.0",
60
+ "solid-js": "^1.9.12"
33
61
  },
34
62
  "devDependencies": {
63
+ "@opentui/core-darwin-x64": "0.2.3",
64
+ "@opentui/core-linux-arm64": "0.2.3",
65
+ "@opentui/core-linux-x64": "0.2.3",
66
+ "@opentui/core-win32-x64": "0.2.3",
35
67
  "@types/bun": "latest"
36
68
  },
37
69
  "peerDependencies": {
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Production bundler. Bun's `bun build` does NOT honor bunfig.toml's
3
+ * preload (per OpenTUI #122), so we drive Bun.build directly with the
4
+ * @opentui/solid bun-plugin to apply the Solid babel transform on every
5
+ * `.tsx/.jsx` file.
6
+ *
7
+ * The runtime path uses bunfig.toml's preload instead -- both code paths
8
+ * end up registering the same plugin, just at different lifecycles.
9
+ *
10
+ * After bundling, we inject a tiny Node-compatible prelude that re-execs
11
+ * the bundle under Bun if it's launched by Node. This is required because
12
+ * `target: 'bun'` emits Bun-only runtime APIs (e.g. `import.meta.require`)
13
+ * and our native deps (@opentui/core, keytar) load through Bun's loader.
14
+ *
15
+ * Without this prelude, `bun install -g dodopayments-cli` works on disk
16
+ * but the symlinked `dodo` binary is invoked via `#!/usr/bin/env node`,
17
+ * which crashes immediately with "Qg is not a function" because Node has
18
+ * no `import.meta.require`. The prelude makes Node hand control off to
19
+ * Bun transparently, and gives a clear error if Bun isn't installed.
20
+ */
21
+
22
+ import { readFileSync, writeFileSync } from 'node:fs';
23
+ import solidPlugin from '@opentui/solid/bun-plugin';
24
+
25
+ const result = await Bun.build({
26
+ entrypoints: ['./src/index.ts'],
27
+ outdir: './dist',
28
+ target: 'bun',
29
+ minify: true,
30
+ plugins: [solidPlugin],
31
+ });
32
+
33
+ if (!result.success) {
34
+ console.error('Build failed.');
35
+ for (const message of result.logs) console.error(message);
36
+ process.exit(1);
37
+ }
38
+
39
+ const main = result.outputs.find((o) => o.kind === 'entry-point');
40
+ if (!main) {
41
+ console.error('Build succeeded but no entry-point output was produced.');
42
+ process.exit(1);
43
+ }
44
+
45
+ const outPath = main.path;
46
+
47
+ /**
48
+ * Node-safe prelude. Must contain ZERO Bun-only APIs.
49
+ *
50
+ * Why this works:
51
+ * - Top-level await in ESM BLOCKS subsequent top-level statements
52
+ * until it resolves. So under Node, the `await import(...)` inside
53
+ * the `if` block runs to completion (and calls process.exit) before
54
+ * any of the bundle's Bun-only top-level code is reached.
55
+ * - Under Bun, the `if` is skipped and the bundle runs normally.
56
+ *
57
+ * Why not wrap the rest of the bundle in `else { ... }`:
58
+ * - The bundle contains top-level `import ...` declarations, which
59
+ * are syntactically forbidden inside a block. So we cannot wrap.
60
+ * Instead we rely on `process.exit()` inside the `if` to keep Node
61
+ * from ever continuing past it.
62
+ *
63
+ * Bun detection:
64
+ * - `typeof Bun !== 'undefined'` is the documented way to detect Bun.
65
+ * Node has no such global. Deno also lacks it; Deno would also fail
66
+ * on other Bun-only bits below, so the explicit error message is
67
+ * the correct outcome for any non-Bun runtime.
68
+ */
69
+ const prelude = `if (typeof Bun === 'undefined') {
70
+ const { spawnSync } = await import('node:child_process');
71
+ const { existsSync } = await import('node:fs');
72
+ const { fileURLToPath } = await import('node:url');
73
+ const path = await import('node:path');
74
+ const os = await import('node:os');
75
+
76
+ const scriptPath = fileURLToPath(import.meta.url);
77
+ const isWindows = process.platform === 'win32';
78
+
79
+ const which = spawnSync(isWindows ? 'where' : 'which', ['bun'], { encoding: 'utf8' });
80
+ let bun = null;
81
+ if (which.status === 0 && which.stdout) {
82
+ const first = which.stdout.split(/\\r?\\n/).find(Boolean);
83
+ if (first && existsSync(first)) bun = first;
84
+ }
85
+ if (!bun) {
86
+ const candidates = [
87
+ path.join(os.homedir(), '.bun', 'bin', isWindows ? 'bun.exe' : 'bun'),
88
+ '/usr/local/bin/bun',
89
+ '/opt/homebrew/bin/bun',
90
+ ];
91
+ for (const c of candidates) {
92
+ if (existsSync(c)) { bun = c; break; }
93
+ }
94
+ }
95
+
96
+ if (!bun) {
97
+ process.stderr.write(
98
+ 'dodopayments-cli requires the Bun runtime when installed via npm/bun.\\n' +
99
+ '\\n' +
100
+ 'Install Bun: https://bun.com/docs/installation\\n' +
101
+ 'Or download a standalone binary (no runtime required):\\n' +
102
+ ' https://github.com/dodopayments/dodopayments-cli/releases\\n'
103
+ );
104
+ process.exit(1);
105
+ }
106
+
107
+ const child = spawnSync(bun, [scriptPath, ...process.argv.slice(2)], {
108
+ stdio: 'inherit',
109
+ env: process.env,
110
+ });
111
+ if (child.error) {
112
+ process.stderr.write('Failed to launch bun: ' + child.error.message + '\\n');
113
+ process.exit(1);
114
+ }
115
+ if (typeof child.signal === 'string' && child.signal) {
116
+ process.kill(process.pid, child.signal);
117
+ }
118
+ process.exit(child.status ?? 0);
119
+ }
120
+ `;
121
+
122
+ const original = readFileSync(outPath, 'utf8');
123
+
124
+ // Splice the prelude immediately after the shebang (Bun emits it on line 1
125
+ // when bundling an executable). Everything below the shebang is untouched.
126
+ const newlineIdx = original.indexOf('\n');
127
+ const firstLine = newlineIdx >= 0 ? original.slice(0, newlineIdx) : '';
128
+ const hasShebang = firstLine.startsWith('#!');
129
+ const shebang = hasShebang ? firstLine : '';
130
+ const body = hasShebang ? original.slice(newlineIdx + 1) : original;
131
+
132
+ const patched = (shebang ? `${shebang}\n` : '') + prelude + body;
133
+ writeFileSync(outPath, patched);
134
+
135
+ const sizeKb = (Buffer.byteLength(patched, 'utf8') / 1024).toFixed(0);
136
+ console.log(`\u2713 Built ${outPath} (${sizeKb} KB)`);
package/test-select.ts ADDED
@@ -0,0 +1,2 @@
1
+ import { mountTuiApp } from './src/tui/app';
2
+ mountTuiApp();
package/tsconfig.json CHANGED
@@ -1,27 +1,25 @@
1
1
  {
2
2
  "compilerOptions": {
3
- // Environment setup & latest features
4
3
  "lib": ["ESNext"],
5
4
  "target": "ESNext",
6
5
  "module": "Preserve",
7
6
  "moduleDetection": "force",
8
- "jsx": "react-jsx",
7
+ "jsx": "preserve",
8
+ "jsxImportSource": "@opentui/solid",
9
9
  "allowJs": true,
10
10
 
11
- // Bundler mode
12
11
  "moduleResolution": "bundler",
13
12
  "allowImportingTsExtensions": true,
14
13
  "verbatimModuleSyntax": true,
15
14
  "noEmit": true,
15
+ "resolveJsonModule": true,
16
16
 
17
- // Best practices
18
17
  "strict": true,
19
18
  "skipLibCheck": true,
20
19
  "noFallthroughCasesInSwitch": true,
21
20
  "noUncheckedIndexedAccess": true,
22
21
  "noImplicitOverride": true,
23
22
 
24
- // Some stricter flags (disabled by default)
25
23
  "noUnusedLocals": false,
26
24
  "noUnusedParameters": false,
27
25
  "noPropertyAccessFromIndexSignature": false