quickdbd-cli 0.3.4__py3-none-any.whl → 0.4.0__py3-none-any.whl

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.
quickdbd_cli/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.3.4"
1
+ __version__ = "0.4.0"
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><rect width="128" height="128" rx="28" fill="#2563eb"/><rect x="22" y="22" width="42" height="36" rx="9" fill="#fff"/><path d="M44 58v19a10 10 0 0 0 10 10h12" fill="none" stroke="#fff" stroke-width="8"/><rect x="64" y="70" width="42" height="33" rx="8" fill="#a8c1f7"/></svg>
quickdbd_cli/cli.py CHANGED
@@ -158,10 +158,28 @@ def cmd_build(args) -> int:
158
158
  def cmd_share(args) -> int:
159
159
  from . import share
160
160
 
161
+ if not share.allowed():
162
+ print(
163
+ "error: sharing is off. qdbd share uploads the diagram (every table and column name) to a GitHub gist"
164
+ f" that anyone with the link can open. If your data policy allows that, set {share.ALLOW_ENV}=1"
165
+ " (doing so accepts https://qdbd.dev/sharing/#disclaimer).",
166
+ file=sys.stderr,
167
+ )
168
+ return 2
161
169
  res = _built_page(args)
162
170
  if isinstance(res, int):
163
171
  return res
164
172
  page, model = res
173
+ print(share.DISCLAIMER, file=sys.stderr)
174
+ if not args.yes:
175
+ if not sys.stdin.isatty():
176
+ print("error: no terminal to confirm in: add --yes to accept the disclaimer and share", file=sys.stderr)
177
+ return 2
178
+ kind = "public" if args.public else "secret"
179
+ print(f"Share {len(model['tables'])} tables as a {kind} gist? [y/N] ", end="", file=sys.stderr, flush=True)
180
+ if sys.stdin.readline().strip().lower() not in ("y", "yes"):
181
+ print("Not shared.", file=sys.stderr)
182
+ return 2
165
183
  key = share.share_key(args.paths, selector_expr(args.select, args.exclude))
166
184
  try:
167
185
  r = share.publish(page, _title(_open(args)), key, public=args.public, new=args.new)
@@ -571,7 +589,10 @@ def build_parser() -> argparse.ArgumentParser:
571
589
  sp.add_argument("--strict", action="store_true")
572
590
  sp.set_defaults(func=cmd_build)
573
591
 
574
- sp = sub.add_parser("share", help="publish the diagram as a GitHub gist and print a link (needs the gh CLI)")
592
+ sp = sub.add_parser(
593
+ "share",
594
+ help="publish the diagram as a GitHub gist and print a link (off unless QDBD_ALLOW_SHARE=1; needs the gh CLI)",
595
+ )
575
596
  paths(sp)
576
597
  selectors(sp)
577
598
  sp.add_argument(
@@ -582,6 +603,7 @@ def build_parser() -> argparse.ArgumentParser:
582
603
  sp.add_argument("--strict", action="store_true")
583
604
  sp.add_argument("--public", action="store_true", help="list the gist publicly (default: secret, link-only)")
584
605
  sp.add_argument("--new", action="store_true", help="make a new gist instead of updating the last one")
606
+ sp.add_argument("-y", "--yes", action="store_true", help="accept the disclaimer without asking (for scripts)")
585
607
  sp.set_defaults(func=cmd_share)
586
608
 
587
609
  sp = sub.add_parser("export", help="write a PNG, SVG or draw.io file")
@@ -665,7 +687,7 @@ def build_parser() -> argparse.ArgumentParser:
665
687
  sp.add_argument(
666
688
  "--read-only",
667
689
  action="store_true",
668
- help="live view only: no editor, nothing saved; safe to share through a tunnel",
690
+ help="live view only: no editor, nothing saved; viewers can't change anything",
669
691
  )
670
692
  sp.add_argument(
671
693
  "--embed",
quickdbd_cli/html.py CHANGED
@@ -4,6 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  import json
6
6
  from importlib import resources
7
+ from urllib.parse import quote
7
8
 
8
9
  from .export import font_css
9
10
 
@@ -14,6 +15,11 @@ def _asset(name: str) -> str:
14
15
  return resources.files("quickdbd_cli").joinpath(f"assets/{name}").read_text(encoding="utf-8")
15
16
 
16
17
 
18
+ def favicon() -> str:
19
+ """The VS Code extension's icon as an inline SVG data URL, so pages stay single-file."""
20
+ return f'<link rel="icon" href="data:image/svg+xml,{quote(_asset("icon.svg").strip(), safe=" /=:")}">'
21
+
22
+
17
23
  def _json_for_script(obj) -> str:
18
24
  # Safe inside <script type="application/json">: no "</" sequences.
19
25
  return json.dumps(obj, sort_keys=True, separators=(",", ":"), ensure_ascii=False).replace("</", "<\\/")
@@ -171,6 +177,7 @@ def render_page(
171
177
  '<!doctype html>\n<html lang="en"><head><meta charset="utf-8">'
172
178
  '<meta name="viewport" content="width=device-width, initial-scale=1">'
173
179
  '<meta name="generator" content="qdbd">'
180
+ f"{favicon()}"
174
181
  f"<title>{_escape(title)}</title>"
175
182
  f"<script>{THEME_JS}</script>"
176
183
  # The font CSS lives in its own <style> so the viewer can reuse it for SVG/PNG export
quickdbd_cli/share.py CHANGED
@@ -4,6 +4,10 @@ Uses the GitHub CLI (``gh api``), so it inherits the user's login. Gists are sec
4
4
  ``public``. The gist made for each input/selection is remembered in the user's cache directory, so
5
5
  sharing again updates the same gist and the link stays the same. The VS Code extension does the same
6
6
  without gh (vscode/src/gist.ts) and shares the cache: keep the two in step.
7
+
8
+ Off unless ``QDBD_ALLOW_SHARE`` is set: a gist puts the schema outside the organisation's control, which a
9
+ client's data agreements may not allow. The extension's own switch is the ``quickdbd.allowSharing`` setting.
10
+ Even then, every share shows ``DISCLAIMER`` and asks first; the extension's dialog (export.ts) says the same.
7
11
  """
8
12
 
9
13
  from __future__ import annotations
@@ -15,11 +19,23 @@ import subprocess
15
19
  from dataclasses import dataclass
16
20
  from pathlib import Path
17
21
 
22
+ ALLOW_ENV = "QDBD_ALLOW_SHARE"
23
+ DISCLAIMER = """\
24
+ Before you share: this uploads the diagram (every table and column name, type, key, relationship
25
+ and comment) to a GitHub gist. Anyone with the link can open it, and copies can outlive the gist.
26
+ By sharing, you confirm that you have the right to publish this schema, that your organisation's
27
+ policies and any client agreements allow it, and that qdbd's authors are not liable for any
28
+ disclosure. Full disclaimer: https://qdbd.dev/sharing/#disclaimer"""
29
+
18
30
 
19
31
  class ShareError(Exception):
20
32
  pass
21
33
 
22
34
 
35
+ def allowed() -> bool:
36
+ return os.environ.get(ALLOW_ENV, "").strip().lower() in ("1", "true", "yes", "on")
37
+
38
+
23
39
  @dataclass
24
40
  class Shared:
25
41
  link: str # gistpreview: renders the gist's HTML, keeps the #view part of the URL
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: quickdbd-cli
3
- Version: 0.3.4
3
+ Version: 0.4.0
4
4
  Summary: Compile QuickDBD-syntax schema files into interactive HTML ER diagrams, with no table limit.
5
5
  Project-URL: Homepage, https://qdbd.dev/
6
6
  Project-URL: Documentation, https://qdbd.dev/guide/
@@ -65,10 +65,10 @@ Description-Content-Type: text/markdown
65
65
  </p>
66
66
 
67
67
  <p align="center">
68
- <a href="https://qdbd.dev/demo/adventureworks/#t=SalesOrderHeader"><img src="https://raw.githubusercontent.com/MarkPhamm/quickdbd-cli/main/docs/assets/img/hero.png" alt="The AdventureWorks sample database as a qdbd diagram, with the SalesOrderHeader table selected" width="760"></a>
68
+ <a href="https://qdbd.dev/demo/adventureworks-dw/#t=FactInternetSales"><img src="https://raw.githubusercontent.com/MarkPhamm/quickdbd-cli/main/docs/assets/img/hero.png" alt="The AdventureWorks DW star schema as a qdbd diagram, with the FactInternetSales table selected" width="760"></a>
69
69
  </p>
70
70
  <p align="center">
71
- <em>AdventureWorks (68 tables) with its column descriptions, built by qdbd. <a href="https://qdbd.dev/demo/adventureworks/#t=SalesOrderHeader">Try it live →</a></em>
71
+ <em>AdventureWorks DW (28 tables), a star schema in five regions, built by qdbd. <a href="https://qdbd.dev/demo/adventureworks-dw/#t=FactInternetSales">Try it live →</a></em>
72
72
  </p>
73
73
 
74
74
  ## What is qdbd?
@@ -169,7 +169,7 @@ In VS Code (or Cursor), the [extension](https://qdbd.dev/vscode/) does the same
169
169
  ```sh
170
170
  qdbd build schema.txt -o schema.html # one self-contained page
171
171
  qdbd export schema.txt -o schema.png # or .svg, .drawio
172
- qdbd share schema.txt # a link to the page, via a GitHub gist
172
+ QDBD_ALLOW_SHARE=1 qdbd share schema.txt # a link via a GitHub gist: off by default, see the disclaimer
173
173
  ```
174
174
 
175
175
  ## Run in CI
@@ -186,7 +186,7 @@ jobs:
186
186
  permissions: { contents: read, pull-requests: write }
187
187
  steps:
188
188
  - uses: actions/checkout@v4
189
- - uses: MarkPhamm/quickdbd-cli@v0.3.4
189
+ - uses: MarkPhamm/quickdbd-cli@v0.4.0
190
190
  with:
191
191
  path: erd/ # schema file(s) or folder(s)
192
192
  output: site/index.html
@@ -257,7 +257,7 @@ No. qdbd only borrows the text syntax.
257
257
  No. It reads `.txt` / `.dbml` schema files or a dbt `manifest.json`. Nothing connects to a warehouse.
258
258
 
259
259
  **Does my schema leave my machine?**
260
- Only if you run `qdbd share`, which uploads the page to a GitHub gist in your account (secret by default), or connect an AI agent through `qdbd mcp`, whose answers go to your AI provider. `qdbd serve` loads its code editor from a CDN; the built pages load nothing.
260
+ Only if you turn sharing on (`QDBD_ALLOW_SHARE=1`, or `quickdbd.allowSharing` in VS Code) and run `qdbd share`, which uploads the page to a GitHub gist in your account (secret by default), publish it yourself (a tunnel, GitHub Pages), or connect an AI agent through `qdbd mcp`, whose answers go to your AI provider. `qdbd serve` loads its code editor from a CDN; the built pages load nothing.
261
261
 
262
262
  **How big can a diagram get?**
263
263
  The demos go up to 200 tables. Search, selectors, regions and collapsed views keep large diagrams workable; `--select` builds a page with just the part you need.
@@ -1,13 +1,13 @@
1
- quickdbd_cli/__init__.py,sha256=oYLGMpySamd16KLiaBTfRyrAS7_oyp-TOEHmzmeumwg,22
1
+ quickdbd_cli/__init__.py,sha256=42STGor_9nKYXumfeV5tiyD_M8VdcddX7CEexmibPBk,22
2
2
  quickdbd_cli/__main__.py,sha256=E6Gls0DNz8GQK2K-kOUIx8cYhgANW_CH54VKrfCfs14,52
3
3
  quickdbd_cli/agent.py,sha256=LEuReTkwWDlRLs-GfQQMpMosHDFWbin0EAXRo73j-dA,37202
4
- quickdbd_cli/cli.py,sha256=h9pTnGnprYOhyuEpjdd32QyAqR-skJRTBvoipIyCZS0,29522
4
+ quickdbd_cli/cli.py,sha256=kphlsJHzp-agb01rlw4PD2_SnriOtr-yRZPuW3I5B_E,30634
5
5
  quickdbd_cli/convert.py,sha256=1AYFm4YmEav_wZp7xCAcL7TsD3qC17Y1I5g6V_fyAU0,16682
6
6
  quickdbd_cli/dbml.py,sha256=tHJOtMm1PHx4-yqs6rncPqdDfbwPcW8F54j_kKlWkx0,59413
7
7
  quickdbd_cli/dbt.py,sha256=AMHzERmc8WfL1tBLX4bJdPVghIHrqrfx8nMDbZMrueY,23100
8
8
  quickdbd_cli/diff.py,sha256=UBiCE3dk_cN-xSRZFQoLiIIFh_FAVZUpLwsdtHG9eBo,9986
9
9
  quickdbd_cli/export.py,sha256=XbSvWqFmhQHPcBtPHPit1SmhJ6qXrPyGlHYt7FpIMyo,3539
10
- quickdbd_cli/html.py,sha256=pn4Jlcce5nniH7NtGoZjzrTH_dTw4qIhio4bWXGupVw,8031
10
+ quickdbd_cli/html.py,sha256=eZSECAaP-vxC_qGXOy0T7cXT7WkJeL7RixYvzMCDCZQ,8309
11
11
  quickdbd_cli/jsrt.py,sha256=_sRkmUbgHDTwK272jeTNUwojfjUKAkv4UeD2E2u3H1A,3464
12
12
  quickdbd_cli/layout.py,sha256=2wrryJ-SSJbMlOdxmtCTzC2_zkTtvRVs-OuOBS1bGEQ,10856
13
13
  quickdbd_cli/mcp.py,sha256=ibUg1a50BBco-hZABdxTexGZi_gclFCdcBDalTvFar8,12350
@@ -16,7 +16,7 @@ quickdbd_cli/model.py,sha256=lQcj89gDg2y4v_xhJX0_PWoWKGx0rg2emREVL_LA6uQ,3352
16
16
  quickdbd_cli/parser.py,sha256=MpWvYWNMIfl8PNKGDyVqVA_RUsuD21oZQqTT7yZd89g,33018
17
17
  quickdbd_cli/project.py,sha256=Iu6aXJNxCbM9KDRbLaxTb7SfbVDv7PkajzKZX4-XfDk,4570
18
18
  quickdbd_cli/serve.py,sha256=NqYAcfT4lySRckAG2tkrZwmRbzYDjdNh18Yh4Er_hPo,12271
19
- quickdbd_cli/share.py,sha256=42VOsau_Ek3rDriakuAxt8pDenimEMrfbGgSNe74GV8,3840
19
+ quickdbd_cli/share.py,sha256=njzF4HpQ-ymusLzzNb_ndvqWGlDaljx7TFP-mZj4lPU,4782
20
20
  quickdbd_cli/tags.py,sha256=fOMcz3N8YAIqh5uJJ3GuYMBCkfOViGRCVNb3Ufz63GM,4098
21
21
  quickdbd_cli/targets.py,sha256=zvge0c2_XOC13gnv2C_XMf_ZmDcpOFPzld2PoyOtyxU,8740
22
22
  quickdbd_cli/assets/Inter-Bold.ttf,sha256=KIMWCZseCkekcW0VkJgAXu98AGaSHzTjIAOT29sBlH8,420428
@@ -28,15 +28,16 @@ quickdbd_cli/assets/editor.js,sha256=Gare_MeAOKlc2QZpTR9nD8Ty-U6JBY3HRWAeMnDkCsU
28
28
  quickdbd_cli/assets/elk-LICENSE.md,sha256=Y36B9KG2tAeVNcSZ_KBeI4z3YFwf9bdtYNfafOlnAMk,14443
29
29
  quickdbd_cli/assets/elk.bundled.js,sha256=EiLkT5U853Rq8jgB5yNwj45vQ2uLN3pqX8dVLzSjB7M,1609707
30
30
  quickdbd_cli/assets/font-metrics.json,sha256=sXSiElxQSK8md8IEePLwh16TTdAqKt9rV140pvMlVS8,8654
31
+ quickdbd_cli/assets/icon.svg,sha256=0T_BOpEdFzxQHg6wJL2rrEyk55nkjascmp_3xBE9IA0,338
31
32
  quickdbd_cli/assets/render.js,sha256=WzxX_sUgdz0O4GgiaupKl8J_LI4YCqF9PUxzRbwebwo,31891
32
33
  quickdbd_cli/assets/style.css,sha256=ttyGKLti1sU-NMp9CBTDgaznfeU14XjWquFJr9XGsaA,18877
33
34
  quickdbd_cli/assets/syntax-reference.md,sha256=WERcsWjyrfeHQPgxQriWKBsqFJnmWTQ2oRZjKYAHhKc,5322
34
35
  quickdbd_cli/assets/viewer.js,sha256=3rKXI80TNv9jF1dJNQa3Gpy0042yTcGfTz_8qg4h5WU,49676
35
- quickdbd_cli-0.3.4.dist-info/METADATA,sha256=ubcoaxo_WRsI_-5TAdjNoR1G9kWcfsRTT_ibmIXdAzA,17195
36
- quickdbd_cli-0.3.4.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
37
- quickdbd_cli-0.3.4.dist-info/entry_points.txt,sha256=nRhiYYug-XOY95nWUmi4oanico3Zjkfqk2OHtIE6SQ0,47
38
- quickdbd_cli-0.3.4.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
39
- quickdbd_cli-0.3.4.dist-info/licenses/NOTICE,sha256=pyv3BfIYiGzKLU4w-GcBe7GXoXxHqZ97Mf6Zpx_3_i0,2067
40
- quickdbd_cli-0.3.4.dist-info/licenses/src/quickdbd_cli/assets/Inter-LICENSE.txt,sha256=JiSB6ERSGzJvXs0FPlm5jIstp4yO4b27boF0MF5Uk1o,4380
41
- quickdbd_cli-0.3.4.dist-info/licenses/src/quickdbd_cli/assets/elk-LICENSE.md,sha256=Y36B9KG2tAeVNcSZ_KBeI4z3YFwf9bdtYNfafOlnAMk,14443
42
- quickdbd_cli-0.3.4.dist-info/RECORD,,
36
+ quickdbd_cli-0.4.0.dist-info/METADATA,sha256=o9bIn-TRuVLhAhKC22kQPosVOYP7tI7Ts5XxF02LqCQ,17359
37
+ quickdbd_cli-0.4.0.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
38
+ quickdbd_cli-0.4.0.dist-info/entry_points.txt,sha256=nRhiYYug-XOY95nWUmi4oanico3Zjkfqk2OHtIE6SQ0,47
39
+ quickdbd_cli-0.4.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
40
+ quickdbd_cli-0.4.0.dist-info/licenses/NOTICE,sha256=pyv3BfIYiGzKLU4w-GcBe7GXoXxHqZ97Mf6Zpx_3_i0,2067
41
+ quickdbd_cli-0.4.0.dist-info/licenses/src/quickdbd_cli/assets/Inter-LICENSE.txt,sha256=JiSB6ERSGzJvXs0FPlm5jIstp4yO4b27boF0MF5Uk1o,4380
42
+ quickdbd_cli-0.4.0.dist-info/licenses/src/quickdbd_cli/assets/elk-LICENSE.md,sha256=Y36B9KG2tAeVNcSZ_KBeI4z3YFwf9bdtYNfafOlnAMk,14443
43
+ quickdbd_cli-0.4.0.dist-info/RECORD,,