dbdocs 1.6.1__tar.gz → 1.6.3__tar.gz

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 (55) hide show
  1. {dbdocs-1.6.1 → dbdocs-1.6.3}/PKG-INFO +1 -1
  2. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/site/builder.py +6 -1
  3. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/site/bundle/assets/css/style.css +183 -3
  4. dbdocs-1.6.3/dbdocs/site/bundle/assets/graph/index.js +62 -0
  5. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/site/bundle/assets/js/app.js +4 -4
  6. {dbdocs-1.6.1/dbdocs/site/bundle/assets/js → dbdocs-1.6.3/dbdocs/site/bundle/assets/js/service}/service.js +1 -0
  7. dbdocs-1.6.3/dbdocs/site/bundle/assets/js/ui/dom.js +26 -0
  8. dbdocs-1.6.3/dbdocs/site/bundle/assets/js/ui/overlays.js +268 -0
  9. {dbdocs-1.6.1/dbdocs/site/bundle/assets/js → dbdocs-1.6.3/dbdocs/site/bundle/assets/js/ui}/ui.js +83 -203
  10. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/site/bundle/index.html +2 -0
  11. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/site/deploy.py +1 -1
  12. dbdocs-1.6.1/dbdocs/site/bundle/assets/graph/index.js +0 -62
  13. {dbdocs-1.6.1 → dbdocs-1.6.3}/.gitignore +0 -0
  14. {dbdocs-1.6.1 → dbdocs-1.6.3}/LICENSE +0 -0
  15. {dbdocs-1.6.1 → dbdocs-1.6.3}/README.md +0 -0
  16. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/__init__.py +0 -0
  17. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/__main__.py +0 -0
  18. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/cli/__init__.py +0 -0
  19. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/cli/main.py +0 -0
  20. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/core/__init__.py +0 -0
  21. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/core/artifacts.py +0 -0
  22. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/core/config.py +0 -0
  23. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/core/exceptions.py +0 -0
  24. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/core/log.py +0 -0
  25. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/__init__.py +0 -0
  26. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/_sqlglot_lineage.py +0 -0
  27. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/column_lineage.py +0 -0
  28. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/erd.py +0 -0
  29. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/graph.py +0 -0
  30. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/health/__init__.py +0 -0
  31. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/health/dimensions.py +0 -0
  32. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/health/extractor.py +0 -0
  33. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/health/rules/__init__.py +0 -0
  34. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/health/rules/base.py +0 -0
  35. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/health/rules/dimensions/__init__.py +0 -0
  36. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/health/rules/dimensions/documentation.py +0 -0
  37. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/health/rules/dimensions/governance.py +0 -0
  38. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/health/rules/dimensions/modeling.py +0 -0
  39. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/health/rules/dimensions/performance.py +0 -0
  40. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/health/rules/dimensions/structure.py +0 -0
  41. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/health/rules/dimensions/testing.py +0 -0
  42. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/health/rules/registry.py +0 -0
  43. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/nodes.py +0 -0
  44. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/extract/tests_index.py +0 -0
  45. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/main.py +0 -0
  46. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/site/__init__.py +0 -0
  47. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/site/api_schema.py +0 -0
  48. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/site/bundle/assets/css/icons.css +0 -0
  49. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/site/bundle/assets/favicon.svg +0 -0
  50. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/site/bundle/assets/graph/index.css +0 -0
  51. {dbdocs-1.6.1/dbdocs/site/bundle/assets/js → dbdocs-1.6.3/dbdocs/site/bundle/assets/js/data}/data.js +0 -0
  52. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/site/bundle/assets/vendor/marked.min.js +0 -0
  53. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/site/bundle/assets/vendor/minisearch.min.js +0 -0
  54. {dbdocs-1.6.1 → dbdocs-1.6.3}/dbdocs/site/inject.py +0 -0
  55. {dbdocs-1.6.1 → dbdocs-1.6.3}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dbdocs
3
- Version: 1.6.1
3
+ Version: 1.6.3
4
4
  Summary: Alternative dbt docs site: Catalog + ERD + column-level lineage
5
5
  Project-URL: Homepage, https://github.com/datnguye/dbt-docs
6
6
  Project-URL: Repository, https://github.com/datnguye/dbt-docs
@@ -211,7 +211,7 @@ class ReportBuilder:
211
211
  counts[label] = counts.get(label, 0) + len(collection)
212
212
  return counts
213
213
 
214
- def generate(self, output_dir: "str | None" = None) -> str:
214
+ def generate(self, output_dir: "str | None" = None, versioned: bool = False) -> str:
215
215
  """Render the site into ``output_dir`` (or config's). Returns its path.
216
216
 
217
217
  The data dict is written as an external ``dbdocs-data.json.gz`` that the
@@ -225,6 +225,10 @@ class ReportBuilder:
225
225
  see ``_write_api`` for the layout. The api/ directory is created after the
226
226
  bundle copytree (so the rmtree + copytree cycle doesn't touch it) and is
227
227
  not shipped in the wheel.
228
+
229
+ ``versioned=True`` is set by ``deploy()`` to signal that a
230
+ ``versions.json`` sibling exists; the SPA gates its version-switcher fetch
231
+ on this flag so a plain ``generate`` build never makes a 404 request.
228
232
  """
229
233
  out = Path(output_dir) if output_dir else Path(self.config.output_path)
230
234
  if out.exists():
@@ -233,6 +237,7 @@ class ReportBuilder:
233
237
  copytree(src=BUNDLE_DIR, dst=out, dirs_exist_ok=True)
234
238
 
235
239
  data = self.build_data()
240
+ data["metadata"]["versioned"] = versioned
236
241
  data["metadata"].update(self._stage_branding(out))
237
242
  index = out / "index.html"
238
243
  index.write_text(strip_marker(index.read_text(encoding="utf-8")), encoding="utf-8")
@@ -87,7 +87,7 @@ code, pre { font-family: "SF Mono", "Roboto Mono", Menlo, Consolas, monospace; }
87
87
  .brand-generated { color: var(--text-soft); font-size: 12px; font-weight: 400; white-space: nowrap; }
88
88
  .search-wrap { position: relative; flex: 1; max-width: 520px; }
89
89
  #search {
90
- width: 100%; padding: 7px 12px; border-radius: var(--radius);
90
+ width: 100%; padding: 7px 76px 7px 12px; border-radius: var(--radius);
91
91
  border: 1px solid var(--border); background: var(--bg-soft); color: var(--text);
92
92
  }
93
93
  #search:focus { outline: none; border-color: var(--accent); }
@@ -190,7 +190,11 @@ body.nav-collapsed .nav-collapse { display: none; }
190
190
  }
191
191
  .nav-reopen:hover { color: var(--accent); border-color: var(--accent); }
192
192
  body.nav-collapsed .nav-reopen { display: inline-flex; }
193
- .sidebar { flex: 1; overflow-y: auto; padding: 12px; }
193
+ .sidebar {
194
+ flex: 1; min-height: 0; overflow: hidden; padding: 12px;
195
+ display: flex; flex-direction: column;
196
+ }
197
+ .sidebar > .nav-cta, .sidebar > .nav-tabs, .sidebar > .nav-filter { flex-shrink: 0; }
194
198
  .nav-filter {
195
199
  width: 100%; box-sizing: border-box; margin: 6px 0 10px;
196
200
  padding: 7px 10px; font-size: 13px; border-radius: var(--radius);
@@ -289,7 +293,7 @@ body.nav-collapsed .nav-reopen { display: inline-flex; }
289
293
  .nav-tab:hover { color: var(--text); background: var(--bg-elev); }
290
294
  .nav-tab.active { color: var(--accent); border-bottom-color: var(--accent); }
291
295
  .nav-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
292
- .nav-tab-panel { min-height: 0; }
296
+ .nav-tab-panel { flex: 1; min-height: 0; overflow-y: auto; }
293
297
 
294
298
  /* Resource-type dot */
295
299
  .dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; display: inline-block; }
@@ -599,6 +603,178 @@ a.score-chip:hover {
599
603
  a.score-chip:hover .score-name { text-decoration: none; }
600
604
  a.score-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
601
605
  @media (prefers-reduced-motion: reduce) { .score-chip { transition: none; } a.score-chip:hover { transform: none; } }
606
+
607
+ /* ── theme transition ───────────────────────────────────────────────────────
608
+ A brief ease so toggling dark mode fades rather than snapping. Scoped only
609
+ to background/border/color so it doesn't make every interaction feel laggy.
610
+ Applied via the .theme-transition class that ui.js adds for 300ms then removes. */
611
+ .theme-transition,
612
+ .theme-transition *,
613
+ .theme-transition *::before,
614
+ .theme-transition *::after {
615
+ transition: background-color 0.25s ease, border-color 0.25s ease, color 0.2s ease !important;
616
+ }
617
+
618
+ /* ── page-mount micro-transition ────────────────────────────────────────────
619
+ Subtle fade+slide-up when route() replaces #app content (150ms, fast). */
620
+ @keyframes page-enter {
621
+ from { opacity: 0; transform: translateY(6px); }
622
+ to { opacity: 1; transform: translateY(0); }
623
+ }
624
+ .page-enter { animation: page-enter 0.15s ease-out both; }
625
+
626
+ /* ── graph skeleton loader ──────────────────────────────────────────────────
627
+ Shimmer gradient shown inside .graph-host while the React Flow bundle mounts.
628
+ Replaced by the graph once dbdocsGraph.mount() fires. */
629
+ @keyframes shimmer {
630
+ 0% { background-position: -200% 0; }
631
+ 100% { background-position: 200% 0; }
632
+ }
633
+ .graph-skeleton {
634
+ width: 100%; height: 480px; border-radius: var(--radius);
635
+ background: linear-gradient(90deg,
636
+ var(--bg-soft) 25%,
637
+ var(--bg-elev) 37%,
638
+ var(--bg-soft) 63%);
639
+ background-size: 200% 100%;
640
+ animation: shimmer 1.4s linear infinite;
641
+ }
642
+
643
+ /* ── toast notifications ────────────────────────────────────────────────────
644
+ Corner-anchored stack. Individual toasts slide in from the right, fade out.
645
+ The ARIA live region (#toast-region) is visually positioned at the bottom-right. */
646
+ #toast-region {
647
+ position: fixed; bottom: 24px; right: 24px; z-index: 200;
648
+ display: flex; flex-direction: column; gap: 8px; pointer-events: none;
649
+ max-width: 320px;
650
+ }
651
+ .toast {
652
+ display: flex; align-items: center; gap: 10px; pointer-events: none;
653
+ padding: 10px 16px; border-radius: var(--radius);
654
+ background: var(--bg-elev); border: 1px solid var(--border);
655
+ box-shadow: 0 4px 16px rgba(0,0,0,0.15); color: var(--text);
656
+ font-size: 13px; font-weight: 500;
657
+ animation: toast-in 0.2s ease-out both;
658
+ }
659
+ .toast.toast-out {
660
+ animation: toast-out 0.2s ease-in both;
661
+ }
662
+ @keyframes toast-in {
663
+ from { opacity: 0; transform: translateX(24px); }
664
+ to { opacity: 1; transform: translateX(0); }
665
+ }
666
+ @keyframes toast-out {
667
+ from { opacity: 1; transform: translateX(0); }
668
+ to { opacity: 0; transform: translateX(24px); }
669
+ }
670
+
671
+ /* ── command palette ────────────────────────────────────────────────────────
672
+ Centered modal overlay with a frosted backdrop. */
673
+ #cmd-backdrop {
674
+ position: fixed; inset: 0; z-index: 100;
675
+ background: rgba(0,0,0,0.45);
676
+ display: flex; align-items: flex-start; justify-content: center;
677
+ padding-top: 15vh;
678
+ }
679
+ #cmd-palette {
680
+ width: min(640px, 92vw);
681
+ background: var(--bg-elev); border: 1px solid var(--border);
682
+ border-radius: calc(var(--radius) + 2px); box-shadow: 0 12px 48px rgba(0,0,0,0.24);
683
+ overflow: hidden;
684
+ animation: palette-in 0.14s ease-out both;
685
+ }
686
+ @keyframes palette-in {
687
+ from { opacity: 0; transform: scale(0.97) translateY(-8px); }
688
+ to { opacity: 1; transform: scale(1) translateY(0); }
689
+ }
690
+ .cmd-input-wrap {
691
+ display: flex; align-items: center; gap: 10px; padding: 12px 16px;
692
+ border-bottom: 1px solid var(--border);
693
+ }
694
+ .cmd-input-wrap .ic { flex-shrink: 0; }
695
+ #cmd-input {
696
+ flex: 1; border: none; outline: none; background: transparent;
697
+ font-size: 15px; color: var(--text); line-height: 1.4;
698
+ }
699
+ #cmd-input::placeholder { color: var(--text-soft); }
700
+ .cmd-kbd-close {
701
+ flex-shrink: 0; padding: 2px 6px; border-radius: 4px;
702
+ background: var(--bg-soft); border: 1px solid var(--border);
703
+ color: var(--text-soft); font-size: 11px; font-family: inherit;
704
+ }
705
+ #cmd-results {
706
+ max-height: 360px; overflow-y: auto;
707
+ padding: 4px 0;
708
+ }
709
+ .cmd-result {
710
+ display: flex; align-items: center; gap: 10px;
711
+ padding: 9px 16px; cursor: pointer; color: var(--text);
712
+ font-size: 13px; text-decoration: none;
713
+ }
714
+ .cmd-result:hover, .cmd-result.cmd-active {
715
+ background: var(--accent-soft); text-decoration: none;
716
+ }
717
+ .cmd-result-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
718
+ .cmd-result-meta { font-size: 11px; color: var(--text-soft); white-space: nowrap; flex-shrink: 0; }
719
+ .cmd-section-label {
720
+ padding: 6px 16px 2px; font-size: 10px; font-weight: 700; letter-spacing: .06em;
721
+ text-transform: uppercase; color: var(--text-soft);
722
+ }
723
+ .cmd-empty { padding: 20px 16px; text-align: center; color: var(--text-soft); font-size: 13px; }
724
+
725
+ /* ── ⌘K hint in the search box ──────────────────────────────────────────────
726
+ A small kbd chip rendered inside .search-wrap (absolute-positioned right edge). */
727
+ .cmd-hint {
728
+ position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
729
+ pointer-events: none;
730
+ display: flex; align-items: center; gap: 3px;
731
+ }
732
+ .cmd-hint kbd {
733
+ padding: 1px 5px; border-radius: 4px;
734
+ background: var(--bg-elev); border: 1px solid var(--border);
735
+ color: var(--text-soft); font-size: 10px; font-family: inherit;
736
+ line-height: 1.6;
737
+ }
738
+
739
+ /* ── sticky table headers ───────────────────────────────────────────────────
740
+ th in the Columns/Tests/other node-page tables stick at the top of their
741
+ scroll container (.content) on vertical scroll. background is explicitly set
742
+ so rows don't bleed through. */
743
+ .node-section-body th {
744
+ position: sticky; top: 0; z-index: 2;
745
+ background: var(--bg-elev); box-shadow: 0 1px 0 var(--border);
746
+ }
747
+
748
+ /* ── scroll-spy active section ──────────────────────────────────────────────
749
+ When IntersectionObserver marks a node-section as visible, its summary gets a
750
+ subtle left accent stripe via the .section-in-view modifier. */
751
+ details.node-section.section-in-view > summary.node-section-summary {
752
+ color: var(--accent);
753
+ }
754
+ details.node-section.section-in-view > summary.node-section-summary .node-section-title {
755
+ color: var(--accent);
756
+ }
757
+ details.node-section.section-in-view > summary.node-section-summary::before {
758
+ color: var(--accent);
759
+ }
760
+
761
+ /* ── Reduced-motion gate ────────────────────────────────────────────────────
762
+ Neutralize the palette/toast/page/skeleton/theme keyframes + transitions. */
763
+ @media (prefers-reduced-motion: reduce) {
764
+ .theme-transition,
765
+ .theme-transition *,
766
+ .theme-transition *::before,
767
+ .theme-transition *::after {
768
+ transition: none !important;
769
+ }
770
+ .page-enter { animation: none; }
771
+ .graph-skeleton { animation: none; background: var(--bg-soft); }
772
+ .toast { animation: none; }
773
+ .toast.toast-out { animation: none; opacity: 0; }
774
+ #cmd-palette { animation: none; }
775
+ @keyframes toast-in { from { opacity: 1; transform: none; } to { opacity: 1; transform: none; } }
776
+ @keyframes toast-out { from { opacity: 0; transform: none; } to { opacity: 0; transform: none; } }
777
+ }
602
778
  .score-chip.good { border-left-color: var(--score-good); }
603
779
  .score-chip.warn { border-left-color: var(--score-warn); }
604
780
  .score-chip.bad { border-left-color: var(--score-bad); }
@@ -625,6 +801,10 @@ a.score-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2
625
801
  .health-error { background: var(--status-error-bg); color: var(--status-error-fg); border-color: var(--status-error-bd); }
626
802
  .health-skip { background: var(--bg-soft); color: var(--text-soft); border-color: var(--border); }
627
803
 
804
+ [data-theme="dark"] .toast { box-shadow: 0 4px 16px rgba(0,0,0,0.45); }
805
+ [data-theme="dark"] #cmd-palette { box-shadow: 0 12px 48px rgba(0,0,0,0.55); }
806
+ [data-theme="dark"] #cmd-backdrop { background: rgba(0,0,0,0.65); }
807
+
628
808
  /* Hamburger + search toggle — hidden on desktop, revealed on phones below. */
629
809
  .nav-toggle { display: none; font-size: 18px; }
630
810
  .search-toggle { display: none; }