@overscore/cli 0.13.8 → 0.13.10

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 CHANGED
@@ -41,10 +41,17 @@ function parseEnv(content) {
41
41
  function safeApiUrl(apiUrl) {
42
42
  try {
43
43
  const h = new URL(apiUrl).hostname;
44
+ // Also allow the configured hub's host — prod by default, or a staging host
45
+ // only if the operator set OVERSCORE_HUB_URL (a trusted, user-set env var).
46
+ // If OVERSCORE_HUB_URL is unset, hubHost === overscore.dev and behavior is
47
+ // identical to before, so real users are unaffected.
48
+ const hubHost = new URL(HUB_URL).hostname;
44
49
  if (h === "overscore.dev" ||
45
50
  h.endsWith(".overscore.dev") ||
46
51
  h === "localhost" ||
47
- h === "127.0.0.1") {
52
+ h === "127.0.0.1" ||
53
+ h === hubHost ||
54
+ h.endsWith("." + hubHost)) {
48
55
  return apiUrl;
49
56
  }
50
57
  }
@@ -599,6 +606,9 @@ async function queryList() {
599
606
  const rowInfo = ds.row_count !== null ? ` (~${ds.row_count.toLocaleString()} rows)` : "";
600
607
  const sampleTag = ds.is_sample ? " [sample]" : "";
601
608
  console.log(` ${ds.name}${rowInfo}${sampleTag}`);
609
+ if (ds.description) {
610
+ console.log(` ${ds.description}`);
611
+ }
602
612
  if (ds.columns && ds.columns.length > 0) {
603
613
  const cols = ds.columns.map((c) => `${c.name} (${c.type})`).join(", ");
604
614
  console.log(` columns: ${cols}`);
@@ -631,6 +641,9 @@ async function queryShow(name) {
631
641
  }
632
642
  if (query.source === "dataset" && query.dataset_name) {
633
643
  console.log(` source: uploaded dataset (${query.dataset_name})`);
644
+ if (query.dataset_description) {
645
+ console.log(` ${query.dataset_description}`);
646
+ }
634
647
  }
635
648
  console.log();
636
649
  if (query.source === "dataset") {
@@ -911,8 +924,8 @@ async function pull(slug) {
911
924
  process.exit(1);
912
925
  }
913
926
  }
914
- const apiUrl = "https://overscore.dev/api";
915
- const baseUrl = apiUrl.replace(/\/api$/, "");
927
+ const apiUrl = `${HUB_URL}/api`;
928
+ const baseUrl = HUB_URL;
916
929
  const versionQuery = versionParam ? `?version=${versionParam}` : "";
917
930
  const url = `${baseUrl}/api/dashboards/${slug}/source${versionQuery}`;
918
931
  console.log(`\n Pulling source for: ${slug}${versionParam ? ` (v${versionParam})` : ""}...`);
@@ -963,7 +976,7 @@ async function pull(slug) {
963
976
  const envContent = `# Overscore Configuration
964
977
  VITE_OVERSCORE_PROJECT_SLUG=${projectSlug}
965
978
  VITE_OVERSCORE_DASHBOARD_SLUG=${dashboardSlug}
966
- VITE_OVERSCORE_API_URL=https://overscore.dev/api
979
+ VITE_OVERSCORE_API_URL=${HUB_URL}/api
967
980
  `;
968
981
  fs.writeFileSync(path.join(targetDir, ".env"), envContent, { mode: 0o600 });
969
982
  const rulesDir = path.join(targetDir, ".claude", "rules");
@@ -1125,7 +1138,23 @@ function collectFiles(dir, prefix) {
1125
1138
  return files;
1126
1139
  }
1127
1140
  // ── Analysis commands ──────────────────────────────────────────────
1128
- const HUB_URL = "https://overscore.dev";
1141
+ // Hub the CLI talks to. Defaults to production. A TRUSTED override — the
1142
+ // OVERSCORE_HUB_URL env var, set deliberately by the operator (e.g. to point at
1143
+ // a staging environment during a security audit) — can repoint it. This is
1144
+ // distinct from the project-.env override (VITE_OVERSCORE_API_URL), which stays
1145
+ // restricted by safeApiUrl() so a poisoned project can't redirect the API key +
1146
+ // bundle to an attacker host (audit L6).
1147
+ const HUB_URL = (process.env.OVERSCORE_HUB_URL || "https://overscore.dev").replace(/\/+$/, "");
1148
+ // Bare host of the hub (overscore.dev, or overscore-test.com on staging) for
1149
+ // building the {slug}.<host> URLs we print back to the user.
1150
+ const HUB_HOST = (() => {
1151
+ try {
1152
+ return new URL(HUB_URL).hostname;
1153
+ }
1154
+ catch {
1155
+ return "overscore.dev";
1156
+ }
1157
+ })();
1129
1158
  function slugify(input) {
1130
1159
  return input
1131
1160
  .toLowerCase()
@@ -1792,7 +1821,7 @@ async function analysisNew(title) {
1792
1821
  npx @overscore/cli analysis publish
1793
1822
 
1794
1823
  The analysis will go live at:
1795
- https://${data.project_slug}.overscore.dev/analysis/${data.slug}
1824
+ https://${data.project_slug}.${HUB_HOST}/analysis/${data.slug}
1796
1825
  `);
1797
1826
  }
1798
1827
  function loadAnalysisMetadata() {
@@ -2385,7 +2414,7 @@ async function dev() {
2385
2414
  apiKey = keyData.raw_key ?? null;
2386
2415
  }
2387
2416
  catch {
2388
- console.error("\n Error: Could not reach overscore.dev to create dev session key.\n");
2417
+ console.error(`\n Error: Could not reach ${HUB_HOST} to create dev session key.\n`);
2389
2418
  process.exit(1);
2390
2419
  }
2391
2420
  if (!apiKey) {
@@ -2644,7 +2673,7 @@ async function templatePull(slug) {
2644
2673
  ? apiSlug.slice(apiSlug.indexOf("_") + 1)
2645
2674
  : apiSlug;
2646
2675
  const targetDir = path.resolve(process.cwd(), process.argv[5] || localSlug);
2647
- const url = `https://overscore.dev/api/templates/${apiSlug}/source`;
2676
+ const url = `${HUB_URL}/api/templates/${apiSlug}/source`;
2648
2677
  console.log(`\n Pulling template: ${slug}...`);
2649
2678
  let res;
2650
2679
  try {
@@ -2663,7 +2692,7 @@ async function templatePull(slug) {
2663
2692
  });
2664
2693
  }
2665
2694
  catch {
2666
- console.error(`\n Error: Could not reach overscore.dev\n`);
2695
+ console.error(`\n Error: Could not reach ${HUB_HOST}\n`);
2667
2696
  process.exit(1);
2668
2697
  }
2669
2698
  if (!res.ok) {
@@ -34,7 +34,8 @@
34
34
  import fs from "fs";
35
35
  import path from "path";
36
36
  import { execSync } from "child_process";
37
- const HUB_URL = "https://overscore.dev";
37
+ // Trusted operator override (e.g. staging audit); defaults to production.
38
+ const HUB_URL = (process.env.OVERSCORE_HUB_URL || "https://overscore.dev").replace(/\/+$/, "");
38
39
  // Mirrors the templates_slug_format CHECK in the marketplace migration.
39
40
  // `_` is the handle namespace delimiter in the stored slug ({handle}_{local}).
40
41
  const TEMPLATE_SLUG_RE = /^[a-z0-9]([a-z0-9_-]*[a-z0-9])?$/;
@@ -263,7 +264,7 @@ export async function templatePush(slugArg) {
263
264
  });
264
265
  }
265
266
  catch {
266
- console.error(`\n Error: Could not reach overscore.dev\n`);
267
+ console.error(`\n Error: Could not reach ${new URL(HUB_URL).hostname}\n`);
267
268
  process.exit(1);
268
269
  }
269
270
  const data = (await res.json().catch(() => ({})));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@overscore/cli",
3
- "version": "0.13.8",
3
+ "version": "0.13.10",
4
4
  "description": "CLI for deploying Overscore dashboards and publishing analyses",
5
5
  "bin": {
6
6
  "overscore": "dist/index.js"