@motherbase/cli 0.2.5 → 0.2.6
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.
- package/LICENSE +21 -0
- package/README.md +247 -247
- package/bin/motherbase.js +10 -10
- package/package.json +35 -26
- package/src/api.js +233 -241
- package/src/commands/_util.js +106 -93
- package/src/commands/backups.js +16 -16
- package/src/commands/branches.js +113 -113
- package/src/commands/completion.js +90 -90
- package/src/commands/config.js +47 -47
- package/src/commands/cron.js +65 -65
- package/src/commands/db-catalog.js +326 -326
- package/src/commands/db.js +103 -103
- package/src/commands/domains.js +124 -124
- package/src/commands/functions.js +304 -297
- package/src/commands/gen.js +172 -172
- package/src/commands/import.js +55 -55
- package/src/commands/index.js +85 -85
- package/src/commands/inspect.js +178 -178
- package/src/commands/keys.js +72 -72
- package/src/commands/link.js +35 -35
- package/src/commands/local.js +294 -273
- package/src/commands/login.js +39 -39
- package/src/commands/logout.js +16 -16
- package/src/commands/mcp.js +61 -61
- package/src/commands/migrate.js +207 -179
- package/src/commands/migration.js +108 -108
- package/src/commands/network.js +83 -83
- package/src/commands/orgs.js +40 -40
- package/src/commands/postgres-config.js +113 -113
- package/src/commands/projects.js +130 -130
- package/src/commands/queues.js +133 -133
- package/src/commands/realtime.js +35 -35
- package/src/commands/rls.js +176 -176
- package/src/commands/secrets.js +66 -66
- package/src/commands/signing.js +130 -130
- package/src/commands/snippets.js +44 -44
- package/src/commands/status.js +42 -42
- package/src/commands/storage.js +261 -261
- package/src/commands/test.js +9 -9
- package/src/commands/unlink.js +15 -15
- package/src/commands/users.js +142 -142
- package/src/commands/vault.js +82 -82
- package/src/commands/webhooks.js +62 -62
- package/src/commands/whoami.js +20 -20
- package/src/commands/wrappers.js +150 -150
- package/src/config.js +98 -98
- package/src/context.js +106 -102
- package/src/docs.js +68 -0
- package/src/edge-templates.js +194 -194
- package/src/format.js +92 -92
- package/src/inspect/csv.js +22 -22
- package/src/inspect/queries.js +562 -562
- package/src/main.js +224 -194
- package/src/mcp/platform-tools.js +233 -233
- package/src/mcp/protocol.js +152 -149
- package/src/mcp/storage-tools.js +93 -93
- package/src/mcp/tools.js +478 -478
- package/src/migration/commands.js +375 -375
- package/src/migration/files.js +245 -245
- package/src/prompt.js +91 -91
- package/src/storage/remote.js +62 -62
- package/src/ui.js +111 -111
package/src/commands/queues.js
CHANGED
|
@@ -1,133 +1,133 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const api = require('../api');
|
|
4
|
-
const { output, requireArg } = require('./_util');
|
|
5
|
-
const { CliError } = require('../context');
|
|
6
|
-
|
|
7
|
-
const enc = encodeURIComponent;
|
|
8
|
-
|
|
9
|
-
function int(flag, name) {
|
|
10
|
-
if (flag === undefined) return undefined;
|
|
11
|
-
const n = Number(flag);
|
|
12
|
-
if (!Number.isInteger(n) || n < 0) throw new CliError(`--${name} must be a non-negative integer`);
|
|
13
|
-
return n;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function parseMessage(raw) {
|
|
17
|
-
try {
|
|
18
|
-
return JSON.parse(requireArg(raw, 'json'));
|
|
19
|
-
} catch (err) {
|
|
20
|
-
if (err instanceof CliError) throw err;
|
|
21
|
-
throw new CliError('the message must be valid JSON, e.g. \'{"task":"resize"}\'');
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const subcommands = {
|
|
26
|
-
list: {
|
|
27
|
-
summary: 'List queues with their depth',
|
|
28
|
-
usage: 'motherbase queues list',
|
|
29
|
-
async run(ctx) {
|
|
30
|
-
const data = await api.adminRequest(ctx, 'GET', '/queues');
|
|
31
|
-
const queues = (data && data.queues) || [];
|
|
32
|
-
output(ctx, data, (_d, ui) =>
|
|
33
|
-
ui.table(queues, [
|
|
34
|
-
{ key: 'name', label: 'NAME' },
|
|
35
|
-
{ key: 'type', label: 'TYPE' },
|
|
36
|
-
{ key: 'length', label: 'MESSAGES' },
|
|
37
|
-
{ key: 'visibleLength', label: 'VISIBLE' },
|
|
38
|
-
{ key: 'totalMessages', label: 'TOTAL' },
|
|
39
|
-
]),
|
|
40
|
-
);
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
enable: {
|
|
44
|
-
summary: 'Install pgmq for this project',
|
|
45
|
-
usage: 'motherbase queues enable',
|
|
46
|
-
async run(ctx) {
|
|
47
|
-
const data = await api.adminRequest(ctx, 'POST', '/queues/enable');
|
|
48
|
-
output(ctx, data, (_d, ui) => ui.success('Queues enabled'));
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
expose: {
|
|
52
|
-
summary: 'Expose queues to the client SDK through pgmq_public (or hide them)',
|
|
53
|
-
usage: 'motherbase queues expose <true|false>',
|
|
54
|
-
async run(ctx, args) {
|
|
55
|
-
const value = requireArg(args[0], 'true|false');
|
|
56
|
-
if (value !== 'true' && value !== 'false') throw new CliError('expected true or false');
|
|
57
|
-
const data = await api.adminRequest(ctx, 'PUT', '/queues/expose', { body: { enabled: value === 'true' } });
|
|
58
|
-
output(ctx, data, (_d, ui) => ui.success(`Queues ${value === 'true' ? 'exposed' : 'hidden'}`));
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
create: {
|
|
62
|
-
summary: 'Create a queue',
|
|
63
|
-
usage: 'motherbase queues create <name> [--type basic|unlogged|partitioned] [--rls true|false]',
|
|
64
|
-
async run(ctx, args, flags) {
|
|
65
|
-
const name = requireArg(args[0], 'name');
|
|
66
|
-
const body = { name };
|
|
67
|
-
if (flags.type) body.type = flags.type;
|
|
68
|
-
if (flags.rls !== undefined) body.rls = flags.rls === true || flags.rls === 'true';
|
|
69
|
-
const data = await api.adminRequest(ctx, 'POST', '/queues', { body });
|
|
70
|
-
output(ctx, data, (_d, ui) => ui.success(`Created queue ${name}`));
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
drop: {
|
|
74
|
-
summary: 'Drop a queue and its messages',
|
|
75
|
-
usage: 'motherbase queues drop <name>',
|
|
76
|
-
async run(ctx, args) {
|
|
77
|
-
const name = requireArg(args[0], 'name');
|
|
78
|
-
const data = await api.adminRequest(ctx, 'DELETE', `/queues/${enc(name)}`);
|
|
79
|
-
output(ctx, data, (_d, ui) => ui.success(`Dropped queue ${name}`));
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
send: {
|
|
83
|
-
summary: 'Send a JSON message',
|
|
84
|
-
usage: "motherbase queues send <name> '<json>' [--delay seconds]",
|
|
85
|
-
async run(ctx, args, flags) {
|
|
86
|
-
const name = requireArg(args[0], 'name');
|
|
87
|
-
const body = { message: parseMessage(args[1]) };
|
|
88
|
-
const delay = int(flags.delay, 'delay');
|
|
89
|
-
if (delay !== undefined) body.delay = delay;
|
|
90
|
-
const data = await api.adminRequest(ctx, 'POST', `/queues/${enc(name)}/messages`, { body });
|
|
91
|
-
output(ctx, data, (d, ui) => ui.success(`Sent message ${((d && d.msgIds) || []).join(', ')}`));
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
read: {
|
|
95
|
-
summary: 'Read messages, hiding them from other readers for the visibility timeout',
|
|
96
|
-
usage: 'motherbase queues read <name> [--qty 1] [--vt 30]',
|
|
97
|
-
async run(ctx, args, flags) {
|
|
98
|
-
const name = requireArg(args[0], 'name');
|
|
99
|
-
const body = {};
|
|
100
|
-
const qty = int(flags.qty, 'qty');
|
|
101
|
-
const vt = int(flags.vt, 'vt');
|
|
102
|
-
if (qty !== undefined) body.qty = qty;
|
|
103
|
-
if (vt !== undefined) body.vt = vt;
|
|
104
|
-
const data = await api.adminRequest(ctx, 'POST', `/queues/${enc(name)}/read`, { body });
|
|
105
|
-
output(ctx, data, (d, ui) => ui.json((d && d.messages) || []));
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
archive: {
|
|
109
|
-
summary: 'Move a message to the archive',
|
|
110
|
-
usage: 'motherbase queues archive <name> <msg-id>',
|
|
111
|
-
async run(ctx, args) {
|
|
112
|
-
const name = requireArg(args[0], 'name');
|
|
113
|
-
const id = requireArg(args[1], 'msg-id');
|
|
114
|
-
const data = await api.adminRequest(ctx, 'POST', `/queues/${enc(name)}/messages/${enc(id)}/archive`);
|
|
115
|
-
output(ctx, data, (_d, ui) => ui.success(`Archived message ${id}`));
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
purge: {
|
|
119
|
-
summary: 'Delete every message in a queue',
|
|
120
|
-
usage: 'motherbase queues purge <name>',
|
|
121
|
-
async run(ctx, args) {
|
|
122
|
-
const name = requireArg(args[0], 'name');
|
|
123
|
-
const data = await api.adminRequest(ctx, 'POST', `/queues/${enc(name)}/purge`);
|
|
124
|
-
output(ctx, data, (d, ui) => ui.success(`Purged ${(d && d.purged) ?? 0} messages from ${name}`));
|
|
125
|
-
},
|
|
126
|
-
},
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
module.exports = {
|
|
130
|
-
summary: 'Message queues (pgmq)',
|
|
131
|
-
usage: 'motherbase queues <list|enable|expose|create|drop|send|read|archive|purge> ...',
|
|
132
|
-
subcommands,
|
|
133
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const api = require('../api');
|
|
4
|
+
const { output, requireArg } = require('./_util');
|
|
5
|
+
const { CliError } = require('../context');
|
|
6
|
+
|
|
7
|
+
const enc = encodeURIComponent;
|
|
8
|
+
|
|
9
|
+
function int(flag, name) {
|
|
10
|
+
if (flag === undefined) return undefined;
|
|
11
|
+
const n = Number(flag);
|
|
12
|
+
if (!Number.isInteger(n) || n < 0) throw new CliError(`--${name} must be a non-negative integer`);
|
|
13
|
+
return n;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function parseMessage(raw) {
|
|
17
|
+
try {
|
|
18
|
+
return JSON.parse(requireArg(raw, 'json'));
|
|
19
|
+
} catch (err) {
|
|
20
|
+
if (err instanceof CliError) throw err;
|
|
21
|
+
throw new CliError('the message must be valid JSON, e.g. \'{"task":"resize"}\'');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const subcommands = {
|
|
26
|
+
list: {
|
|
27
|
+
summary: 'List queues with their depth',
|
|
28
|
+
usage: 'motherbase queues list',
|
|
29
|
+
async run(ctx) {
|
|
30
|
+
const data = await api.adminRequest(ctx, 'GET', '/queues');
|
|
31
|
+
const queues = (data && data.queues) || [];
|
|
32
|
+
output(ctx, data, (_d, ui) =>
|
|
33
|
+
ui.table(queues, [
|
|
34
|
+
{ key: 'name', label: 'NAME' },
|
|
35
|
+
{ key: 'type', label: 'TYPE' },
|
|
36
|
+
{ key: 'length', label: 'MESSAGES' },
|
|
37
|
+
{ key: 'visibleLength', label: 'VISIBLE' },
|
|
38
|
+
{ key: 'totalMessages', label: 'TOTAL' },
|
|
39
|
+
]),
|
|
40
|
+
);
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
enable: {
|
|
44
|
+
summary: 'Install pgmq for this project',
|
|
45
|
+
usage: 'motherbase queues enable',
|
|
46
|
+
async run(ctx) {
|
|
47
|
+
const data = await api.adminRequest(ctx, 'POST', '/queues/enable');
|
|
48
|
+
output(ctx, data, (_d, ui) => ui.success('Queues enabled'));
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
expose: {
|
|
52
|
+
summary: 'Expose queues to the client SDK through pgmq_public (or hide them)',
|
|
53
|
+
usage: 'motherbase queues expose <true|false>',
|
|
54
|
+
async run(ctx, args) {
|
|
55
|
+
const value = requireArg(args[0], 'true|false');
|
|
56
|
+
if (value !== 'true' && value !== 'false') throw new CliError('expected true or false');
|
|
57
|
+
const data = await api.adminRequest(ctx, 'PUT', '/queues/expose', { body: { enabled: value === 'true' } });
|
|
58
|
+
output(ctx, data, (_d, ui) => ui.success(`Queues ${value === 'true' ? 'exposed' : 'hidden'}`));
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
create: {
|
|
62
|
+
summary: 'Create a queue',
|
|
63
|
+
usage: 'motherbase queues create <name> [--type basic|unlogged|partitioned] [--rls true|false]',
|
|
64
|
+
async run(ctx, args, flags) {
|
|
65
|
+
const name = requireArg(args[0], 'name');
|
|
66
|
+
const body = { name };
|
|
67
|
+
if (flags.type) body.type = flags.type;
|
|
68
|
+
if (flags.rls !== undefined) body.rls = flags.rls === true || flags.rls === 'true';
|
|
69
|
+
const data = await api.adminRequest(ctx, 'POST', '/queues', { body });
|
|
70
|
+
output(ctx, data, (_d, ui) => ui.success(`Created queue ${name}`));
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
drop: {
|
|
74
|
+
summary: 'Drop a queue and its messages',
|
|
75
|
+
usage: 'motherbase queues drop <name>',
|
|
76
|
+
async run(ctx, args) {
|
|
77
|
+
const name = requireArg(args[0], 'name');
|
|
78
|
+
const data = await api.adminRequest(ctx, 'DELETE', `/queues/${enc(name)}`);
|
|
79
|
+
output(ctx, data, (_d, ui) => ui.success(`Dropped queue ${name}`));
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
send: {
|
|
83
|
+
summary: 'Send a JSON message',
|
|
84
|
+
usage: "motherbase queues send <name> '<json>' [--delay seconds]",
|
|
85
|
+
async run(ctx, args, flags) {
|
|
86
|
+
const name = requireArg(args[0], 'name');
|
|
87
|
+
const body = { message: parseMessage(args[1]) };
|
|
88
|
+
const delay = int(flags.delay, 'delay');
|
|
89
|
+
if (delay !== undefined) body.delay = delay;
|
|
90
|
+
const data = await api.adminRequest(ctx, 'POST', `/queues/${enc(name)}/messages`, { body });
|
|
91
|
+
output(ctx, data, (d, ui) => ui.success(`Sent message ${((d && d.msgIds) || []).join(', ')}`));
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
read: {
|
|
95
|
+
summary: 'Read messages, hiding them from other readers for the visibility timeout',
|
|
96
|
+
usage: 'motherbase queues read <name> [--qty 1] [--vt 30]',
|
|
97
|
+
async run(ctx, args, flags) {
|
|
98
|
+
const name = requireArg(args[0], 'name');
|
|
99
|
+
const body = {};
|
|
100
|
+
const qty = int(flags.qty, 'qty');
|
|
101
|
+
const vt = int(flags.vt, 'vt');
|
|
102
|
+
if (qty !== undefined) body.qty = qty;
|
|
103
|
+
if (vt !== undefined) body.vt = vt;
|
|
104
|
+
const data = await api.adminRequest(ctx, 'POST', `/queues/${enc(name)}/read`, { body });
|
|
105
|
+
output(ctx, data, (d, ui) => ui.json((d && d.messages) || []));
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
archive: {
|
|
109
|
+
summary: 'Move a message to the archive',
|
|
110
|
+
usage: 'motherbase queues archive <name> <msg-id>',
|
|
111
|
+
async run(ctx, args) {
|
|
112
|
+
const name = requireArg(args[0], 'name');
|
|
113
|
+
const id = requireArg(args[1], 'msg-id');
|
|
114
|
+
const data = await api.adminRequest(ctx, 'POST', `/queues/${enc(name)}/messages/${enc(id)}/archive`);
|
|
115
|
+
output(ctx, data, (_d, ui) => ui.success(`Archived message ${id}`));
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
purge: {
|
|
119
|
+
summary: 'Delete every message in a queue',
|
|
120
|
+
usage: 'motherbase queues purge <name>',
|
|
121
|
+
async run(ctx, args) {
|
|
122
|
+
const name = requireArg(args[0], 'name');
|
|
123
|
+
const data = await api.adminRequest(ctx, 'POST', `/queues/${enc(name)}/purge`);
|
|
124
|
+
output(ctx, data, (d, ui) => ui.success(`Purged ${(d && d.purged) ?? 0} messages from ${name}`));
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
module.exports = {
|
|
130
|
+
summary: 'Message queues (pgmq)',
|
|
131
|
+
usage: 'motherbase queues <list|enable|expose|create|drop|send|read|archive|purge> ...',
|
|
132
|
+
subcommands,
|
|
133
|
+
};
|
package/src/commands/realtime.js
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const api = require('../api');
|
|
4
|
-
const { output } = require('./_util');
|
|
5
|
-
|
|
6
|
-
const subcommands = {
|
|
7
|
-
config: {
|
|
8
|
-
summary: 'Show realtime config, or set enabled models with --models a,b,c',
|
|
9
|
-
usage: 'motherbase realtime config [--models a,b,c]',
|
|
10
|
-
async run(ctx, args, flags) {
|
|
11
|
-
if (flags.models !== undefined) {
|
|
12
|
-
const models = String(flags.models).split(',').map(s => s.trim()).filter(Boolean);
|
|
13
|
-
const data = await api.adminRequest(ctx, 'PATCH', '/realtime/config', { body: { models } });
|
|
14
|
-
output(ctx, data, (d, ui) => ui.success(`Enabled models: ${(d && d.models ? d.models : models).join(', ') || '(none)'}`));
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
const data = await api.adminRequest(ctx, 'GET', '/realtime/config');
|
|
18
|
-
output(ctx, data, (d, ui) => ui.keyValue(d || {}));
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
channels: {
|
|
22
|
-
summary: 'List active realtime channels',
|
|
23
|
-
usage: 'motherbase realtime channels',
|
|
24
|
-
async run(ctx) {
|
|
25
|
-
const data = await api.adminRequest(ctx, 'GET', '/realtime/channels');
|
|
26
|
-
output(ctx, data, (d, ui) => ui.json((d && d.channels) || d));
|
|
27
|
-
},
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
module.exports = {
|
|
32
|
-
summary: 'Realtime configuration and channels',
|
|
33
|
-
usage: 'motherbase realtime <config|channels> ...',
|
|
34
|
-
subcommands,
|
|
35
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const api = require('../api');
|
|
4
|
+
const { output } = require('./_util');
|
|
5
|
+
|
|
6
|
+
const subcommands = {
|
|
7
|
+
config: {
|
|
8
|
+
summary: 'Show realtime config, or set enabled models with --models a,b,c',
|
|
9
|
+
usage: 'motherbase realtime config [--models a,b,c]',
|
|
10
|
+
async run(ctx, args, flags) {
|
|
11
|
+
if (flags.models !== undefined) {
|
|
12
|
+
const models = String(flags.models).split(',').map(s => s.trim()).filter(Boolean);
|
|
13
|
+
const data = await api.adminRequest(ctx, 'PATCH', '/realtime/config', { body: { models } });
|
|
14
|
+
output(ctx, data, (d, ui) => ui.success(`Enabled models: ${(d && d.models ? d.models : models).join(', ') || '(none)'}`));
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const data = await api.adminRequest(ctx, 'GET', '/realtime/config');
|
|
18
|
+
output(ctx, data, (d, ui) => ui.keyValue(d || {}));
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
channels: {
|
|
22
|
+
summary: 'List active realtime channels',
|
|
23
|
+
usage: 'motherbase realtime channels',
|
|
24
|
+
async run(ctx) {
|
|
25
|
+
const data = await api.adminRequest(ctx, 'GET', '/realtime/channels');
|
|
26
|
+
output(ctx, data, (d, ui) => ui.json((d && d.channels) || d));
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
module.exports = {
|
|
32
|
+
summary: 'Realtime configuration and channels',
|
|
33
|
+
usage: 'motherbase realtime <config|channels> ...',
|
|
34
|
+
subcommands,
|
|
35
|
+
};
|