dbdocs 1.0.1__tar.gz → 1.0.2__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.
- {dbdocs-1.0.1 → dbdocs-1.0.2}/.gitignore +1 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/PKG-INFO +1 -1
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/extract/nodes.py +39 -14
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/site/bundle/assets/app.js +16 -12
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/site/bundle/assets/style.css +6 -10
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/site/bundle/index.html +1 -1
- {dbdocs-1.0.1 → dbdocs-1.0.2}/LICENSE +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/README.md +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/__init__.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/__main__.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/cli/__init__.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/cli/main.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/core/__init__.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/core/artifacts.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/core/config.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/core/exceptions.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/core/log.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/extract/__init__.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/extract/_sqlglot_lineage.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/extract/column_lineage.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/extract/erd.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/extract/erd_json.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/extract/graph.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/main.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/site/__init__.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/site/builder.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/site/bundle/assets/favicon.svg +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/site/bundle/assets/graph/index.css +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/site/bundle/assets/graph/index.js +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/site/bundle/assets/vendor/marked.min.js +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/site/bundle/assets/vendor/minisearch.min.js +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/site/deploy.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/dbdocs/site/inject.py +0 -0
- {dbdocs-1.0.1 → dbdocs-1.0.2}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dbdocs
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.2
|
|
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
|
|
@@ -12,27 +12,52 @@ from typing import Any
|
|
|
12
12
|
from dbdocs.core.artifacts import NODE_PREFIXES, db_schema, node_name
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
def _column_entry(name: str, manifest_column: Any, col_type: str) -> dict:
|
|
16
|
+
"""One column record. Newlines in the description become ``<br>`` for HTML."""
|
|
17
|
+
description = getattr(manifest_column, "description", "") or "" if manifest_column else ""
|
|
18
|
+
return {
|
|
19
|
+
"name": name,
|
|
20
|
+
"type": col_type or "",
|
|
21
|
+
"tags": (getattr(manifest_column, "tags", []) or []) if manifest_column else [],
|
|
22
|
+
"description": description.replace("\n", "<br>"),
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
15
26
|
def _columns(model: Any, catalog_node: Any) -> list:
|
|
16
|
-
"""
|
|
27
|
+
"""Build a node's columns: the manifest is the source of truth, the catalog
|
|
28
|
+
enriches it.
|
|
29
|
+
|
|
30
|
+
The **manifest** decides which columns are documented and carries their
|
|
31
|
+
metadata (description, tags, ``data_type``); the **catalog** *enriches* — it
|
|
32
|
+
supplies the warehouse-confirmed type and any columns the manifest didn't
|
|
33
|
+
document. It never replaces the manifest, so a model absent from a
|
|
34
|
+
stale/partial ``catalog.json`` still shows every documented column.
|
|
17
35
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
36
|
+
Manifest columns come first, in manifest order, each with its type enriched
|
|
37
|
+
from the catalog when present (falling back to the manifest ``data_type``).
|
|
38
|
+
The catalog keys columns by the warehouse's casing (Snowflake upper-cases
|
|
39
|
+
them) while the manifest keeps the modeled casing, so the catalog type lookup
|
|
40
|
+
is case-insensitive. Catalog-only columns are appended afterwards.
|
|
21
41
|
"""
|
|
22
42
|
manifest_columns = getattr(model, "columns", {}) or {}
|
|
23
43
|
catalog_columns = getattr(catalog_node, "columns", {}) or {} if catalog_node else {}
|
|
44
|
+
catalog_by_lower = {str(name).lower(): col for name, col in catalog_columns.items()}
|
|
45
|
+
|
|
24
46
|
columns = []
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"tags": (getattr(manifest_column, "tags", []) or []) if manifest_column else [],
|
|
33
|
-
"description": description.replace("\n", "<br>"),
|
|
34
|
-
}
|
|
47
|
+
seen_lower = set()
|
|
48
|
+
for name, manifest_column in manifest_columns.items():
|
|
49
|
+
lower = str(name).lower()
|
|
50
|
+
seen_lower.add(lower)
|
|
51
|
+
catalog_column = catalog_by_lower.get(lower)
|
|
52
|
+
col_type = getattr(catalog_column, "type", None) or getattr(
|
|
53
|
+
manifest_column, "data_type", None
|
|
35
54
|
)
|
|
55
|
+
columns.append(_column_entry(name, manifest_column, col_type or ""))
|
|
56
|
+
|
|
57
|
+
for name, catalog_column in catalog_columns.items():
|
|
58
|
+
if str(name).lower() in seen_lower:
|
|
59
|
+
continue
|
|
60
|
+
columns.append(_column_entry(name, None, getattr(catalog_column, "type", "") or ""))
|
|
36
61
|
return columns
|
|
37
62
|
|
|
38
63
|
|
|
@@ -120,12 +120,23 @@
|
|
|
120
120
|
el("span", {}, ["Generated by "]),
|
|
121
121
|
el("a", { href: "https://github.com/datnguye/dbt-docs", target: "_blank", rel: "noopener" }, ["dbdocs"]),
|
|
122
122
|
]);
|
|
123
|
+
var meta = footerMeta();
|
|
124
|
+
if (meta) left.appendChild(el("span", { class: "cf-meta" }, [" · " + meta]));
|
|
123
125
|
var right = el("a", { class: "cf-top", href: "#", onclick: function (e) { e.preventDefault(); app.scrollTop = 0; } }, ["↑ Back to top"]);
|
|
124
126
|
foot.appendChild(left);
|
|
125
127
|
foot.appendChild(right);
|
|
126
128
|
return foot;
|
|
127
129
|
}
|
|
128
130
|
|
|
131
|
+
/* "snowflake · N column-lineage edges" — the build metadata shown in the
|
|
132
|
+
content footer. The "Generated X" part lives in the topbar (see boot). */
|
|
133
|
+
function footerMeta() {
|
|
134
|
+
var parts = [];
|
|
135
|
+
if (META.adapter_type) parts.push(META.adapter_type);
|
|
136
|
+
parts.push(Object.keys(COLLIN).length + " column-lineage edges");
|
|
137
|
+
return parts.join(" · ");
|
|
138
|
+
}
|
|
139
|
+
|
|
129
140
|
var RTYPE_ORDER = { model: 0, snapshot: 1, seed: 2, source: 3 };
|
|
130
141
|
|
|
131
142
|
function buildNav() {
|
|
@@ -456,17 +467,6 @@
|
|
|
456
467
|
link.hidden = false;
|
|
457
468
|
}
|
|
458
469
|
|
|
459
|
-
function initTopbarMeta() {
|
|
460
|
-
var box = document.getElementById("topbar-meta");
|
|
461
|
-
if (!box) return;
|
|
462
|
-
var parts = [];
|
|
463
|
-
if (META.generated_at) parts.push("Generated " + META.generated_at);
|
|
464
|
-
if (META.adapter_type) parts.push(META.adapter_type);
|
|
465
|
-
parts.push(Object.keys(COLLIN).length + " column-lineage edges");
|
|
466
|
-
box.textContent = parts.join(" · ");
|
|
467
|
-
box.hidden = false;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
470
|
function initFooter() {
|
|
471
471
|
var footer = document.getElementById("site-footer");
|
|
472
472
|
if (!footer) return;
|
|
@@ -486,8 +486,12 @@
|
|
|
486
486
|
function boot() {
|
|
487
487
|
document.getElementById("brand-name").textContent = META.site_name || "dbt docs";
|
|
488
488
|
document.title = META.site_name || "dbt docs";
|
|
489
|
+
if (META.generated_at) {
|
|
490
|
+
var gen = document.getElementById("brand-generated");
|
|
491
|
+
gen.textContent = "Generated " + META.generated_at;
|
|
492
|
+
gen.hidden = false;
|
|
493
|
+
}
|
|
489
494
|
initRepo();
|
|
490
|
-
initTopbarMeta();
|
|
491
495
|
initFooter();
|
|
492
496
|
initTheme();
|
|
493
497
|
buildNav();
|
|
@@ -52,8 +52,9 @@ code, pre { font-family: "SF Mono", "Roboto Mono", Menlo, Consolas, monospace; }
|
|
|
52
52
|
background: var(--bg-elev); border-bottom: 1px solid var(--border);
|
|
53
53
|
position: sticky; top: 0; z-index: 30;
|
|
54
54
|
}
|
|
55
|
-
.brand { display: flex; align-items:
|
|
56
|
-
.brand-mark { display: block; width: 24px; height: 24px; border-radius: 6px; }
|
|
55
|
+
.brand { display: flex; align-items: baseline; gap: 8px; font-weight: 600; min-width: 160px; }
|
|
56
|
+
.brand-mark { display: block; width: 24px; height: 24px; border-radius: 6px; align-self: center; }
|
|
57
|
+
.brand-generated { color: var(--text-soft); font-size: 12px; font-weight: 400; white-space: nowrap; }
|
|
57
58
|
.search-wrap { position: relative; flex: 1; max-width: 520px; }
|
|
58
59
|
#search {
|
|
59
60
|
width: 100%; padding: 7px 12px; border-radius: var(--radius);
|
|
@@ -118,21 +119,16 @@ code, pre { font-family: "SF Mono", "Roboto Mono", Menlo, Consolas, monospace; }
|
|
|
118
119
|
}
|
|
119
120
|
.footer-copy { color: var(--text-soft); font-size: 12px; }
|
|
120
121
|
|
|
121
|
-
/* Build metadata in the header (generated / adapter / edges) */
|
|
122
|
-
.topbar-meta {
|
|
123
|
-
color: var(--text-soft); font-size: 11.5px; white-space: nowrap;
|
|
124
|
-
padding-right: 6px; flex-shrink: 0;
|
|
125
|
-
}
|
|
126
|
-
@media (max-width: 1100px) { .topbar-meta { display: none; } }
|
|
127
|
-
|
|
128
122
|
/* End-of-page content footer */
|
|
129
123
|
.content-foot {
|
|
130
124
|
display: flex; align-items: center; justify-content: space-between; gap: 12px;
|
|
131
125
|
margin-top: 40px; padding-top: 16px; border-top: 1px solid var(--border);
|
|
132
126
|
color: var(--text-soft); font-size: 12px;
|
|
133
127
|
}
|
|
134
|
-
.content-foot .cf-left { display: inline-flex; align-items: center; gap: 6px; }
|
|
128
|
+
.content-foot .cf-left { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
|
135
129
|
.content-foot .cf-left .ic { color: var(--text-soft); }
|
|
130
|
+
/* Build metadata (generated / adapter / edges) appended to the footer's left */
|
|
131
|
+
.content-foot .cf-meta { color: var(--text-soft); }
|
|
136
132
|
.content-foot .cf-top { color: var(--text-soft); }
|
|
137
133
|
.content-foot .cf-top:hover { color: var(--accent); }
|
|
138
134
|
.bmc {
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
<div class="brand">
|
|
15
15
|
<img class="brand-mark" src="assets/favicon.svg" alt="" width="24" height="24" />
|
|
16
16
|
<span class="brand-name" id="brand-name">dbt docs</span>
|
|
17
|
+
<span class="brand-generated" id="brand-generated" hidden></span>
|
|
17
18
|
</div>
|
|
18
|
-
<div class="topbar-meta" id="topbar-meta" hidden></div>
|
|
19
19
|
<div class="search-wrap">
|
|
20
20
|
<input id="search" type="search" placeholder="Search models, sources, columns…" autocomplete="off" />
|
|
21
21
|
<div id="search-results" class="search-results" hidden></div>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|