@mason-data/cli 0.6.2 → 0.8.0

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 (119) hide show
  1. package/README.md +147 -69
  2. package/dist/src/api/error.js +3 -0
  3. package/dist/src/api/postgres/catalog.js +258 -14
  4. package/dist/src/api/postgres/encode.js +3 -1
  5. package/dist/src/api/postgres/explain.js +3 -2
  6. package/dist/src/api/postgres/protocol.js +39 -23
  7. package/dist/src/api/postgres/server.js +1290 -223
  8. package/dist/src/api/postgres/translate.js +81 -9
  9. package/dist/src/api/request-log.js +18 -5
  10. package/dist/src/cdc/pg-wire.js +144 -38
  11. package/dist/src/cdc/poll.js +5 -5
  12. package/dist/src/cli/background.js +55 -8
  13. package/dist/src/cli/cancel.js +75 -0
  14. package/dist/src/cli/command.js +5 -3
  15. package/dist/src/cli/commands.js +843 -272
  16. package/dist/src/cli/control.js +59 -0
  17. package/dist/src/cli/demo.js +158 -0
  18. package/dist/src/cli/dev.js +458 -125
  19. package/dist/src/cli/doctor.js +25 -12
  20. package/dist/src/cli/guides.js +103 -31
  21. package/dist/src/cli/init.js +159 -58
  22. package/dist/src/cli/machine.js +18 -12
  23. package/dist/src/cli/main.js +5 -5
  24. package/dist/src/cli/mcp.js +735 -0
  25. package/dist/src/cli/metrics.js +79 -0
  26. package/dist/src/cli/pg-tls.js +13 -3
  27. package/dist/src/cli/pg-url.js +4 -0
  28. package/dist/src/cli/pin.js +13 -12
  29. package/dist/src/cli/preflight.js +24 -14
  30. package/dist/src/cli/project.js +48 -7
  31. package/dist/src/cli/readiness.js +38 -4
  32. package/dist/src/cli/registry.js +57 -35
  33. package/dist/src/cli/replication-checks.js +7 -5
  34. package/dist/src/cli/replication-mode.js +105 -26
  35. package/dist/src/cli/request-filter.js +134 -0
  36. package/dist/src/cli/roles.js +584 -0
  37. package/dist/src/cli/run-server.js +498 -133
  38. package/dist/src/cli/runs.js +1 -1
  39. package/dist/src/cli/security.js +10 -8
  40. package/dist/src/cli/serve.js +147 -40
  41. package/dist/src/cli/share-run.js +286 -0
  42. package/dist/src/cli/share.js +286 -0
  43. package/dist/src/cli/source-edit.js +168 -0
  44. package/dist/src/cli/sources.js +290 -39
  45. package/dist/src/cli/supervise.js +12 -1
  46. package/dist/src/cli/sync.js +55 -25
  47. package/dist/src/cli/tunnel.js +200 -0
  48. package/dist/src/cli/ui.js +9 -6
  49. package/dist/src/cli/usage.js +128 -0
  50. package/dist/src/cli/user.js +496 -40
  51. package/dist/src/cli/version.js +9 -7
  52. package/dist/src/demo/seed.js +240 -0
  53. package/dist/src/demo/source.js +655 -0
  54. package/dist/src/duck/cancel.js +10 -1
  55. package/dist/src/duck/distinct-key.js +228 -0
  56. package/dist/src/duck/events.js +134 -0
  57. package/dist/src/duck/executor-worker.js +25 -11
  58. package/dist/src/duck/executor.js +107 -53
  59. package/dist/src/duck/explain.js +158 -29
  60. package/dist/src/duck/extensions.js +160 -0
  61. package/dist/src/duck/functions.js +73 -19
  62. package/dist/src/duck/gaps.js +25 -11
  63. package/dist/src/duck/grants.js +176 -0
  64. package/dist/src/duck/history.js +123 -0
  65. package/dist/src/duck/jsonb-order.js +175 -0
  66. package/dist/src/duck/jsonb.js +10 -8
  67. package/dist/src/duck/kept-route.js +82 -2
  68. package/dist/src/duck/kept.js +211 -44
  69. package/dist/src/duck/pgtree.js +40 -0
  70. package/dist/src/duck/plan.js +120 -30
  71. package/dist/src/duck/publication.js +6 -6
  72. package/dist/src/duck/requests.js +265 -93
  73. package/dist/src/duck/rewrite.js +1193 -73
  74. package/dist/src/duck/row-filter.js +649 -0
  75. package/dist/src/duck/store.js +271 -159
  76. package/dist/src/duck/stream.js +10 -5
  77. package/dist/src/duck/sync.js +907 -275
  78. package/dist/src/duck/types.js +6 -5
  79. package/dist/src/duck/usage.js +324 -0
  80. package/dist/src/duck/users.js +64 -15
  81. package/dist/src/duck/verified.js +9 -0
  82. package/dist/src/duck/views.js +2 -3
  83. package/dist/src/lib/database-name.js +62 -0
  84. package/dist/src/lib/dotenv.js +17 -4
  85. package/dist/src/lib/log-buffer.js +68 -0
  86. package/dist/src/lib/pg-numeric.js +5 -2
  87. package/dist/src/lib/project-version.js +23 -23
  88. package/dist/src/lib/table-sync.js +267 -0
  89. package/dist/src/lib/timezone.js +3 -2
  90. package/dist/src/web/app.css +706 -55
  91. package/dist/src/web/app.js +330 -258
  92. package/dist/src/web/charts.js +229 -0
  93. package/dist/src/web/index.html +84 -15
  94. package/dist/src/web/pages/queries.js +192 -0
  95. package/dist/src/web/pages/status.js +446 -0
  96. package/dist/src/web/pages/syncs.js +155 -0
  97. package/dist/src/web/pages/tables.js +434 -0
  98. package/dist/src/web/pages/usage.js +397 -0
  99. package/dist/src/web/pages/users.js +218 -0
  100. package/dist/src/web/shared.js +568 -0
  101. package/dist/src/web/vendor/README.md +25 -0
  102. package/dist/src/web/vendor/geist-1.7.2/Geist-Variable.woff2 +0 -0
  103. package/dist/src/web/vendor/geist-1.7.2/GeistMono-Variable.woff2 +0 -0
  104. package/dist/src/web/vendor/geist-1.7.2/LICENSE.txt +92 -0
  105. package/dist/src/web/vendor/lucide-1.56.0/LICENSE.txt +43 -0
  106. package/dist/src/web/vendor/lucide-1.56.0/chart-column.mjs +29 -0
  107. package/dist/src/web/vendor/lucide-1.56.0/layout-dashboard.mjs +29 -0
  108. package/dist/src/web/vendor/lucide-1.56.0/logs.mjs +34 -0
  109. package/dist/src/web/vendor/lucide-1.56.0/menu.mjs +28 -0
  110. package/dist/src/web/vendor/lucide-1.56.0/square-terminal.mjs +28 -0
  111. package/dist/src/web/vendor/lucide-1.56.0/table.mjs +29 -0
  112. package/dist/src/web/vendor/lucide-1.56.0/users.mjs +29 -0
  113. package/dist/src/web/vendor/lucide-1.56.0/x.mjs +27 -0
  114. package/dist/src/web/vendor/uplot-1.6.32/LICENSE.txt +21 -0
  115. package/dist/src/web/vendor/uplot-1.6.32/uPlot.esm.js +6140 -0
  116. package/dist/src/web/vendor/uplot-1.6.32/uPlot.min.css +1 -0
  117. package/dist/src/web/vendor/zilla-slab-5.3.0/LICENSE.txt +93 -0
  118. package/dist/src/web/vendor/zilla-slab-5.3.0/zilla-slab-latin-700-normal.woff2 +0 -0
  119. package/package.json +10 -3
@@ -0,0 +1,75 @@
1
+ /**
2
+ * `mason cancel <session>`: stops the statement a session of the Postgres API is running, exactly as a client's own
3
+ * cancel (the protocol's CancelRequest) stops it — the listener's one path (src/api/postgres/server.ts `interrupt`),
4
+ * through the run's `POST /api/cancel` (src/cli/run-server.ts). The client is told 57014 "canceling statement due to
5
+ * user request", and the request log records it as cancelled. `mason logs --running` lists the sessions.
6
+ */
7
+ import { failed, jsonText, parseCommand, reportText } from "./command.js";
8
+ import { out as styleOut } from "./style.js";
9
+ import { callRun } from "./control.js";
10
+ import { reach } from "./state.js";
11
+ import { guarded, oneLine, runFailure, spanText } from "./commands.js";
12
+ const out = (m) => { process.stdout.write(`${m}\n`); };
13
+ export const CANCEL_USAGE = `usage: mason cancel <session> [--statement <n>] [--json]
14
+
15
+ Stops the statement a session of the Postgres API is running now, as the client's own cancel would: the client is
16
+ told "canceling statement due to user request" (SQLSTATE 57014), its session stays open, and the request log keeps
17
+ the statement as cancelled. mason logs --running lists the statements running now, with their sessions and numbers.
18
+
19
+ mason logs --running
20
+ mason cancel 12 --statement 340
21
+ mason cancel 12
22
+
23
+ --statement <n> only that statement (its number in mason logs --running): if it ended and the session runs
24
+ another, nothing is cancelled and the answer says so. Without it, whatever the session runs now
25
+ is stopped, as a client's own cancel stops it.
26
+ --json as data: { cancelled: { session, statement, user, applicationName, method, startedAt, runningMs,
27
+ rows, query, queryTruncated } (the statement it stopped), next }
28
+ `;
29
+ export const CANCEL = {
30
+ needs: "run",
31
+ name: "cancel",
32
+ summary: "stop the statement a session of the Postgres API is running, as the client's cancel would: mason cancel 12",
33
+ usage: CANCEL_USAGE,
34
+ options: { statement: { type: "string" }, json: { type: "boolean" } },
35
+ json: ["cancelled", "next"],
36
+ };
37
+ export async function cancel(argv) {
38
+ const f = parseCommand(CANCEL, argv);
39
+ if (typeof f === "number")
40
+ return f;
41
+ const json = f.values.json === true;
42
+ const running = ["mason logs --running", "the statements running now, with their sessions"];
43
+ if (f.positionals.length !== 1 || !/^[1-9]\d*$/.test(f.positionals[0])) {
44
+ return failed("cancel", { message: f.positionals.length === 0 ? "name the session: mason cancel <session>" : `${f.positionals.join(" ")} is not a session's number`,
45
+ code: "usage", fix: "mason logs --running lists each statement running with its session", next: [running], usage: CANCEL_USAGE }, { json });
46
+ }
47
+ const session = Number(f.positionals[0]);
48
+ const statement = f.values.statement;
49
+ if (statement !== undefined && (typeof statement !== "string" || !/^[1-9]\d*$/.test(statement))) {
50
+ return failed("cancel", { message: `--statement ${String(statement)} is not a statement's number`, code: "usage",
51
+ fix: "mason logs --running lists each statement running with its number", next: [running], usage: CANCEL_USAGE }, { json });
52
+ }
53
+ const w = await reach(CANCEL, json);
54
+ if (w === null || !("run" in w))
55
+ return 1;
56
+ const run = w.run;
57
+ return guarded("cancel", json, async () => {
58
+ const r = await callRun(run, "POST", "/api/cancel", { session, ...(statement !== undefined ? { statement: Number(statement) } : {}) });
59
+ if (r.status !== 200)
60
+ return failed("cancel", runFailure(r, [running]), { json });
61
+ const c = r.body.cancelled;
62
+ const next = [[`mason logs --requests --outcome cancelled -n 5`, "the statements cancelled, this one among them once it ended"], running];
63
+ if (json) {
64
+ out(jsonText(CANCEL, { cancelled: c }, next));
65
+ return 0;
66
+ }
67
+ out(reportText({
68
+ headline: `Cancelled session ${c.session}'s statement: it ends now, and its client gets a "canceling statement" error.`,
69
+ details: [["Statement", oneLine(c.query) || "(no statement)"], ["Client", `${c.applicationName || "(no application_name)"}${c.user ? ` (user ${c.user})` : ""}`],
70
+ ["Running", `${spanText(c.runningMs / 1000)}, ${c.rows.toLocaleString("en-US")} row${c.rows === 1 ? "" : "s"} sent`]],
71
+ next,
72
+ }, styleOut()));
73
+ return 0;
74
+ });
75
+ }
@@ -24,7 +24,7 @@ export function parseCommand(spec, argv) {
24
24
  parsed = parseArgs({ args: argv, options: { ...spec.options, ...HELP }, allowPositionals: true });
25
25
  }
26
26
  catch (e) {
27
- return failed(spec.name, { message: e.message, code: "usage", usage: spec.usage, next: [[`mason ${spec.name} --help`, "its usage, with every option"]] }, { json: wantsJson(argv) });
27
+ return failed(spec.name, { message: e.message, code: "usage", usage: spec.usage, next: [[`mason ${spec.name} --help`, "its usage, with every option"]] }, { json: wantsJson(argv, spec) });
28
28
  }
29
29
  if (parsed.values.help) {
30
30
  process.stdout.write(spec.usage);
@@ -76,8 +76,9 @@ export function nextJson(steps = []) {
76
76
  return steps.map(([command, what]) => what ? { command, what } : { command });
77
77
  }
78
78
  /** Whether a command line asked for data: `--json` anywhere on it (read before the line is parsed, so a wrong line
79
- * is answered in JSON too). */
80
- export const wantsJson = (argv) => argv.includes("--json");
79
+ * is answered in JSON too) — never for a command whose stdout is a protocol's (`CommandSpec.stdout`), whose every
80
+ * failure is said on stderr. */
81
+ export const wantsJson = (argv, spec) => spec?.stdout !== "protocol" && argv.includes("--json");
81
82
  /**
82
83
  * A COMMAND'S --json ANSWER (an agent wants clear, unambiguous context and a machine-readable format, and a person
83
84
  * and an agent both want the next steps): one JSON object on stdout, always with `next` — the same steps the human
@@ -104,6 +105,7 @@ export const FAILURE_CODES = {
104
105
  no_project: "no Mason project here or above (mason init makes one)",
105
106
  bad_config: "this folder is a Mason project whose .mason/config.json cannot be read: repair it, or move .mason/ aside and mason init",
106
107
  bad_source: "the project's sources file (mason/sources/<name>.yml) is missing or names something wrong: the file, the key and the way out are said",
108
+ bad_roles: "the project's roles file (mason/roles.yml) names something wrong: a table the sources file does not sync, a column the synced table lacks, a role with no table; the file, the key and the way out are said",
107
109
  not_running: "Mason is not running for the project (mason start)",
108
110
  unreachable: "Mason is running but does not answer (mason logs says why)",
109
111
  not_found: "a name nothing has: a table, a column, a user",