@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 +3 -3
- package/src/commands/add.ts +6 -5
- package/src/commands/create.ts +11 -10
- package/src/commands/publish.ts +8 -7
- package/src/utils/prompt.ts +9 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glasshome/widget-cli",
|
|
3
|
-
"version": "0.13.
|
|
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": "
|
|
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.
|
|
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",
|
package/src/commands/add.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
|
-
import { cancel,
|
|
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 (
|
|
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 (
|
|
91
|
+
if (cancelled(description)) {
|
|
91
92
|
cancel("Operation cancelled.");
|
|
92
93
|
return null;
|
|
93
94
|
}
|
|
94
95
|
|
|
95
96
|
return {
|
|
96
|
-
widgetName
|
|
97
|
-
description
|
|
97
|
+
widgetName,
|
|
98
|
+
description,
|
|
98
99
|
};
|
|
99
100
|
}
|
|
100
101
|
|
package/src/commands/create.ts
CHANGED
|
@@ -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,
|
|
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 (
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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 (!
|
|
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 (!
|
|
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 (
|
|
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"));
|
package/src/commands/publish.ts
CHANGED
|
@@ -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,
|
|
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 (
|
|
88
|
+
if (cancelled(choice)) {
|
|
88
89
|
cancel("Publish cancelled.");
|
|
89
90
|
process.exit(0);
|
|
90
91
|
}
|
|
91
92
|
|
|
92
|
-
scope = choice
|
|
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 (
|
|
125
|
+
if (cancelled(selected)) {
|
|
125
126
|
cancel("Publish cancelled.");
|
|
126
127
|
process.exit(0);
|
|
127
128
|
}
|
|
128
|
-
widgetName = selected
|
|
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 (
|
|
152
|
+
if (cancelled(choice)) {
|
|
152
153
|
cancel("Publish cancelled.");
|
|
153
154
|
process.exit(0);
|
|
154
155
|
}
|
|
155
|
-
bump = choice
|
|
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
|
+
}
|