@glasshome/widget-cli 0.10.6 → 0.11.0

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/bin/cli.ts CHANGED
@@ -33,7 +33,7 @@ Commands:
33
33
  publish [hub-url] Build and publish a widget to Hub
34
34
  login [hub-url] Authenticate with GlassHome Hub
35
35
  info [name] Show widget metadata and bundle info
36
- upgrade Upgrade @glasshome/widget-sdk to latest version
36
+ upgrade Upgrade @glasshome/widget-sdk (latest, or --to <version>) and sync manifests
37
37
  migrate config Rewrite widgets' raw-zod config to defineConfig + field.*
38
38
  --name <widget> targets one; --dry previews without writing
39
39
  help Show this help message
@@ -56,6 +56,7 @@ Examples:
56
56
  glasshome-widget login
57
57
  glasshome-widget login https://my-hub.example.com
58
58
  glasshome-widget upgrade
59
+ glasshome-widget upgrade --to 1.10.3
59
60
  glasshome-widget publish --dir packages/widgets
60
61
  `.trim();
61
62
 
@@ -68,6 +69,7 @@ const { values: flags, positionals } = parseArgs({
68
69
  name: { type: "string" },
69
70
  bump: { type: "string" },
70
71
  scope: { type: "string" },
72
+ to: { type: "string" },
71
73
  "re-auth": { type: "boolean" },
72
74
  isolate: { type: "boolean" },
73
75
  dry: { type: "boolean" },
@@ -193,7 +195,7 @@ switch (effectiveCommand) {
193
195
 
194
196
  case "upgrade": {
195
197
  const { runUpgrade } = await import("../src/commands/upgrade");
196
- await runUpgrade(resolveWidgetDir());
198
+ await runUpgrade(resolveWidgetDir(), { to: str(flags.to) });
197
199
  outro("Done");
198
200
  break;
199
201
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glasshome/widget-cli",
3
- "version": "0.10.6",
3
+ "version": "0.11.0",
4
4
  "description": "CLI for creating and managing GlassHome widgets",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,20 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { sdkDependencySection } from "./upgrade";
3
+
4
+ describe("sdkDependencySection", () => {
5
+ test("finds the SDK in whichever section declares it", () => {
6
+ expect(sdkDependencySection({ peerDependencies: { "@glasshome/widget-sdk": "^1.10.2" } })).toBe(
7
+ "peerDependencies",
8
+ );
9
+ expect(sdkDependencySection({ devDependencies: { "@glasshome/widget-sdk": "^1.10.2" } })).toBe(
10
+ "devDependencies",
11
+ );
12
+ expect(sdkDependencySection({ dependencies: { "@glasshome/widget-sdk": "^1.10.2" } })).toBe(
13
+ "dependencies",
14
+ );
15
+ });
16
+
17
+ test("returns null when the SDK is not declared", () => {
18
+ expect(sdkDependencySection({ dependencies: { zod: "^4" } })).toBeNull();
19
+ });
20
+ });
@@ -1,6 +1,6 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
2
  import { dirname, join, resolve } from "node:path";
3
- import { log, note, spinner } from "@clack/prompts";
3
+ import { log, spinner } from "@clack/prompts";
4
4
  import { discoverWidgets, readManifest, writeManifest } from "../utils/manifest";
5
5
  import { getInstalledSdkVersion } from "../utils/sdk-version";
6
6
  import { runValidate } from "./validate";
@@ -58,20 +58,60 @@ function syncManifestSdkVersions(cwd: string, newVersion: string): void {
58
58
  log.info(`Updated sdkVersion to ${sdkRange} in ${widgets.length} manifest(s)`);
59
59
  }
60
60
 
61
- export async function runUpgrade(cwd: string): Promise<void> {
61
+ const SDK_PKG = "@glasshome/widget-sdk";
62
+
63
+ type DependencySection = "peerDependencies" | "devDependencies" | "dependencies";
64
+ type PackageManifest = Partial<Record<DependencySection, Record<string, string>>>;
65
+
66
+ const SECTION_FLAG: Record<DependencySection, string[]> = {
67
+ peerDependencies: ["--peer"],
68
+ devDependencies: ["--dev"],
69
+ dependencies: [],
70
+ };
71
+
72
+ /** Which section declares the SDK, so the bump lands where the author put it. */
73
+ export function sdkDependencySection(pkg: PackageManifest): DependencySection | null {
74
+ const sections: DependencySection[] = ["peerDependencies", "devDependencies", "dependencies"];
75
+ return sections.find((section) => pkg[section]?.[SDK_PKG] !== undefined) ?? null;
76
+ }
77
+
78
+ /**
79
+ * Standalone project: `bun add` the SDK at the requested version (default
80
+ * latest) into the section that already declares it. Bun installs the SDK's
81
+ * required peers alongside, so @glasshome/ui follows without a second step.
82
+ */
83
+ function bumpSdkDependency(cwd: string, section: DependencySection, target: string): boolean {
84
+ const s = spinner();
85
+ s.start(`Installing ${SDK_PKG}@${target}...`);
86
+ const proc = Bun.spawnSync(["bun", "add", ...SECTION_FLAG[section], `${SDK_PKG}@${target}`], {
87
+ cwd,
88
+ });
89
+ if (proc.exitCode !== 0) {
90
+ s.stop("Install failed");
91
+ log.error(proc.stderr.toString());
92
+ return false;
93
+ }
94
+ s.stop(`Installed ${SDK_PKG}@${target}`);
95
+ return true;
96
+ }
97
+
98
+ export interface UpgradeOptions {
99
+ /** Version or dist-tag to move to in a standalone project. Default "latest". */
100
+ to?: string;
101
+ }
102
+
103
+ export async function runUpgrade(cwd: string, options: UpgradeOptions = {}): Promise<void> {
62
104
  const pkgPath = resolve(cwd, "package.json");
63
105
  if (!existsSync(pkgPath)) {
64
106
  log.error("No package.json found in current directory.");
65
107
  process.exit(1);
66
108
  }
67
109
 
68
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
69
- const currentVersion =
70
- pkg.peerDependencies?.["@glasshome/widget-sdk"] ??
71
- pkg.devDependencies?.["@glasshome/widget-sdk"] ??
72
- pkg.dependencies?.["@glasshome/widget-sdk"];
110
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8")) as PackageManifest;
111
+ const section = sdkDependencySection(pkg);
112
+ const currentVersion = section ? pkg[section]?.[SDK_PKG] : undefined;
73
113
 
74
- if (!currentVersion) {
114
+ if (!section || !currentVersion) {
75
115
  log.error("@glasshome/widget-sdk is not listed in dependencies or peerDependencies.");
76
116
  process.exit(1);
77
117
  }
@@ -125,27 +165,21 @@ export async function runUpgrade(cwd: string): Promise<void> {
125
165
  return;
126
166
  }
127
167
 
128
- // Standalone project. Bumping the dependency is still the author's call, but
129
- // syncing the manifests to whatever is installed is not: a manifest range
130
- // that excludes the installed SDK fails validation, and this is the command
131
- // that error tells people to run.
168
+ // Standalone project: bump the dependency, then sync every manifest to what
169
+ // is now installed. A manifest range that excludes the installed SDK fails
170
+ // validation, and this is the command that error tells people to run.
171
+ if (!bumpSdkDependency(cwd, section, options.to ?? "latest")) process.exit(1);
172
+
132
173
  const installed = getInstalledSdkVersion(cwd);
133
- if (installed) {
134
- syncManifestSdkVersions(cwd, installed);
135
- const valid = await runValidate(cwd);
136
- if (!valid) log.warn(`Synced manifests to ${installed}, but validation found problems above.`);
137
- } else {
174
+ if (!installed) {
138
175
  log.warn("No @glasshome/widget-sdk installed here, so manifests were left alone.");
176
+ return;
177
+ }
178
+ syncManifestSdkVersions(cwd, installed);
179
+ const valid = await runValidate(cwd);
180
+ if (valid) {
181
+ log.success(`Upgraded to @glasshome/widget-sdk@${installed}`);
182
+ } else {
183
+ log.warn(`Upgraded to ${installed}, but validation found problems above.`);
139
184
  }
140
-
141
- log.info("To move to a different SDK version:");
142
- note(
143
- [
144
- "1. Bump @glasshome/widget-sdk in package.json peerDependencies",
145
- "2. bun install",
146
- "3. bun widget upgrade (sync manifest files)",
147
- "4. bun widget validate (check compatibility)",
148
- ].join("\n"),
149
- "To upgrade",
150
- );
151
185
  }