@glasshome/widget-cli 0.13.3 → 0.13.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glasshome/widget-cli",
3
- "version": "0.13.3",
3
+ "version": "0.13.4",
4
4
  "description": "CLI for creating and managing GlassHome widgets",
5
5
  "type": "module",
6
6
  "bin": {
@@ -18,7 +18,7 @@
18
18
  ],
19
19
  "devDependencies": {
20
20
  "@iconify/types": "^2.0.0",
21
- "@types/bun": "latest",
21
+ "@types/bun": "^1.4.0",
22
22
  "@types/semver": "^7.0.0",
23
23
  "playwright": "^1.40.0",
24
24
  "typescript": "^7.0.2"
@@ -30,7 +30,7 @@
30
30
  "@fontsource-variable/geist-mono": "^5.2.8",
31
31
  "@glasshome/sync-layer": "0.8.1",
32
32
  "@glasshome/widget-contract": "0.2.1",
33
- "@glasshome/widget-sdk": "1.14.3",
33
+ "@glasshome/widget-sdk": "1.15.1",
34
34
  "@iconify-json/lucide": "^1.2.0",
35
35
  "@iconify-json/mdi": "^1.2.3",
36
36
  "@tailwindcss/vite": "^4.1.13",
@@ -1,6 +1,7 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { resolve } from "node:path";
3
- import { cancel, isCancel, log, text } from "@clack/prompts";
3
+ import { cancel, log, text } from "@clack/prompts";
4
+ import { cancelled } from "../utils/prompt";
4
5
  import { defaultSdkRange, FALLBACK_SDK_RANGE } from "../utils/sdk-version";
5
6
 
6
7
  /** Capitalize kebab-case into PascalCase for component names. */
@@ -77,7 +78,7 @@ export async function promptWidgetDetails(defaults?: { widgetName?: string }): P
77
78
  return "Name must be lowercase alphanumeric with optional hyphens";
78
79
  },
79
80
  });
80
- if (isCancel(widgetName)) {
81
+ if (cancelled(widgetName)) {
81
82
  cancel("Operation cancelled.");
82
83
  return null;
83
84
  }
@@ -87,14 +88,14 @@ export async function promptWidgetDetails(defaults?: { widgetName?: string }): P
87
88
  placeholder: "A GlassHome dashboard widget",
88
89
  defaultValue: "",
89
90
  });
90
- if (isCancel(description)) {
91
+ if (cancelled(description)) {
91
92
  cancel("Operation cancelled.");
92
93
  return null;
93
94
  }
94
95
 
95
96
  return {
96
- widgetName: widgetName as string,
97
- description: description as string,
97
+ widgetName,
98
+ description,
98
99
  };
99
100
  }
100
101
 
@@ -9,8 +9,9 @@ import {
9
9
  writeFileSync,
10
10
  } from "node:fs";
11
11
  import { dirname, join, resolve } from "node:path";
12
- import { cancel, confirm, isCancel, log, note, spinner, text } from "@clack/prompts";
12
+ import { cancel, confirm, log, note, spinner, text } from "@clack/prompts";
13
13
  import color from "picocolors";
14
+ import { cancelled } from "../utils/prompt";
14
15
  import { defaultSdkRange, FALLBACK_SDK_RANGE } from "../utils/sdk-version";
15
16
  import { getCliVersion } from "../utils/version";
16
17
  import { promptWidgetDetails, scaffoldWidget } from "./add";
@@ -59,7 +60,7 @@ export async function runCreate() {
59
60
  },
60
61
  });
61
62
 
62
- if (isCancel(projectName)) {
63
+ if (cancelled(projectName)) {
63
64
  cancel("Operation cancelled.");
64
65
  process.exit(0);
65
66
  }
@@ -70,7 +71,7 @@ export async function runCreate() {
70
71
  defaultValue: "",
71
72
  });
72
73
 
73
- if (isCancel(projectDescription)) {
74
+ if (cancelled(projectDescription)) {
74
75
  cancel("Operation cancelled.");
75
76
  process.exit(0);
76
77
  }
@@ -80,7 +81,7 @@ export async function runCreate() {
80
81
  const widgetDetails = await promptWidgetDetails();
81
82
  if (!widgetDetails) process.exit(0);
82
83
 
83
- const targetDir = resolve(process.cwd(), projectName as string);
84
+ const targetDir = resolve(process.cwd(), projectName);
84
85
 
85
86
  if (existsSync(targetDir)) {
86
87
  cancel(`Directory "${projectName}" already exists.`);
@@ -115,7 +116,7 @@ export async function runCreate() {
115
116
  }
116
117
 
117
118
  const projectDesc =
118
- (projectDescription as string) || `A GlassHome widget project: ${projectName}`;
119
+ projectDescription || `A GlassHome widget project: ${projectName}`;
119
120
 
120
121
  // Replace project-level placeholders in package.json. Pin the CLI to the
121
122
  // version that scaffolded the project (caret) so `bun widget` resolves the
@@ -123,7 +124,7 @@ export async function runCreate() {
123
124
  // stale global/bunx copy.
124
125
  const pkgPath = join(targetDir, "package.json");
125
126
  let pkgContent = readFileSync(pkgPath, "utf-8");
126
- pkgContent = pkgContent.replace(/PROJECT_NAME/g, projectName as string);
127
+ pkgContent = pkgContent.replace(/PROJECT_NAME/g, projectName);
127
128
  pkgContent = pkgContent.replace(/PROJECT_DESCRIPTION/g, projectDesc);
128
129
  pkgContent = pkgContent.replace(/CLI_VERSION/g, `^${getCliVersion()}`);
129
130
  // Nothing is installed yet, so this comes from the SDK the CLI ships
@@ -134,7 +135,7 @@ export async function runCreate() {
134
135
  // Replace project-level placeholders in README.md
135
136
  const readmePath = join(targetDir, "README.md");
136
137
  let readmeContent = readFileSync(readmePath, "utf-8");
137
- readmeContent = readmeContent.replace(/PROJECT_NAME/g, projectName as string);
138
+ readmeContent = readmeContent.replace(/PROJECT_NAME/g, projectName);
138
139
  readmeContent = readmeContent.replace(/PROJECT_DESCRIPTION/g, projectDesc);
139
140
  writeFileSync(readmePath, readmeContent);
140
141
 
@@ -153,7 +154,7 @@ export async function runCreate() {
153
154
  initialValue: true,
154
155
  });
155
156
 
156
- if (!isCancel(shouldInstall) && shouldInstall) {
157
+ if (!cancelled(shouldInstall) && shouldInstall) {
157
158
  const installSpinner = spinner();
158
159
  installSpinner.start("Installing dependencies...");
159
160
  const installProc = Bun.spawnSync(["bun", "install"], { cwd: installCwd });
@@ -179,7 +180,7 @@ export async function runCreate() {
179
180
  initialValue: true,
180
181
  });
181
182
 
182
- if (!isCancel(shouldGit) && shouldGit) {
183
+ if (!cancelled(shouldGit) && shouldGit) {
183
184
  const gitSpinner = spinner();
184
185
  gitSpinner.start("Initializing git repository...");
185
186
  const initProc = Bun.spawnSync(["git", "init"], { cwd: targetDir });
@@ -201,7 +202,7 @@ export async function runCreate() {
201
202
  steps.push(color.cyan(`cd ${projectName}`));
202
203
  } else {
203
204
  steps.push(color.cyan(`cd ${projectName}`));
204
- if (isCancel(shouldInstall) || !shouldInstall) steps.push(color.cyan("bun install"));
205
+ if (cancelled(shouldInstall) || !shouldInstall) steps.push(color.cyan("bun install"));
205
206
  }
206
207
  steps.push(cmd("bun widget connect <url>", "connect to a dashboard for live testing"));
207
208
  steps.push(cmd("bun widget add", "add another widget"));
@@ -1,10 +1,11 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { existsSync, readFileSync } from "node:fs";
3
3
  import { resolve } from "node:path";
4
- import { cancel, isCancel, log, select, spinner } from "@clack/prompts";
4
+ import { cancel, log, select, spinner } from "@clack/prompts";
5
5
  import semver from "semver";
6
6
  import { getHubUrl, getToken } from "../utils/auth";
7
7
  import { confirmPublish, fetchScopes, requestPublish, uploadToR2 } from "../utils/hub-api";
8
+ import { cancelled } from "../utils/prompt";
8
9
  import {
9
10
  discoverWidgets,
10
11
  formatBytes,
@@ -84,12 +85,12 @@ export async function runPublish(
84
85
  })),
85
86
  });
86
87
 
87
- if (isCancel(choice)) {
88
+ if (cancelled(choice)) {
88
89
  cancel("Publish cancelled.");
89
90
  process.exit(0);
90
91
  }
91
92
 
92
- scope = choice as string;
93
+ scope = choice;
93
94
  }
94
95
 
95
96
  // Step 4: Select widget
@@ -121,11 +122,11 @@ export async function runPublish(
121
122
  options: widgetOptions,
122
123
  });
123
124
 
124
- if (isCancel(selected)) {
125
+ if (cancelled(selected)) {
125
126
  cancel("Publish cancelled.");
126
127
  process.exit(0);
127
128
  }
128
- widgetName = selected as string;
129
+ widgetName = selected;
129
130
  }
130
131
 
131
132
  const manifest = readManifest(cwd, widgetName);
@@ -148,11 +149,11 @@ export async function runPublish(
148
149
  ],
149
150
  });
150
151
 
151
- if (isCancel(choice)) {
152
+ if (cancelled(choice)) {
152
153
  cancel("Publish cancelled.");
153
154
  process.exit(0);
154
155
  }
155
- bump = choice as string;
156
+ bump = choice;
156
157
  }
157
158
 
158
159
  let version = currentVersion;
@@ -0,0 +1,9 @@
1
+ import { isCancel } from "@clack/prompts";
2
+
3
+ /**
4
+ * `isCancel` is typed `value is typeof CANCEL_SYMBOL` while the prompts return
5
+ * `string | symbol`, so excluding one unique symbol narrows nothing.
6
+ */
7
+ export function cancelled(value: unknown): value is symbol {
8
+ return isCancel(value);
9
+ }