@parix/cli 0.1.5

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 (66) hide show
  1. package/README.md +123 -0
  2. package/dist/cli.cjs +30 -0
  3. package/dist/cli.d.cts +2 -0
  4. package/dist/cli.d.ts +2 -0
  5. package/dist/cli.js +28 -0
  6. package/dist/commands/api.cjs +81 -0
  7. package/dist/commands/api.d.cts +2 -0
  8. package/dist/commands/api.d.ts +2 -0
  9. package/dist/commands/api.js +78 -0
  10. package/dist/commands/auth.cjs +128 -0
  11. package/dist/commands/auth.d.cts +2 -0
  12. package/dist/commands/auth.d.ts +2 -0
  13. package/dist/commands/auth.js +125 -0
  14. package/dist/commands/database.cjs +259 -0
  15. package/dist/commands/database.d.cts +2 -0
  16. package/dist/commands/database.d.ts +2 -0
  17. package/dist/commands/database.js +256 -0
  18. package/dist/commands/tb.cjs +242 -0
  19. package/dist/commands/tb.d.cts +2 -0
  20. package/dist/commands/tb.d.ts +2 -0
  21. package/dist/commands/tb.js +239 -0
  22. package/dist/lib/api-client.cjs +44 -0
  23. package/dist/lib/api-client.d.cts +10 -0
  24. package/dist/lib/api-client.d.ts +10 -0
  25. package/dist/lib/api-client.js +40 -0
  26. package/dist/lib/config.cjs +24 -0
  27. package/dist/lib/config.d.cts +10 -0
  28. package/dist/lib/config.d.ts +10 -0
  29. package/dist/lib/config.js +18 -0
  30. package/dist/lib/loopback-server.cjs +158 -0
  31. package/dist/lib/loopback-server.d.cts +20 -0
  32. package/dist/lib/loopback-server.d.ts +20 -0
  33. package/dist/lib/loopback-server.js +155 -0
  34. package/dist/lib/oauth-api.cjs +73 -0
  35. package/dist/lib/oauth-api.d.cts +31 -0
  36. package/dist/lib/oauth-api.d.ts +31 -0
  37. package/dist/lib/oauth-api.js +68 -0
  38. package/dist/lib/oauth-session.cjs +108 -0
  39. package/dist/lib/oauth-session.d.cts +32 -0
  40. package/dist/lib/oauth-session.d.ts +32 -0
  41. package/dist/lib/oauth-session.js +103 -0
  42. package/dist/lib/oauth.cjs +58 -0
  43. package/dist/lib/oauth.d.cts +19 -0
  44. package/dist/lib/oauth.d.ts +19 -0
  45. package/dist/lib/oauth.js +49 -0
  46. package/dist/lib/open-url.cjs +38 -0
  47. package/dist/lib/open-url.d.cts +1 -0
  48. package/dist/lib/open-url.d.ts +1 -0
  49. package/dist/lib/open-url.js +32 -0
  50. package/dist/lib/output.cjs +20 -0
  51. package/dist/lib/output.d.cts +6 -0
  52. package/dist/lib/output.d.ts +6 -0
  53. package/dist/lib/output.js +15 -0
  54. package/dist/lib/parix-api.cjs +59 -0
  55. package/dist/lib/parix-api.d.cts +12 -0
  56. package/dist/lib/parix-api.d.ts +12 -0
  57. package/dist/lib/parix-api.js +55 -0
  58. package/dist/lib/session.cjs +80 -0
  59. package/dist/lib/session.d.cts +28 -0
  60. package/dist/lib/session.d.ts +28 -0
  61. package/dist/lib/session.js +74 -0
  62. package/dist/lib/tb-payloads.cjs +153 -0
  63. package/dist/lib/tb-payloads.d.cts +61 -0
  64. package/dist/lib/tb-payloads.d.ts +61 -0
  65. package/dist/lib/tb-payloads.js +144 -0
  66. package/package.json +74 -0
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createTbCommand = createTbCommand;
4
+ const prompts_1 = require("@clack/prompts");
5
+ const commander_1 = require("commander");
6
+ const output_1 = require("../lib/output.cjs");
7
+ const parix_api_1 = require("../lib/parix-api.cjs");
8
+ const tb_payloads_1 = require("../lib/tb-payloads.cjs");
9
+ function createTbCommand() {
10
+ const tb = new commander_1.Command('tb')
11
+ .description('Run TigerBeetle operations against a database')
12
+ .addHelpText('after', [
13
+ '',
14
+ 'Examples:',
15
+ ' parix tb create-accounts db_123 --id 1000 --ledger 1 --code 1',
16
+ ' parix tb create-transfers db_123 --id 2000 --from 1000 --to 1001 --amount 1 --ledger 1 --code 1',
17
+ ' parix tb lookup-accounts db_123 --id 1000 --id 1001',
18
+ ' parix tb query-transfers db_123 --limit 10 --json',
19
+ ' parix tb create-transfers db_123 --file ./transfer.json',
20
+ ].join('\n'));
21
+ addCreateAccountsCommand(tb);
22
+ addCreateTransfersCommand(tb);
23
+ addLookupCommand(tb, 'lookup-accounts', 'lookup_accounts', 'Lookup accounts');
24
+ addLookupCommand(tb, 'lookup-transfers', 'lookup_transfers', 'Lookup transfers');
25
+ addAccountFilterCommand(tb, 'get-account-transfers', 'get_account_transfers', 'Get account transfers');
26
+ addAccountFilterCommand(tb, 'get-account-balances', 'get_account_balances', 'Get account balances');
27
+ addQueryCommand(tb, 'query-accounts', 'query_accounts', 'Query accounts');
28
+ addQueryCommand(tb, 'query-transfers', 'query_transfers', 'Query transfers');
29
+ return tb;
30
+ }
31
+ function addCreateAccountsCommand(parent) {
32
+ parent
33
+ .command('create-accounts')
34
+ .description('Create TigerBeetle accounts')
35
+ .argument('<database-id>', 'Database id')
36
+ .option('-b, --base-url <url>', 'Parix base URL')
37
+ .option('--json', 'Print raw JSON')
38
+ .option('--payload <json>', 'Raw JSON payload override')
39
+ .option('--file <path>', 'Read JSON payload from file')
40
+ .option('--id <id>', 'Account id (defaults to generated id)')
41
+ .option('--ledger <ledger>', 'Ledger id')
42
+ .option('--code <code>', 'Account code')
43
+ .option('--flag <flag>', 'Account flag name or bitfield value', collectValues, [])
44
+ .option('--user-data-128 <value>', 'user_data_128')
45
+ .option('--user-data-64 <value>', 'user_data_64')
46
+ .option('--user-data-32 <value>', 'user_data_32')
47
+ .addHelpText('after', [
48
+ '',
49
+ 'Examples:',
50
+ ' parix tb create-accounts db_123 --id 1000 --ledger 1 --code 1',
51
+ ' parix tb create-accounts db_123 --payload "[{\"id\":\"1000\",\"ledger\":\"1\",\"code\":\"1\",\"flags\":\"0\"}]"',
52
+ ].join('\n'))
53
+ .action(async (databaseId, options) => {
54
+ const payload = await (0, tb_payloads_1.resolveTbPayload)(options, () => (0, tb_payloads_1.buildCreateAccountsPayload)({
55
+ code: options.code,
56
+ flags: options.flag,
57
+ id: options.id,
58
+ ledger: options.ledger,
59
+ userData128: options.userData128,
60
+ userData32: options.userData32,
61
+ userData64: options.userData64,
62
+ }));
63
+ await executeTbOperation(databaseId, 'create_accounts', payload, options);
64
+ });
65
+ }
66
+ function addCreateTransfersCommand(parent) {
67
+ parent
68
+ .command('create-transfers')
69
+ .description('Create TigerBeetle transfers')
70
+ .argument('<database-id>', 'Database id')
71
+ .option('-b, --base-url <url>', 'Parix base URL')
72
+ .option('--json', 'Print raw JSON')
73
+ .option('--payload <json>', 'Raw JSON payload override')
74
+ .option('--file <path>', 'Read JSON payload from file')
75
+ .option('--id <id>', 'Transfer id (defaults to generated id)')
76
+ .option('--from <id>', 'Debit account id')
77
+ .option('--to <id>', 'Credit account id')
78
+ .option('--amount <amount>', 'Transfer amount')
79
+ .option('--ledger <ledger>', 'Ledger id')
80
+ .option('--code <code>', 'Transfer code')
81
+ .option('--flag <flag>', 'Transfer flag name or bitfield value', collectValues, [])
82
+ .option('--pending-id <id>', 'Pending transfer id')
83
+ .option('--timeout <ms>', 'Timeout value')
84
+ .addHelpText('after', [
85
+ '',
86
+ 'Examples:',
87
+ ' parix tb create-transfers db_123 --id 2000 --from 1000 --to 1001 --amount 1 --ledger 1 --code 1',
88
+ ' parix tb create-transfers db_123 --file ./transfer.json',
89
+ ].join('\n'))
90
+ .action(async (databaseId, options) => {
91
+ const payload = await (0, tb_payloads_1.resolveTbPayload)(options, () => (0, tb_payloads_1.buildCreateTransfersPayload)({
92
+ amount: options.amount,
93
+ code: options.code,
94
+ creditAccountId: options.to,
95
+ debitAccountId: options.from,
96
+ flags: options.flag,
97
+ id: options.id,
98
+ ledger: options.ledger,
99
+ pendingId: options.pendingId,
100
+ timeout: options.timeout,
101
+ }));
102
+ await executeTbOperation(databaseId, 'create_transfers', payload, options);
103
+ });
104
+ }
105
+ function addLookupCommand(parent, name, operation, description) {
106
+ parent
107
+ .command(name)
108
+ .description(description)
109
+ .argument('<database-id>', 'Database id')
110
+ .option('-b, --base-url <url>', 'Parix base URL')
111
+ .option('--json', 'Print raw JSON')
112
+ .option('--payload <json>', 'Raw JSON payload override')
113
+ .option('--file <path>', 'Read JSON payload from file')
114
+ .option('--id <id>', 'ID to lookup', collectValues, [])
115
+ .option('--ids <ids>', 'Comma-separated IDs to lookup')
116
+ .addHelpText('after', [
117
+ '',
118
+ 'Examples:',
119
+ ` parix tb ${name} db_123 --id 1000 --id 1001`,
120
+ ` parix tb ${name} db_123 --ids 1000,1001`,
121
+ ].join('\n'))
122
+ .action(async (databaseId, options) => {
123
+ const payload = await (0, tb_payloads_1.resolveTbPayload)(options, () => (0, tb_payloads_1.buildLookupPayload)({
124
+ id: options.id,
125
+ ids: options.ids,
126
+ }));
127
+ await executeTbOperation(databaseId, operation, payload, options);
128
+ });
129
+ }
130
+ function addAccountFilterCommand(parent, name, operation, description) {
131
+ parent
132
+ .command(name)
133
+ .description(description)
134
+ .argument('<database-id>', 'Database id')
135
+ .option('-b, --base-url <url>', 'Parix base URL')
136
+ .option('--json', 'Print raw JSON')
137
+ .option('--payload <json>', 'Raw JSON payload override')
138
+ .option('--file <path>', 'Read JSON payload from file')
139
+ .option('--account-id <id>', 'Account id')
140
+ .option('--limit <limit>', 'Maximum row count', '100')
141
+ .option('--flag <flag>', 'Filter flag name or bitfield value', collectValues, [])
142
+ .option('--timestamp-min <value>', 'Minimum timestamp')
143
+ .option('--timestamp-max <value>', 'Maximum timestamp')
144
+ .option('--user-data-128 <value>', 'user_data_128')
145
+ .option('--user-data-64 <value>', 'user_data_64')
146
+ .option('--user-data-32 <value>', 'user_data_32')
147
+ .option('--code <code>', 'Filter code')
148
+ .addHelpText('after', [
149
+ '',
150
+ 'Examples:',
151
+ ` parix tb ${name} db_123 --account-id 1000 --limit 10 --flag debits`,
152
+ ` parix tb ${name} db_123 --file ./filter.json`,
153
+ ].join('\n'))
154
+ .action(async (databaseId, options) => {
155
+ const payload = await (0, tb_payloads_1.resolveTbPayload)(options, () => (0, tb_payloads_1.buildAccountFilterPayload)({
156
+ accountId: options.accountId,
157
+ code: options.code,
158
+ flags: options.flag,
159
+ limit: options.limit,
160
+ timestampMax: options.timestampMax,
161
+ timestampMin: options.timestampMin,
162
+ userData128: options.userData128,
163
+ userData32: options.userData32,
164
+ userData64: options.userData64,
165
+ }));
166
+ await executeTbOperation(databaseId, operation, payload, options);
167
+ });
168
+ }
169
+ function addQueryCommand(parent, name, operation, description) {
170
+ parent
171
+ .command(name)
172
+ .description(description)
173
+ .argument('<database-id>', 'Database id')
174
+ .option('-b, --base-url <url>', 'Parix base URL')
175
+ .option('--json', 'Print raw JSON')
176
+ .option('--payload <json>', 'Raw JSON payload override')
177
+ .option('--file <path>', 'Read JSON payload from file')
178
+ .option('--limit <limit>', 'Maximum row count', '100')
179
+ .option('--flag <flag>', 'Query flag name or bitfield value', collectValues, [])
180
+ .option('--ledger <ledger>', 'Filter ledger')
181
+ .option('--code <code>', 'Filter code')
182
+ .option('--timestamp-min <value>', 'Minimum timestamp')
183
+ .option('--timestamp-max <value>', 'Maximum timestamp')
184
+ .option('--user-data-128 <value>', 'user_data_128')
185
+ .option('--user-data-64 <value>', 'user_data_64')
186
+ .option('--user-data-32 <value>', 'user_data_32')
187
+ .addHelpText('after', [
188
+ '',
189
+ 'Examples:',
190
+ ` parix tb ${name} db_123 --limit 10`,
191
+ ` parix tb ${name} db_123 --ledger 1 --limit 10 --json`,
192
+ ].join('\n'))
193
+ .action(async (databaseId, options) => {
194
+ const payload = await (0, tb_payloads_1.resolveTbPayload)(options, () => (0, tb_payloads_1.buildQueryPayload)({
195
+ code: options.code,
196
+ flags: options.flag,
197
+ ledger: options.ledger,
198
+ limit: options.limit,
199
+ timestampMax: options.timestampMax,
200
+ timestampMin: options.timestampMin,
201
+ userData128: options.userData128,
202
+ userData32: options.userData32,
203
+ userData64: options.userData64,
204
+ }));
205
+ await executeTbOperation(databaseId, operation, payload, options);
206
+ });
207
+ }
208
+ async function executeTbOperation(databaseId, operation, payload, options) {
209
+ const response = await (0, parix_api_1.requestApiJson)({
210
+ baseUrl: options.baseUrl,
211
+ body: JSON.stringify(payload),
212
+ headers: {
213
+ 'content-type': 'application/json',
214
+ },
215
+ method: 'POST',
216
+ path: `/api/v1/databases/${encodeURIComponent(databaseId)}/tb/${operation}`,
217
+ });
218
+ if (options.json) {
219
+ (0, output_1.printJson)(response);
220
+ return;
221
+ }
222
+ (0, prompts_1.note)(response.docsUrl, 'TigerBeetle docs');
223
+ (0, prompts_1.note)([
224
+ `Operation: ${response.operationLabel}`,
225
+ `Database: ${response.databaseName}`,
226
+ `Provider: ${response.provider}`,
227
+ `Cluster ID: ${response.clusterId}`,
228
+ `Target host: ${response.targetHost}`,
229
+ `Replicas: ${String(response.replicaCount)}`,
230
+ `Mode: ${response.mode}`,
231
+ `Persisted: ${String(response.persisted)}`,
232
+ ].join('\n'), 'Execution');
233
+ if (Array.isArray(response.responsePayload)) {
234
+ (0, prompts_1.note)(String(response.responsePayload.length), 'Rows returned');
235
+ }
236
+ (0, output_1.printJson)(response.responsePayload);
237
+ (0, prompts_1.outro)(response.message);
238
+ }
239
+ function collectValues(value, previous) {
240
+ previous.push(value);
241
+ return previous;
242
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function createTbCommand(): Command;
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function createTbCommand(): Command;
@@ -0,0 +1,239 @@
1
+ import { note, outro } from '@clack/prompts';
2
+ import { Command } from 'commander';
3
+ import { printJson } from "../lib/output.js";
4
+ import { requestApiJson } from "../lib/parix-api.js";
5
+ import { buildAccountFilterPayload, buildCreateAccountsPayload, buildCreateTransfersPayload, buildLookupPayload, buildQueryPayload, resolveTbPayload, } from "../lib/tb-payloads.js";
6
+ export function createTbCommand() {
7
+ const tb = new Command('tb')
8
+ .description('Run TigerBeetle operations against a database')
9
+ .addHelpText('after', [
10
+ '',
11
+ 'Examples:',
12
+ ' parix tb create-accounts db_123 --id 1000 --ledger 1 --code 1',
13
+ ' parix tb create-transfers db_123 --id 2000 --from 1000 --to 1001 --amount 1 --ledger 1 --code 1',
14
+ ' parix tb lookup-accounts db_123 --id 1000 --id 1001',
15
+ ' parix tb query-transfers db_123 --limit 10 --json',
16
+ ' parix tb create-transfers db_123 --file ./transfer.json',
17
+ ].join('\n'));
18
+ addCreateAccountsCommand(tb);
19
+ addCreateTransfersCommand(tb);
20
+ addLookupCommand(tb, 'lookup-accounts', 'lookup_accounts', 'Lookup accounts');
21
+ addLookupCommand(tb, 'lookup-transfers', 'lookup_transfers', 'Lookup transfers');
22
+ addAccountFilterCommand(tb, 'get-account-transfers', 'get_account_transfers', 'Get account transfers');
23
+ addAccountFilterCommand(tb, 'get-account-balances', 'get_account_balances', 'Get account balances');
24
+ addQueryCommand(tb, 'query-accounts', 'query_accounts', 'Query accounts');
25
+ addQueryCommand(tb, 'query-transfers', 'query_transfers', 'Query transfers');
26
+ return tb;
27
+ }
28
+ function addCreateAccountsCommand(parent) {
29
+ parent
30
+ .command('create-accounts')
31
+ .description('Create TigerBeetle accounts')
32
+ .argument('<database-id>', 'Database id')
33
+ .option('-b, --base-url <url>', 'Parix base URL')
34
+ .option('--json', 'Print raw JSON')
35
+ .option('--payload <json>', 'Raw JSON payload override')
36
+ .option('--file <path>', 'Read JSON payload from file')
37
+ .option('--id <id>', 'Account id (defaults to generated id)')
38
+ .option('--ledger <ledger>', 'Ledger id')
39
+ .option('--code <code>', 'Account code')
40
+ .option('--flag <flag>', 'Account flag name or bitfield value', collectValues, [])
41
+ .option('--user-data-128 <value>', 'user_data_128')
42
+ .option('--user-data-64 <value>', 'user_data_64')
43
+ .option('--user-data-32 <value>', 'user_data_32')
44
+ .addHelpText('after', [
45
+ '',
46
+ 'Examples:',
47
+ ' parix tb create-accounts db_123 --id 1000 --ledger 1 --code 1',
48
+ ' parix tb create-accounts db_123 --payload "[{\"id\":\"1000\",\"ledger\":\"1\",\"code\":\"1\",\"flags\":\"0\"}]"',
49
+ ].join('\n'))
50
+ .action(async (databaseId, options) => {
51
+ const payload = await resolveTbPayload(options, () => buildCreateAccountsPayload({
52
+ code: options.code,
53
+ flags: options.flag,
54
+ id: options.id,
55
+ ledger: options.ledger,
56
+ userData128: options.userData128,
57
+ userData32: options.userData32,
58
+ userData64: options.userData64,
59
+ }));
60
+ await executeTbOperation(databaseId, 'create_accounts', payload, options);
61
+ });
62
+ }
63
+ function addCreateTransfersCommand(parent) {
64
+ parent
65
+ .command('create-transfers')
66
+ .description('Create TigerBeetle transfers')
67
+ .argument('<database-id>', 'Database id')
68
+ .option('-b, --base-url <url>', 'Parix base URL')
69
+ .option('--json', 'Print raw JSON')
70
+ .option('--payload <json>', 'Raw JSON payload override')
71
+ .option('--file <path>', 'Read JSON payload from file')
72
+ .option('--id <id>', 'Transfer id (defaults to generated id)')
73
+ .option('--from <id>', 'Debit account id')
74
+ .option('--to <id>', 'Credit account id')
75
+ .option('--amount <amount>', 'Transfer amount')
76
+ .option('--ledger <ledger>', 'Ledger id')
77
+ .option('--code <code>', 'Transfer code')
78
+ .option('--flag <flag>', 'Transfer flag name or bitfield value', collectValues, [])
79
+ .option('--pending-id <id>', 'Pending transfer id')
80
+ .option('--timeout <ms>', 'Timeout value')
81
+ .addHelpText('after', [
82
+ '',
83
+ 'Examples:',
84
+ ' parix tb create-transfers db_123 --id 2000 --from 1000 --to 1001 --amount 1 --ledger 1 --code 1',
85
+ ' parix tb create-transfers db_123 --file ./transfer.json',
86
+ ].join('\n'))
87
+ .action(async (databaseId, options) => {
88
+ const payload = await resolveTbPayload(options, () => buildCreateTransfersPayload({
89
+ amount: options.amount,
90
+ code: options.code,
91
+ creditAccountId: options.to,
92
+ debitAccountId: options.from,
93
+ flags: options.flag,
94
+ id: options.id,
95
+ ledger: options.ledger,
96
+ pendingId: options.pendingId,
97
+ timeout: options.timeout,
98
+ }));
99
+ await executeTbOperation(databaseId, 'create_transfers', payload, options);
100
+ });
101
+ }
102
+ function addLookupCommand(parent, name, operation, description) {
103
+ parent
104
+ .command(name)
105
+ .description(description)
106
+ .argument('<database-id>', 'Database id')
107
+ .option('-b, --base-url <url>', 'Parix base URL')
108
+ .option('--json', 'Print raw JSON')
109
+ .option('--payload <json>', 'Raw JSON payload override')
110
+ .option('--file <path>', 'Read JSON payload from file')
111
+ .option('--id <id>', 'ID to lookup', collectValues, [])
112
+ .option('--ids <ids>', 'Comma-separated IDs to lookup')
113
+ .addHelpText('after', [
114
+ '',
115
+ 'Examples:',
116
+ ` parix tb ${name} db_123 --id 1000 --id 1001`,
117
+ ` parix tb ${name} db_123 --ids 1000,1001`,
118
+ ].join('\n'))
119
+ .action(async (databaseId, options) => {
120
+ const payload = await resolveTbPayload(options, () => buildLookupPayload({
121
+ id: options.id,
122
+ ids: options.ids,
123
+ }));
124
+ await executeTbOperation(databaseId, operation, payload, options);
125
+ });
126
+ }
127
+ function addAccountFilterCommand(parent, name, operation, description) {
128
+ parent
129
+ .command(name)
130
+ .description(description)
131
+ .argument('<database-id>', 'Database id')
132
+ .option('-b, --base-url <url>', 'Parix base URL')
133
+ .option('--json', 'Print raw JSON')
134
+ .option('--payload <json>', 'Raw JSON payload override')
135
+ .option('--file <path>', 'Read JSON payload from file')
136
+ .option('--account-id <id>', 'Account id')
137
+ .option('--limit <limit>', 'Maximum row count', '100')
138
+ .option('--flag <flag>', 'Filter flag name or bitfield value', collectValues, [])
139
+ .option('--timestamp-min <value>', 'Minimum timestamp')
140
+ .option('--timestamp-max <value>', 'Maximum timestamp')
141
+ .option('--user-data-128 <value>', 'user_data_128')
142
+ .option('--user-data-64 <value>', 'user_data_64')
143
+ .option('--user-data-32 <value>', 'user_data_32')
144
+ .option('--code <code>', 'Filter code')
145
+ .addHelpText('after', [
146
+ '',
147
+ 'Examples:',
148
+ ` parix tb ${name} db_123 --account-id 1000 --limit 10 --flag debits`,
149
+ ` parix tb ${name} db_123 --file ./filter.json`,
150
+ ].join('\n'))
151
+ .action(async (databaseId, options) => {
152
+ const payload = await resolveTbPayload(options, () => buildAccountFilterPayload({
153
+ accountId: options.accountId,
154
+ code: options.code,
155
+ flags: options.flag,
156
+ limit: options.limit,
157
+ timestampMax: options.timestampMax,
158
+ timestampMin: options.timestampMin,
159
+ userData128: options.userData128,
160
+ userData32: options.userData32,
161
+ userData64: options.userData64,
162
+ }));
163
+ await executeTbOperation(databaseId, operation, payload, options);
164
+ });
165
+ }
166
+ function addQueryCommand(parent, name, operation, description) {
167
+ parent
168
+ .command(name)
169
+ .description(description)
170
+ .argument('<database-id>', 'Database id')
171
+ .option('-b, --base-url <url>', 'Parix base URL')
172
+ .option('--json', 'Print raw JSON')
173
+ .option('--payload <json>', 'Raw JSON payload override')
174
+ .option('--file <path>', 'Read JSON payload from file')
175
+ .option('--limit <limit>', 'Maximum row count', '100')
176
+ .option('--flag <flag>', 'Query flag name or bitfield value', collectValues, [])
177
+ .option('--ledger <ledger>', 'Filter ledger')
178
+ .option('--code <code>', 'Filter code')
179
+ .option('--timestamp-min <value>', 'Minimum timestamp')
180
+ .option('--timestamp-max <value>', 'Maximum timestamp')
181
+ .option('--user-data-128 <value>', 'user_data_128')
182
+ .option('--user-data-64 <value>', 'user_data_64')
183
+ .option('--user-data-32 <value>', 'user_data_32')
184
+ .addHelpText('after', [
185
+ '',
186
+ 'Examples:',
187
+ ` parix tb ${name} db_123 --limit 10`,
188
+ ` parix tb ${name} db_123 --ledger 1 --limit 10 --json`,
189
+ ].join('\n'))
190
+ .action(async (databaseId, options) => {
191
+ const payload = await resolveTbPayload(options, () => buildQueryPayload({
192
+ code: options.code,
193
+ flags: options.flag,
194
+ ledger: options.ledger,
195
+ limit: options.limit,
196
+ timestampMax: options.timestampMax,
197
+ timestampMin: options.timestampMin,
198
+ userData128: options.userData128,
199
+ userData32: options.userData32,
200
+ userData64: options.userData64,
201
+ }));
202
+ await executeTbOperation(databaseId, operation, payload, options);
203
+ });
204
+ }
205
+ async function executeTbOperation(databaseId, operation, payload, options) {
206
+ const response = await requestApiJson({
207
+ baseUrl: options.baseUrl,
208
+ body: JSON.stringify(payload),
209
+ headers: {
210
+ 'content-type': 'application/json',
211
+ },
212
+ method: 'POST',
213
+ path: `/api/v1/databases/${encodeURIComponent(databaseId)}/tb/${operation}`,
214
+ });
215
+ if (options.json) {
216
+ printJson(response);
217
+ return;
218
+ }
219
+ note(response.docsUrl, 'TigerBeetle docs');
220
+ note([
221
+ `Operation: ${response.operationLabel}`,
222
+ `Database: ${response.databaseName}`,
223
+ `Provider: ${response.provider}`,
224
+ `Cluster ID: ${response.clusterId}`,
225
+ `Target host: ${response.targetHost}`,
226
+ `Replicas: ${String(response.replicaCount)}`,
227
+ `Mode: ${response.mode}`,
228
+ `Persisted: ${String(response.persisted)}`,
229
+ ].join('\n'), 'Execution');
230
+ if (Array.isArray(response.responsePayload)) {
231
+ note(String(response.responsePayload.length), 'Rows returned');
232
+ }
233
+ printJson(response.responsePayload);
234
+ outro(response.message);
235
+ }
236
+ function collectValues(value, previous) {
237
+ previous.push(value);
238
+ return previous;
239
+ }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApiClient = void 0;
4
+ const oauth_session_1 = require("./oauth-session.cjs");
5
+ const TRAILING_SLASHES_REGEX = /\/+$/;
6
+ class ApiClient {
7
+ session;
8
+ constructor(options) {
9
+ this.session = options.session;
10
+ }
11
+ async request(pathname, init = {}) {
12
+ this.session = await (0, oauth_session_1.ensureFreshSession)(this.session);
13
+ const url = toRequestUrl(pathname, this.session.baseUrl);
14
+ const headers = new Headers(init.headers);
15
+ headers.set('authorization', `Bearer ${this.session.accessToken}`);
16
+ const response = await fetch(url, {
17
+ ...init,
18
+ headers,
19
+ });
20
+ if (response.status !== 401) {
21
+ return response;
22
+ }
23
+ this.session = await (0, oauth_session_1.ensureFreshSession)({
24
+ ...this.session,
25
+ accessTokenExpiresAt: new Date(0).toISOString(),
26
+ });
27
+ const retryHeaders = new Headers(init.headers);
28
+ retryHeaders.set('authorization', `Bearer ${this.session.accessToken}`);
29
+ return fetch(url, {
30
+ ...init,
31
+ headers: retryHeaders,
32
+ });
33
+ }
34
+ }
35
+ exports.ApiClient = ApiClient;
36
+ function toRequestUrl(pathname, baseUrl) {
37
+ if (pathname.startsWith('http://') || pathname.startsWith('https://')) {
38
+ return pathname;
39
+ }
40
+ return new URL(pathname, `${trimTrailingSlash(baseUrl)}/`).toString();
41
+ }
42
+ function trimTrailingSlash(value) {
43
+ return value.replace(TRAILING_SLASHES_REGEX, '');
44
+ }
@@ -0,0 +1,10 @@
1
+ import type { StoredSession } from "./session.cjs";
2
+ interface ApiClientOptions {
3
+ session: StoredSession;
4
+ }
5
+ export declare class ApiClient {
6
+ private session;
7
+ constructor(options: ApiClientOptions);
8
+ request(pathname: string, init?: RequestInit): Promise<Response>;
9
+ }
10
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { StoredSession } from "./session.js";
2
+ interface ApiClientOptions {
3
+ session: StoredSession;
4
+ }
5
+ export declare class ApiClient {
6
+ private session;
7
+ constructor(options: ApiClientOptions);
8
+ request(pathname: string, init?: RequestInit): Promise<Response>;
9
+ }
10
+ export {};
@@ -0,0 +1,40 @@
1
+ import { ensureFreshSession } from "./oauth-session.js";
2
+ const TRAILING_SLASHES_REGEX = /\/+$/;
3
+ export class ApiClient {
4
+ session;
5
+ constructor(options) {
6
+ this.session = options.session;
7
+ }
8
+ async request(pathname, init = {}) {
9
+ this.session = await ensureFreshSession(this.session);
10
+ const url = toRequestUrl(pathname, this.session.baseUrl);
11
+ const headers = new Headers(init.headers);
12
+ headers.set('authorization', `Bearer ${this.session.accessToken}`);
13
+ const response = await fetch(url, {
14
+ ...init,
15
+ headers,
16
+ });
17
+ if (response.status !== 401) {
18
+ return response;
19
+ }
20
+ this.session = await ensureFreshSession({
21
+ ...this.session,
22
+ accessTokenExpiresAt: new Date(0).toISOString(),
23
+ });
24
+ const retryHeaders = new Headers(init.headers);
25
+ retryHeaders.set('authorization', `Bearer ${this.session.accessToken}`);
26
+ return fetch(url, {
27
+ ...init,
28
+ headers: retryHeaders,
29
+ });
30
+ }
31
+ }
32
+ function toRequestUrl(pathname, baseUrl) {
33
+ if (pathname.startsWith('http://') || pathname.startsWith('https://')) {
34
+ return pathname;
35
+ }
36
+ return new URL(pathname, `${trimTrailingSlash(baseUrl)}/`).toString();
37
+ }
38
+ function trimTrailingSlash(value) {
39
+ return value.replace(TRAILING_SLASHES_REGEX, '');
40
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LOGIN_TIMEOUT_MS = exports.DEFAULT_BASE_URL = void 0;
4
+ exports.resolveBaseUrl = resolveBaseUrl;
5
+ exports.trimTrailingSlash = trimTrailingSlash;
6
+ exports.parsePortOption = parsePortOption;
7
+ const TRAILING_SLASHES_REGEX = /\/+$/;
8
+ exports.DEFAULT_BASE_URL = 'https://parix.io';
9
+ exports.LOGIN_TIMEOUT_MS = 5 * 60 * 1000;
10
+ function resolveBaseUrl(input, storedSession, options = {}) {
11
+ const storedSessionBaseUrl = options.useStoredSession === false ? undefined : storedSession?.baseUrl;
12
+ const value = input ?? storedSessionBaseUrl ?? process.env.PARIX_BASE_URL ?? exports.DEFAULT_BASE_URL;
13
+ return trimTrailingSlash(new URL(value).toString());
14
+ }
15
+ function trimTrailingSlash(value) {
16
+ return value.replace(TRAILING_SLASHES_REGEX, '');
17
+ }
18
+ function parsePortOption(value) {
19
+ const parsed = Number.parseInt(value, 10);
20
+ if (!Number.isInteger(parsed) || parsed < 0 || parsed > 65535) {
21
+ throw new Error(`Invalid port: ${value}`);
22
+ }
23
+ return parsed;
24
+ }
@@ -0,0 +1,10 @@
1
+ import type { StoredSession } from "./session.cjs";
2
+ export declare const DEFAULT_BASE_URL = "https://parix.io";
3
+ export declare const LOGIN_TIMEOUT_MS: number;
4
+ interface ResolveBaseUrlOptions {
5
+ useStoredSession?: boolean;
6
+ }
7
+ export declare function resolveBaseUrl(input: string | undefined, storedSession?: StoredSession | null, options?: ResolveBaseUrlOptions): string;
8
+ export declare function trimTrailingSlash(value: string): string;
9
+ export declare function parsePortOption(value: string): number;
10
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { StoredSession } from "./session.js";
2
+ export declare const DEFAULT_BASE_URL = "https://parix.io";
3
+ export declare const LOGIN_TIMEOUT_MS: number;
4
+ interface ResolveBaseUrlOptions {
5
+ useStoredSession?: boolean;
6
+ }
7
+ export declare function resolveBaseUrl(input: string | undefined, storedSession?: StoredSession | null, options?: ResolveBaseUrlOptions): string;
8
+ export declare function trimTrailingSlash(value: string): string;
9
+ export declare function parsePortOption(value: string): number;
10
+ export {};
@@ -0,0 +1,18 @@
1
+ const TRAILING_SLASHES_REGEX = /\/+$/;
2
+ export const DEFAULT_BASE_URL = 'https://parix.io';
3
+ export const LOGIN_TIMEOUT_MS = 5 * 60 * 1000;
4
+ export function resolveBaseUrl(input, storedSession, options = {}) {
5
+ const storedSessionBaseUrl = options.useStoredSession === false ? undefined : storedSession?.baseUrl;
6
+ const value = input ?? storedSessionBaseUrl ?? process.env.PARIX_BASE_URL ?? DEFAULT_BASE_URL;
7
+ return trimTrailingSlash(new URL(value).toString());
8
+ }
9
+ export function trimTrailingSlash(value) {
10
+ return value.replace(TRAILING_SLASHES_REGEX, '');
11
+ }
12
+ export function parsePortOption(value) {
13
+ const parsed = Number.parseInt(value, 10);
14
+ if (!Number.isInteger(parsed) || parsed < 0 || parsed > 65535) {
15
+ throw new Error(`Invalid port: ${value}`);
16
+ }
17
+ return parsed;
18
+ }