@malloydata/malloyyo 0.2.22 → 0.2.23
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.
- package/dist/index.js +73 -10
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7,19 +7,80 @@ import { resolve as resolve2 } from "node:path";
|
|
|
7
7
|
// src/config.ts
|
|
8
8
|
import { readFileSync, existsSync } from "node:fs";
|
|
9
9
|
import { join } from "node:path";
|
|
10
|
+
var KNOWN_KEYS = /* @__PURE__ */ new Set(["analytics", "targets"]);
|
|
11
|
+
function isTarget(v) {
|
|
12
|
+
return typeof v === "object" && v !== null && typeof v.url === "string";
|
|
13
|
+
}
|
|
14
|
+
var warned = /* @__PURE__ */ new Set();
|
|
15
|
+
function warnOnce(key, msg) {
|
|
16
|
+
if (warned.has(key)) return;
|
|
17
|
+
warned.add(key);
|
|
18
|
+
console.warn(msg);
|
|
19
|
+
}
|
|
20
|
+
function parseMalloyyoConfig(raw) {
|
|
21
|
+
const declared = raw.targets;
|
|
22
|
+
const targets = typeof declared === "object" && declared !== null ? { ...declared } : {};
|
|
23
|
+
const legacy = [];
|
|
24
|
+
const unknown = [];
|
|
25
|
+
for (const [k, v] of Object.entries(raw)) {
|
|
26
|
+
if (KNOWN_KEYS.has(k)) continue;
|
|
27
|
+
if (isTarget(v)) {
|
|
28
|
+
if (!(k in targets)) targets[k] = v;
|
|
29
|
+
legacy.push(k);
|
|
30
|
+
} else {
|
|
31
|
+
unknown.push(k);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (legacy.length) {
|
|
35
|
+
warnOnce(
|
|
36
|
+
"legacy-targets",
|
|
37
|
+
`malloy-config.json: publish target(s) ${legacy.map((t) => `"${t}"`).join(", ")} are at the top of the "malloyyo" block. Move them under "targets":
|
|
38
|
+
"malloyyo": { "targets": { ${legacy.map((t) => `"${t}": { \u2026 }`).join(", ")} } }
|
|
39
|
+
The old shape still works for now.`
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
if (unknown.length) {
|
|
43
|
+
warnOnce(
|
|
44
|
+
"unknown-keys",
|
|
45
|
+
`malloy-config.json: ignoring unknown key(s) in the "malloyyo" block: ${unknown.map((k) => `"${k}"`).join(", ")}. Known keys: ${[...KNOWN_KEYS].join(", ")}.`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
const analytics = raw.analytics;
|
|
49
|
+
return {
|
|
50
|
+
analytics: typeof analytics === "string" && analytics ? analytics : void 0,
|
|
51
|
+
targets
|
|
52
|
+
};
|
|
53
|
+
}
|
|
10
54
|
function readTargetMap(dir) {
|
|
55
|
+
const raw = readMalloyyoBlock(dir);
|
|
56
|
+
if (raw) return parseMalloyyoConfig(raw).targets;
|
|
57
|
+
throw new Error(
|
|
58
|
+
`No \`malloyyo\` config found in ${dir} (looked for a "malloyyo" block in malloy-config.json, then malloyyo.json).`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
function readMalloyyoBlock(dir) {
|
|
11
62
|
const malloyConfig = join(dir, "malloy-config.json");
|
|
12
63
|
if (existsSync(malloyConfig)) {
|
|
13
|
-
|
|
14
|
-
|
|
64
|
+
try {
|
|
65
|
+
const json = JSON.parse(readFileSync(malloyConfig, "utf8"));
|
|
66
|
+
if (json.malloyyo && typeof json.malloyyo === "object") return json.malloyyo;
|
|
67
|
+
} catch {
|
|
68
|
+
}
|
|
15
69
|
}
|
|
16
70
|
const standalone = join(dir, "malloyyo.json");
|
|
17
71
|
if (existsSync(standalone)) {
|
|
18
|
-
|
|
72
|
+
try {
|
|
73
|
+
return JSON.parse(readFileSync(standalone, "utf8"));
|
|
74
|
+
} catch {
|
|
75
|
+
}
|
|
19
76
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
function readSiteConfig(dir) {
|
|
80
|
+
const raw = readMalloyyoBlock(dir);
|
|
81
|
+
if (!raw) return {};
|
|
82
|
+
const { analytics } = parseMalloyyoConfig(raw);
|
|
83
|
+
return analytics ? { analytics } : {};
|
|
23
84
|
}
|
|
24
85
|
var normalizeUrl = (u) => u.replace(/\/+$/, "");
|
|
25
86
|
function resolveTarget(dir, name) {
|
|
@@ -3366,6 +3427,7 @@ async function bundleDashboards(opts = {}) {
|
|
|
3366
3427
|
const outDir = path7.resolve(root, opts.out ?? "docs");
|
|
3367
3428
|
const title = opts.title ?? path7.basename(root);
|
|
3368
3429
|
const target = opts.target ?? "pages";
|
|
3430
|
+
const analytics = opts.analytics ?? readSiteConfig(root).analytics;
|
|
3369
3431
|
const cleanUrls = target === "vercel";
|
|
3370
3432
|
const selfHostDuckdb = opts.duckdb === "bundled";
|
|
3371
3433
|
const runner = await makeRunner(root);
|
|
@@ -3502,9 +3564,9 @@ boot(Dashboard);
|
|
|
3502
3564
|
if (!got.ok) throw new Error(`dashboard ${d.name}: ${got.error}`);
|
|
3503
3565
|
specs = got.givens;
|
|
3504
3566
|
}
|
|
3505
|
-
fs6.writeFileSync(path7.join(outDir, `${d.name}.html`), page(d, dashboards, title, specs, tileSpecs, cleanUrls,
|
|
3567
|
+
fs6.writeFileSync(path7.join(outDir, `${d.name}.html`), page(d, dashboards, title, specs, tileSpecs, cleanUrls, analytics));
|
|
3506
3568
|
}
|
|
3507
|
-
fs6.writeFileSync(path7.join(outDir, "index.html"), indexPage(dashboards, title, !!landing, cleanUrls,
|
|
3569
|
+
fs6.writeFileSync(path7.join(outDir, "index.html"), indexPage(dashboards, title, !!landing, cleanUrls, analytics));
|
|
3508
3570
|
if (landing) {
|
|
3509
3571
|
await esbuild3.build({
|
|
3510
3572
|
stdin: {
|
|
@@ -3542,6 +3604,7 @@ bundled ${dashboards.length} dashboard(s) \u2192 ${path7.relative(process.cwd(),
|
|
|
3542
3604
|
selfHostDuckdb ? ` duckdb ${duck.length} assets (self-hosted)` : ` duckdb jsDelivr CDN (nothing copied)`
|
|
3543
3605
|
);
|
|
3544
3606
|
console.log(` model ${Object.keys(modelFiles).length} .malloy files inlined`);
|
|
3607
|
+
if (analytics) console.log(` analytics ${analytics}`);
|
|
3545
3608
|
if (copiedData.length) {
|
|
3546
3609
|
const mb = copiedData.reduce((a, r) => a + fs6.statSync(path7.join(root, r)).size, 0) / 1048576;
|
|
3547
3610
|
console.log(` data ${copiedData.length} file(s) copied, ${mb.toFixed(1)} MB (same-origin)`);
|
|
@@ -3677,7 +3740,7 @@ async function launchCmd(mode, opts) {
|
|
|
3677
3740
|
}
|
|
3678
3741
|
|
|
3679
3742
|
// package.json
|
|
3680
|
-
var version = "0.2.
|
|
3743
|
+
var version = "0.2.23";
|
|
3681
3744
|
|
|
3682
3745
|
// src/index.ts
|
|
3683
3746
|
function shortSha(sha) {
|
|
@@ -3784,7 +3847,7 @@ program.command("author").option("-C, --root <dir>", "project root (default: cur
|
|
|
3784
3847
|
program.command("test").option("-C, --root <dir>", "project root (default: current directory)").description("launch Claude wired ONLY to the explore surface \u2014 the claude.ai web preview").action(async (opts) => {
|
|
3785
3848
|
await launchCmd("test", opts);
|
|
3786
3849
|
});
|
|
3787
|
-
program.command("dashboard").argument("<action>", "action to run (dev | bundle)").option("-C, --root <dir>", "project root (default: current directory)").option("-p, --port <port>", "port to serve on (dev)", "4173").option("-o, --out <dir>", "output directory (bundle)", "docs").option("--title <title>", "site title (bundle; default: project directory name)").option("--target <target>", "deploy target: pages | vercel (bundle)", "pages").option("--duckdb <source>", "DuckDB binaries: cdn | bundled (bundle)", "cdn").option("--analytics <id>", "
|
|
3850
|
+
program.command("dashboard").argument("<action>", "action to run (dev | bundle)").option("-C, --root <dir>", "project root (default: current directory)").option("-p, --port <port>", "port to serve on (dev)", "4173").option("-o, --out <dir>", "output directory (bundle)", "docs").option("--title <title>", "site title (bundle; default: project directory name)").option("--target <target>", "deploy target: pages | vercel (bundle)", "pages").option("--duckdb <source>", "DuckDB binaries: cdn | bundled (bundle)", "cdn").option("--analytics <id>", "GA4 Measurement ID, overriding malloyyo.analytics in malloy-config.json (bundle)").option("--no-serve", "bundle only; don't serve the result (bundle)").description("preview dashboards locally (dev), or build a static site from them (bundle)").action(
|
|
3788
3851
|
async (action, opts) => {
|
|
3789
3852
|
if (action === "dev") {
|
|
3790
3853
|
await serveDashboard({ root: opts.root, port: Number(opts.port) });
|