@deaquinodev/querky 0.4.4 → 0.4.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 (2) hide show
  1. package/dist/index.js +48 -34
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -39,10 +39,11 @@ var PgDbClient = class {
39
39
  }
40
40
  pg;
41
41
  async query(sql) {
42
- const result = await this.pg.query(sql);
42
+ const raw = await this.pg.query(sql);
43
+ const result = Array.isArray(raw) ? raw[raw.length - 1] : raw;
43
44
  return {
44
- fields: result.fields.map((f) => f.name),
45
- rows: result.rows,
45
+ fields: (result.fields ?? []).map((f) => f.name),
46
+ rows: result.rows ?? [],
46
47
  rowCount: result.rowCount ?? 0
47
48
  };
48
49
  }
@@ -625,8 +626,12 @@ var COMMANDS = {
625
626
  description: "Save last query as a named alias",
626
627
  category: "Aliases",
627
628
  usage: "/save <name>",
628
- detail: "Saves the last executed SQL query as a named alias scoped to the current database. Run it later with /<name>. Supports positional ($1, $2) and named (:param) substitution.",
629
- example: "/save active-orders",
629
+ detail: "Saves the last executed SQL query as a named alias scoped to the current database. Run it later with /<name>. If the query contains $1, $2 placeholders or :param placeholders, values are substituted at run time.",
630
+ examples: [
631
+ "/save active-orders (no params \u2014 run with /active-orders)",
632
+ "/save user-by-id (query had WHERE id = $1 \u2014 run with /user-by-id 42)",
633
+ "/save by-status (query had WHERE status = :status \u2014 run with /by-status :status=active)"
634
+ ],
630
635
  run: (ctx) => {
631
636
  const name = ctx.args.trim();
632
637
  if (!name) return { ok: false, message: "Usage: /save <name>" };
@@ -640,8 +645,14 @@ var COMMANDS = {
640
645
  description: "Define an alias inline",
641
646
  category: "Aliases",
642
647
  usage: "/alias <name> <SQL>",
643
- detail: "Defines a named alias without running a query first. Equivalent to /save but lets you specify the SQL directly.",
644
- example: "/alias recent SELECT * FROM events ORDER BY created_at DESC LIMIT 20",
648
+ detail: "Defines a named alias without running a query first. Use $1, $2 for positional args or :param for named args \u2014 values are substituted when the alias is invoked.",
649
+ examples: [
650
+ "/alias recent SELECT * FROM events ORDER BY created_at DESC LIMIT 20",
651
+ "/alias user SELECT * FROM users WHERE id = $1",
652
+ "/alias by-email SELECT * FROM users WHERE email = :email",
653
+ "/user 42 (positional)",
654
+ "/by-email :email=alice@example.com (named)"
655
+ ],
645
656
  run: (ctx) => {
646
657
  const [name, ...rest] = ctx.args.trim().split(/\s+/);
647
658
  if (!name || rest.length === 0) return { ok: false, message: "Usage: /alias <name> <SQL>" };
@@ -706,7 +717,8 @@ var COMMANDS = {
706
717
  description: cmd.description,
707
718
  psqlAlias: PSQL_REVERSE[name],
708
719
  detail: cmd.detail,
709
- example: cmd.example
720
+ example: cmd.example,
721
+ examples: cmd.examples
710
722
  };
711
723
  return { ok: true, message: "", helpData: { mode: "detail", entry } };
712
724
  }
@@ -1713,7 +1725,7 @@ import { Box as Box2, Text as Text2 } from "ink";
1713
1725
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1714
1726
  var COL_PAD = 1;
1715
1727
  var INDIGO = "#818cf8";
1716
- var BORDER = "white";
1728
+ var BORDER2 = "white";
1717
1729
  var NULL_COLOR = "#6366f1";
1718
1730
  var NULL_MARKER = "\u2205";
1719
1731
  function isNull(val) {
@@ -1744,10 +1756,10 @@ function hline(widths, left, mid, right) {
1744
1756
  function ExpandedTable({ columns, rows }) {
1745
1757
  const keyWidth = columns.reduce((max, col) => Math.max(max, col.length), 0);
1746
1758
  return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", children: rows.map((row, i) => /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginBottom: i < rows.length - 1 ? 1 : 0, children: [
1747
- /* @__PURE__ */ jsx2(Text2, { color: BORDER, children: `\u2500[ Record ${i + 1} ]${"\u2500".repeat(Math.max(0, keyWidth + 14 - String(i + 1).length))}` }),
1759
+ /* @__PURE__ */ jsx2(Text2, { color: BORDER2, children: `\u2500[ Record ${i + 1} ]${"\u2500".repeat(Math.max(0, keyWidth + 14 - String(i + 1).length))}` }),
1748
1760
  columns.map((col) => /* @__PURE__ */ jsxs2(Box2, { children: [
1749
1761
  /* @__PURE__ */ jsx2(Text2, { color: INDIGO, bold: true, children: col.padEnd(keyWidth) }),
1750
- /* @__PURE__ */ jsx2(Text2, { color: BORDER, children: " \u2502 " }),
1762
+ /* @__PURE__ */ jsx2(Text2, { color: BORDER2, children: " \u2502 " }),
1751
1763
  isNull(row[col]) ? /* @__PURE__ */ jsx2(Text2, { color: NULL_COLOR, dimColor: true, children: NULL_MARKER }) : /* @__PURE__ */ jsx2(Text2, { children: cellValue(row[col]) })
1752
1764
  ] }, col))
1753
1765
  ] }, i)) });
@@ -1760,31 +1772,31 @@ function Table({ columns, rows, expanded = false }) {
1760
1772
  const botLine = hline(widths, "\u2570", "\u2534", "\u256F");
1761
1773
  function renderHeaderRow(cols) {
1762
1774
  return /* @__PURE__ */ jsxs2(Box2, { children: [
1763
- /* @__PURE__ */ jsx2(Text2, { color: BORDER, children: "\u2502" }),
1775
+ /* @__PURE__ */ jsx2(Text2, { color: BORDER2, children: "\u2502" }),
1764
1776
  cols.map((v, i) => /* @__PURE__ */ jsxs2(Box2, { children: [
1765
1777
  /* @__PURE__ */ jsx2(Text2, { color: INDIGO, bold: true, children: " ".repeat(COL_PAD) + pad(v, widths[i]) + " ".repeat(COL_PAD) }),
1766
- /* @__PURE__ */ jsx2(Text2, { color: BORDER, children: "\u2502" })
1778
+ /* @__PURE__ */ jsx2(Text2, { color: BORDER2, children: "\u2502" })
1767
1779
  ] }, i))
1768
1780
  ] });
1769
1781
  }
1770
1782
  function renderDataRow(row) {
1771
1783
  return /* @__PURE__ */ jsxs2(Box2, { children: [
1772
- /* @__PURE__ */ jsx2(Text2, { color: BORDER, children: "\u2502" }),
1784
+ /* @__PURE__ */ jsx2(Text2, { color: BORDER2, children: "\u2502" }),
1773
1785
  columns.map((col, i) => /* @__PURE__ */ jsxs2(Box2, { children: [
1774
1786
  isNull(row[col]) ? /* @__PURE__ */ jsx2(Text2, { color: NULL_COLOR, dimColor: true, children: " ".repeat(COL_PAD) + pad(NULL_MARKER, widths[i]) + " ".repeat(COL_PAD) }) : /* @__PURE__ */ jsx2(Text2, { children: " ".repeat(COL_PAD) + pad(cellValue(row[col]), widths[i]) + " ".repeat(COL_PAD) }),
1775
- /* @__PURE__ */ jsx2(Text2, { color: BORDER, children: "\u2502" })
1787
+ /* @__PURE__ */ jsx2(Text2, { color: BORDER2, children: "\u2502" })
1776
1788
  ] }, i))
1777
1789
  ] });
1778
1790
  }
1779
1791
  return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
1780
- /* @__PURE__ */ jsx2(Text2, { color: BORDER, children: topLine }),
1792
+ /* @__PURE__ */ jsx2(Text2, { color: BORDER2, children: topLine }),
1781
1793
  renderHeaderRow(columns),
1782
- /* @__PURE__ */ jsx2(Text2, { color: BORDER, children: midLine }),
1794
+ /* @__PURE__ */ jsx2(Text2, { color: BORDER2, children: midLine }),
1783
1795
  rows.map((row, i) => /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
1784
1796
  renderDataRow(row),
1785
- i < rows.length - 1 && /* @__PURE__ */ jsx2(Text2, { color: BORDER, children: midLine })
1797
+ i < rows.length - 1 && /* @__PURE__ */ jsx2(Text2, { color: BORDER2, children: midLine })
1786
1798
  ] }, i)),
1787
- /* @__PURE__ */ jsx2(Text2, { color: BORDER, children: botLine })
1799
+ /* @__PURE__ */ jsx2(Text2, { color: BORDER2, children: botLine })
1788
1800
  ] });
1789
1801
  }
1790
1802
 
@@ -1944,7 +1956,7 @@ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1944
1956
  var USAGE_WIDTH = 28;
1945
1957
  function HelpView({ data }) {
1946
1958
  if (data.mode === "detail" && data.entry) {
1947
- const { usage, description, psqlAlias, detail, example } = data.entry;
1959
+ const { usage, description, psqlAlias, detail, example, examples } = data.entry;
1948
1960
  return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginTop: 1, children: [
1949
1961
  /* @__PURE__ */ jsxs5(Text5, { bold: true, color: "white", children: [
1950
1962
  usage,
@@ -1952,10 +1964,13 @@ function HelpView({ data }) {
1952
1964
  ] }),
1953
1965
  /* @__PURE__ */ jsx5(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text5, { children: description }) }),
1954
1966
  detail && /* @__PURE__ */ jsx5(Box5, { marginTop: 1, children: /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: detail }) }),
1955
- example && /* @__PURE__ */ jsxs5(Box5, { marginTop: 1, children: [
1967
+ examples && examples.length > 0 ? /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginTop: 1, children: [
1968
+ /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "Examples:" }),
1969
+ examples.map((ex, i) => /* @__PURE__ */ jsx5(Box5, { marginLeft: 2, children: /* @__PURE__ */ jsx5(Text5, { color: theme.accent, children: ex }) }, i))
1970
+ ] }) : example ? /* @__PURE__ */ jsxs5(Box5, { marginTop: 1, children: [
1956
1971
  /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "Example: " }),
1957
1972
  /* @__PURE__ */ jsx5(Text5, { color: theme.accent, children: example })
1958
- ] })
1973
+ ] }) : null
1959
1974
  ] });
1960
1975
  }
1961
1976
  if (data.mode === "list" && data.groups) {
@@ -1994,7 +2009,6 @@ var TABLE_COLORS = [
1994
2009
  "#fbbf24",
1995
2010
  "#2dd4bf"
1996
2011
  ];
1997
- var BORDER2 = "white";
1998
2012
  var PAD = 1;
1999
2013
  var GAP = 2;
2000
2014
  var FK_PREFIX = "FK \u2192 ";
@@ -2042,31 +2056,31 @@ function TableBox({ table, m, color, colorMap }) {
2042
2056
  const bot = "\u2570" + "\u2500".repeat(nameW + PAD * 2) + "\u2534" + "\u2500".repeat(typeW + PAD * 2) + "\u2534" + "\u2500".repeat(keyW + PAD * 2) + "\u256F";
2043
2057
  const headerW = totalW - 4;
2044
2058
  return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
2045
- /* @__PURE__ */ jsx6(Text6, { color: BORDER2, children: top }),
2059
+ /* @__PURE__ */ jsx6(Text6, { color, children: top }),
2046
2060
  /* @__PURE__ */ jsxs6(Box6, { children: [
2047
- /* @__PURE__ */ jsx6(Text6, { color: BORDER2, children: "\u2502" }),
2061
+ /* @__PURE__ */ jsx6(Text6, { color, children: "\u2502" }),
2048
2062
  /* @__PURE__ */ jsxs6(Text6, { color, bold: true, children: [
2049
2063
  sp,
2050
2064
  p(table.name, headerW),
2051
2065
  sp
2052
2066
  ] }),
2053
- /* @__PURE__ */ jsx6(Text6, { color: BORDER2, children: "\u2502" })
2067
+ /* @__PURE__ */ jsx6(Text6, { color, children: "\u2502" })
2054
2068
  ] }),
2055
- /* @__PURE__ */ jsx6(Text6, { color: BORDER2, children: sep }),
2069
+ /* @__PURE__ */ jsx6(Text6, { color, children: sep }),
2056
2070
  table.columns.map((col, i) => /* @__PURE__ */ jsxs6(Box6, { children: [
2057
- /* @__PURE__ */ jsx6(Text6, { color: BORDER2, children: "\u2502" }),
2071
+ /* @__PURE__ */ jsx6(Text6, { color, children: "\u2502" }),
2058
2072
  /* @__PURE__ */ jsxs6(Text6, { children: [
2059
2073
  sp,
2060
2074
  p(col.name, nameW),
2061
2075
  sp
2062
2076
  ] }),
2063
- /* @__PURE__ */ jsx6(Text6, { color: BORDER2, children: "\u2502" }),
2077
+ /* @__PURE__ */ jsx6(Text6, { color, children: "\u2502" }),
2064
2078
  /* @__PURE__ */ jsxs6(Text6, { dimColor: true, children: [
2065
2079
  sp,
2066
2080
  p(col.type, typeW),
2067
2081
  sp
2068
2082
  ] }),
2069
- /* @__PURE__ */ jsx6(Text6, { color: BORDER2, children: "\u2502" }),
2083
+ /* @__PURE__ */ jsx6(Text6, { color, children: "\u2502" }),
2070
2084
  col.isPk ? /* @__PURE__ */ jsxs6(Text6, { bold: true, children: [
2071
2085
  sp,
2072
2086
  p("PK", keyW),
@@ -2076,7 +2090,7 @@ function TableBox({ table, m, color, colorMap }) {
2076
2090
  sp,
2077
2091
  FK_PREFIX
2078
2092
  ] }),
2079
- /* @__PURE__ */ jsxs6(Text6, { color: colorMap.get(col.fkTable) ?? BORDER2, children: [
2093
+ /* @__PURE__ */ jsxs6(Text6, { color: colorMap.get(col.fkTable) ?? color, children: [
2080
2094
  p(col.fkTable, keyW - FK_PREFIX.length),
2081
2095
  sp
2082
2096
  ] })
@@ -2085,9 +2099,9 @@ function TableBox({ table, m, color, colorMap }) {
2085
2099
  " ".repeat(keyW),
2086
2100
  sp
2087
2101
  ] }),
2088
- /* @__PURE__ */ jsx6(Text6, { color: BORDER2, children: "\u2502" })
2102
+ /* @__PURE__ */ jsx6(Text6, { color, children: "\u2502" })
2089
2103
  ] }, i)),
2090
- /* @__PURE__ */ jsx6(Text6, { color: BORDER2, children: bot })
2104
+ /* @__PURE__ */ jsx6(Text6, { color, children: bot })
2091
2105
  ] });
2092
2106
  }
2093
2107
  function ErdView({ data }) {
@@ -2105,7 +2119,7 @@ function ErdView({ data }) {
2105
2119
  {
2106
2120
  table: data.tables[ti],
2107
2121
  m: metrics[ti],
2108
- color: colorMap.get(data.tables[ti].name) ?? BORDER2,
2122
+ color: colorMap.get(data.tables[ti].name) ?? BORDER,
2109
2123
  colorMap
2110
2124
  }
2111
2125
  ) }, ti)) }, ri)) });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deaquinodev/querky",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "description": "A quirky terminal SQL client with vim mode, AI features, and schema-aware autocomplete",
5
5
  "main": "dist/index.js",
6
6
  "files": [