@datashow/super-visual-cli 0.1.0-rc.1 → 0.1.0-rc.2

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.
@@ -1,9 +1,16 @@
1
1
  #!/usr/bin/env node
2
- import { main } from "../src/main.mjs";
2
+ import { main, stopActiveProgress } from "../src/main.mjs";
3
3
 
4
4
  main().catch((error) => {
5
+ stopActiveProgress();
5
6
  const json = process.argv.includes("--json");
6
7
  const message = error instanceof Error ? error.message : String(error);
7
- process.stderr.write(`${json ? JSON.stringify({ ok: false, error: message }) : `supervisual: ${message}`}\n`);
8
+ const summary = error?.summary ?? "Super Visual could not complete the command.";
9
+ const guidance = error?.guidance;
10
+ if (json) {
11
+ process.stderr.write(`${JSON.stringify({ ok: false, message: summary, ...(guidance ? { guidance } : {}), error: message })}\n`);
12
+ } else {
13
+ process.stderr.write(`\n${summary}\n${guidance ? `${guidance}\n` : ""}\nTechnical details: ${message}\n`);
14
+ }
8
15
  process.exitCode = 1;
9
16
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datashow/super-visual-cli",
3
- "version": "0.1.0-rc.1",
3
+ "version": "0.1.0-rc.2",
4
4
  "description": "CLI for validating, compiling, packaging, verifying, and deploying Super Visual projects.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -25,10 +25,10 @@
25
25
  "access": "public"
26
26
  },
27
27
  "dependencies": {
28
- "@datashow/super-visual-adapter-claude-dashboard": "0.1.0-rc.1",
29
- "@datashow/super-visual-compiler": "0.1.0-rc.1",
30
- "@datashow/super-visual-contracts": "0.1.0-rc.1",
31
- "@datashow/super-visual-fabric": "0.1.0-rc.1",
28
+ "@datashow/super-visual-adapter-claude-dashboard": "0.1.0-rc.2",
29
+ "@datashow/super-visual-compiler": "0.1.0-rc.2",
30
+ "@datashow/super-visual-contracts": "0.1.0-rc.2",
31
+ "@datashow/super-visual-fabric": "0.1.0-rc.2",
32
32
  "@fontsource/source-serif-4": "5.3.1",
33
33
  "@nivo/bar": "0.99.0",
34
34
  "@nivo/line": "0.99.0",
package/src/main.mjs CHANGED
@@ -15,7 +15,29 @@ import { resolveProjectTarget, targetUpdate, writeProjectTarget } from "./projec
15
15
  import { runSemanticPreviewTest, startSemanticPreview } from "./semantic-preview.mjs";
16
16
 
17
17
  const run = promisify(execFile);
18
- const VERSION = "0.1.0-rc.1";
18
+ const VERSION = "0.1.0-rc.2";
19
+ const FABRIC_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
20
+ const SPINNER_FRAMES = ["|", "/", "-", "\\"];
21
+ let activeProgress = null;
22
+
23
+ export class CliUserError extends Error {
24
+ constructor(message, { summary, guidance } = {}) {
25
+ super(message);
26
+ this.name = "CliUserError";
27
+ this.summary = summary;
28
+ this.guidance = guidance;
29
+ }
30
+ }
31
+
32
+ export function validateFabricId(value, optionName) {
33
+ if (value === undefined) return;
34
+ if (FABRIC_ID_PATTERN.test(value)) return;
35
+ const target = optionName === "--workspace-id" ? "workspace" : "semantic model";
36
+ throw new CliUserError(`${optionName} must be a 36-character GUID in 8-4-4-4-12 format; received "${value}" (${String(value).length} characters).`, {
37
+ summary: `Super Visual could not initialize the project because the ${target} ID is not valid.`,
38
+ guidance: `Copy the complete ${target} ID from Fabric and run the command again.`,
39
+ });
40
+ }
19
41
 
20
42
  function projectFile(input = ".") {
21
43
  const resolved = path.resolve(input);
@@ -26,7 +48,29 @@ function output(value, json) {
26
48
  process.stdout.write(`${json ? JSON.stringify(value) : typeof value === "string" ? value : JSON.stringify(value, null, 2)}\n`);
27
49
  }
28
50
 
51
+ export function stopActiveProgress() {
52
+ if (!activeProgress) return;
53
+ clearInterval(activeProgress.timer);
54
+ process.stdout.write(`\r${" ".repeat(activeProgress.width)}\r`);
55
+ activeProgress = null;
56
+ }
57
+
29
58
  function writeInitProgress(event) {
59
+ if (event.status === "running" && process.stdout.isTTY) {
60
+ stopActiveProgress();
61
+ let frame = 0;
62
+ const render = () => {
63
+ const line = `${SPINNER_FRAMES[frame % SPINNER_FRAMES.length]} ${event.message}`;
64
+ process.stdout.write(`\r${line}`);
65
+ activeProgress.width = Math.max(activeProgress.width, line.length);
66
+ frame += 1;
67
+ };
68
+ activeProgress = { timer: null, width: event.message.length + 2 };
69
+ render();
70
+ activeProgress.timer = setInterval(render, 80);
71
+ return;
72
+ }
73
+ stopActiveProgress();
30
74
  const marker = event.status === "passed" ? "✓" : "…";
31
75
  process.stdout.write(`${marker} ${event.message}\n`);
32
76
  }
@@ -275,13 +319,23 @@ function createProgram() {
275
319
  .option("--force", "write into an existing empty directory")
276
320
  .action(async (directory, options, command) => {
277
321
  if ((options.workspaceName || options.semanticModelId || options.reportName || options.connectionId) && !options.workspaceId) throw new Error("--workspace-id is required when saving a Fabric binding");
322
+ validateFabricId(options.workspaceId, "--workspace-id");
323
+ validateFabricId(options.semanticModelId, "--semantic-model-id");
278
324
  const json = jsonEnabled(command);
279
325
  if (!json) process.stdout.write(`\nSuper Visual init\n\n`);
280
326
  let liveValidation = null;
281
327
  if (options.workspaceId && options.semanticModelId && !options.skipLiveValidation) {
282
328
  if (!json) writeInitProgress({ status: "running", message: "Verifying the Fabric workspace and Power BI semantic model (read-only)" });
283
- const client = new FabricHttpClient({ timeoutSeconds: Number(options.timeout) });
284
- const inspected = await inspectSemanticModel({ client, workspaceId: options.workspaceId, workspaceName: options.workspaceName, semanticModelId: options.semanticModelId });
329
+ let inspected;
330
+ try {
331
+ const client = new FabricHttpClient({ timeoutSeconds: Number(options.timeout) });
332
+ inspected = await inspectSemanticModel({ client, workspaceId: options.workspaceId, workspaceName: options.workspaceName, semanticModelId: options.semanticModelId });
333
+ } catch (error) {
334
+ throw new CliUserError(error instanceof Error ? error.message : String(error), {
335
+ summary: "Super Visual could not verify the Fabric workspace and semantic model.",
336
+ guidance: "Confirm that you are signed in, can access the workspace, and copied both IDs from the same Fabric workspace.",
337
+ });
338
+ }
285
339
  liveValidation = {
286
340
  ok: true,
287
341
  status: "passed",
@@ -10,6 +10,6 @@
10
10
  "verify": "supervisual verify ."
11
11
  },
12
12
  "devDependencies": {
13
- "@datashow/super-visual-cli": "0.1.0-rc.1"
13
+ "@datashow/super-visual-cli": "0.1.0-rc.2"
14
14
  }
15
15
  }
@@ -10,6 +10,6 @@
10
10
  "verify": "supervisual verify ."
11
11
  },
12
12
  "devDependencies": {
13
- "@datashow/super-visual-cli": "0.1.0-rc.1"
13
+ "@datashow/super-visual-cli": "0.1.0-rc.2"
14
14
  }
15
15
  }