@motherbase/cli 0.2.4 → 0.2.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 (47) hide show
  1. package/README.md +247 -134
  2. package/package.json +2 -2
  3. package/src/api.js +14 -2
  4. package/src/commands/_util.js +49 -6
  5. package/src/commands/backups.js +16 -0
  6. package/src/commands/branches.js +113 -0
  7. package/src/commands/completion.js +90 -0
  8. package/src/commands/db-catalog.js +326 -0
  9. package/src/commands/db.js +16 -5
  10. package/src/commands/domains.js +124 -0
  11. package/src/commands/functions.js +297 -274
  12. package/src/commands/gen.js +172 -126
  13. package/src/commands/import.js +23 -3
  14. package/src/commands/index.js +27 -6
  15. package/src/commands/inspect.js +142 -5
  16. package/src/commands/keys.js +72 -72
  17. package/src/commands/local.js +273 -273
  18. package/src/commands/mcp.js +61 -43
  19. package/src/commands/migrate.js +179 -0
  20. package/src/commands/migration.js +81 -6
  21. package/src/commands/network.js +83 -0
  22. package/src/commands/orgs.js +40 -0
  23. package/src/commands/postgres-config.js +113 -0
  24. package/src/commands/projects.js +8 -3
  25. package/src/commands/queues.js +133 -0
  26. package/src/commands/secrets.js +29 -8
  27. package/src/commands/signing.js +130 -0
  28. package/src/commands/snippets.js +44 -0
  29. package/src/commands/storage.js +192 -44
  30. package/src/commands/test.js +9 -0
  31. package/src/commands/users.js +30 -1
  32. package/src/commands/vault.js +82 -0
  33. package/src/commands/wrappers.js +150 -0
  34. package/src/edge-templates.js +194 -0
  35. package/src/format.js +92 -0
  36. package/src/inspect/csv.js +22 -0
  37. package/src/inspect/queries.js +562 -0
  38. package/src/main.js +41 -7
  39. package/src/mcp/platform-tools.js +233 -0
  40. package/src/mcp/protocol.js +149 -149
  41. package/src/mcp/storage-tools.js +93 -0
  42. package/src/mcp/tools.js +478 -166
  43. package/src/migration/commands.js +375 -0
  44. package/src/migration/files.js +245 -0
  45. package/src/prompt.js +1 -1
  46. package/src/storage/remote.js +62 -0
  47. package/src/commands/migrations.js +0 -85
@@ -0,0 +1,62 @@
1
+ 'use strict';
2
+
3
+ // Storage paths in the Supabase CLI's form: `ss:///<bucket>/<key>`. Anything
4
+ // else is a local path. Kept free of I/O so the path rules can be tested alone.
5
+
6
+ const path = require('path');
7
+ const { CliError } = require('../context');
8
+
9
+ const SCHEME = 'ss:///';
10
+
11
+ const isRemote = value => typeof value === 'string' && value.startsWith('ss://');
12
+
13
+ /** `ss:///bucket/a/b` → `{ bucket: 'bucket', key: 'a/b' }`; `ss:///` → `{ bucket: '', key: '' }`. */
14
+ function parseRemote(value) {
15
+ if (!value.startsWith(SCHEME)) {
16
+ throw new CliError(`Storage paths look like ${SCHEME}<bucket>/<key>, got "${value}".`);
17
+ }
18
+ const [bucket = '', ...rest] = value.slice(SCHEME.length).split('/');
19
+ return { bucket, key: rest.join('/') };
20
+ }
21
+
22
+ function requireBucket(remote, value) {
23
+ if (!remote.bucket) throw new CliError(`"${value}" names no bucket.`);
24
+ return remote;
25
+ }
26
+
27
+ /** A key as a URL path: every segment encoded, the slashes between them kept. */
28
+ const encodeKey = key => key.split('/').map(encodeURIComponent).join('/');
29
+
30
+ /** `a/b/` and `a/b` both mean the prefix `a/b/`; the empty prefix is the bucket root. */
31
+ const asPrefix = key => (key ? key.replace(/\/*$/, '/') : '');
32
+
33
+ /**
34
+ * One directory level of a listing, as `ls` shows it: the objects directly
35
+ * under `prefix`, and each deeper key collapsed into its first folder (with a
36
+ * trailing slash), deduplicated, in order.
37
+ */
38
+ function childrenOf(keys, prefix) {
39
+ const seen = new Set();
40
+ for (const key of keys) {
41
+ if (!key.startsWith(prefix)) continue;
42
+ const rest = key.slice(prefix.length);
43
+ const slash = rest.indexOf('/');
44
+ seen.add(slash < 0 ? rest : rest.slice(0, slash + 1));
45
+ }
46
+ return [...seen].filter(Boolean);
47
+ }
48
+
49
+ /**
50
+ * Where a single file lands. A destination ending in `/` (or the bucket root)
51
+ * is a folder, so the source's basename is appended, as `cp` does locally.
52
+ */
53
+ function destinationKey(dstKey, sourceName) {
54
+ return !dstKey || dstKey.endsWith('/') ? `${dstKey}${path.basename(sourceName)}` : dstKey;
55
+ }
56
+
57
+ /** The key under `toPrefix` that `key` maps to when moving/copying `fromPrefix`. */
58
+ function rebase(key, fromPrefix, toPrefix) {
59
+ return `${toPrefix}${key.slice(fromPrefix.length)}`;
60
+ }
61
+
62
+ module.exports = { SCHEME, isRemote, parseRemote, requireBucket, encodeKey, asPrefix, childrenOf, destinationKey, rebase };
@@ -1,85 +0,0 @@
1
- 'use strict';
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const api = require('../api');
6
- const { output, requireArg } = require('./_util');
7
- const { CliError } = require('../context');
8
-
9
- function readSql(cwd, file) {
10
- if (!file) return undefined;
11
- return fs.readFileSync(path.resolve(cwd, file), 'utf8');
12
- }
13
-
14
- const subcommands = {
15
- list: {
16
- summary: 'List schema migrations',
17
- usage: 'motherbase migrations list',
18
- async run(ctx) {
19
- const data = await api.adminRequest(ctx, 'GET', '/migrations');
20
- const rows = (data && data.migrations) || [];
21
- output(ctx, data, (_d, ui) =>
22
- ui.table(rows, [
23
- { key: 'id', label: 'ID' },
24
- { key: 'name', label: 'NAME' },
25
- { key: 'status', label: 'STATUS' },
26
- { key: 'appliedAt', label: 'APPLIED' },
27
- ]),
28
- );
29
- },
30
- },
31
- diff: {
32
- summary: 'Show a diff between live schema and migrations',
33
- usage: 'motherbase migrations diff',
34
- async run(ctx) {
35
- const data = await api.adminRequest(ctx, 'GET', '/migrations/diff');
36
- output(ctx, data, (d, ui) => ui.json(d));
37
- },
38
- },
39
- get: {
40
- summary: 'Show a single migration',
41
- usage: 'motherbase migrations get <id>',
42
- async run(ctx, args) {
43
- const id = requireArg(args[0], 'id');
44
- const data = await api.adminRequest(ctx, 'GET', `/migrations/${id}`);
45
- output(ctx, data, (d, ui) => ui.keyValue((d && d.migration) || d || {}));
46
- },
47
- },
48
- create: {
49
- summary: 'Create a migration from up/down SQL files',
50
- usage: 'motherbase migrations create --name <name> --up <file.sql> [--down <file.sql>]',
51
- async run(ctx, args, flags) {
52
- const name = flags.name || args[0];
53
- if (!name) throw new CliError('--name is required');
54
- const upSql = readSql(ctx.cwd, flags.up);
55
- const downSql = readSql(ctx.cwd, flags.down);
56
- if (!upSql) throw new CliError('--up <file.sql> is required');
57
- const data = await api.adminRequest(ctx, 'POST', '/migrations', { body: { name, upSql, downSql } });
58
- output(ctx, data, (d, ui) => ui.success(`Created migration ${name}`));
59
- },
60
- },
61
- apply: {
62
- summary: 'Apply a migration',
63
- usage: 'motherbase migrations apply <id>',
64
- async run(ctx, args) {
65
- const id = requireArg(args[0], 'id');
66
- const data = await api.adminRequest(ctx, 'POST', `/migrations/${id}/apply`);
67
- output(ctx, data, (d, ui) => ui.success(`Applied ${id}`));
68
- },
69
- },
70
- rollback: {
71
- summary: 'Roll back a migration',
72
- usage: 'motherbase migrations rollback <id>',
73
- async run(ctx, args) {
74
- const id = requireArg(args[0], 'id');
75
- const data = await api.adminRequest(ctx, 'POST', `/migrations/${id}/rollback`);
76
- output(ctx, data, (d, ui) => ui.success(`Rolled back ${id}`));
77
- },
78
- },
79
- };
80
-
81
- module.exports = {
82
- summary: 'Schema migrations (list/diff/create/apply/rollback)',
83
- usage: 'motherbase migrations <list|diff|get|create|apply|rollback> ...',
84
- subcommands,
85
- };