@glasshome/widget-cli 0.4.11 → 0.4.13
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 +12 -5
- package/package.json +1 -1
- package/src/commands/connect.ts +18 -9
package/bin/cli.ts
CHANGED
|
@@ -25,6 +25,7 @@ Commands:
|
|
|
25
25
|
add Add a new widget to the project
|
|
26
26
|
build Build all widgets (per-widget, self-contained bundles)
|
|
27
27
|
connect <url> Connect to a running dashboard for live testing
|
|
28
|
+
--re-auth discards stored credentials and re-runs device approval
|
|
28
29
|
validate [name] Validate all widgets or a specific one
|
|
29
30
|
publish [hub-url] Build and publish a widget to Hub
|
|
30
31
|
login [hub-url] Authenticate with GlassHome Hub
|
|
@@ -60,13 +61,19 @@ const { values: flags, positionals } = parseArgs({
|
|
|
60
61
|
name: { type: "string" },
|
|
61
62
|
bump: { type: "string" },
|
|
62
63
|
scope: { type: "string" },
|
|
64
|
+
"re-auth": { type: "boolean" },
|
|
63
65
|
help: { type: "boolean", short: "h" },
|
|
64
66
|
},
|
|
65
67
|
allowPositionals: true,
|
|
66
68
|
strict: false,
|
|
67
69
|
});
|
|
68
70
|
|
|
69
|
-
|
|
71
|
+
// strict:false widens every flag to string | boolean | undefined; a bare
|
|
72
|
+
// `--flag` with no value parses as `true`, which no string option accepts.
|
|
73
|
+
const str = (v: string | boolean | undefined): string | undefined =>
|
|
74
|
+
typeof v === "string" ? v : undefined;
|
|
75
|
+
|
|
76
|
+
const explicitDir = str(flags.dir);
|
|
70
77
|
const [command, ...args] = positionals;
|
|
71
78
|
|
|
72
79
|
if (command === "help" || flags.help) {
|
|
@@ -114,7 +121,7 @@ switch (effectiveCommand) {
|
|
|
114
121
|
process.exit(1);
|
|
115
122
|
}
|
|
116
123
|
const { runConnect } = await import("../src/commands/connect");
|
|
117
|
-
await runConnect(url, resolveWidgetDir());
|
|
124
|
+
await runConnect(url, resolveWidgetDir(), { reAuth: flags["re-auth"] === true });
|
|
118
125
|
break;
|
|
119
126
|
}
|
|
120
127
|
|
|
@@ -144,9 +151,9 @@ switch (effectiveCommand) {
|
|
|
144
151
|
const hubUrlArg = args[0];
|
|
145
152
|
const { runPublish } = await import("../src/commands/publish");
|
|
146
153
|
await runPublish(resolveWidgetDir(), hubUrlArg, {
|
|
147
|
-
name: flags.name,
|
|
148
|
-
bump: flags.bump as "keep" | "patch" | "minor" | "major" | undefined,
|
|
149
|
-
scope: flags.scope,
|
|
154
|
+
name: str(flags.name),
|
|
155
|
+
bump: str(flags.bump) as "keep" | "patch" | "minor" | "major" | undefined,
|
|
156
|
+
scope: str(flags.scope),
|
|
150
157
|
});
|
|
151
158
|
outro("Done");
|
|
152
159
|
break;
|
package/package.json
CHANGED
package/src/commands/connect.ts
CHANGED
|
@@ -87,7 +87,11 @@ async function uploadAllWidgets(apiUrl: string, distDir: string, token: string):
|
|
|
87
87
|
return slugs;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
export async function runConnect(
|
|
90
|
+
export async function runConnect(
|
|
91
|
+
apiUrl: string,
|
|
92
|
+
cwd: string,
|
|
93
|
+
opts: { reAuth?: boolean } = {},
|
|
94
|
+
): Promise<void> {
|
|
91
95
|
const distDir = resolve(cwd, "dist");
|
|
92
96
|
const solid = (await import("vite-plugin-solid")).default;
|
|
93
97
|
const buildOpts = { srcDir: "src", outDir: "dist", plugins: [solid()] };
|
|
@@ -119,6 +123,11 @@ export async function runConnect(apiUrl: string, cwd: string): Promise<void> {
|
|
|
119
123
|
const host = extractHost(api);
|
|
120
124
|
let token = "";
|
|
121
125
|
|
|
126
|
+
if (opts.reAuth) {
|
|
127
|
+
clearHostToken(host);
|
|
128
|
+
log.info("Discarded stored credentials (--re-auth).");
|
|
129
|
+
}
|
|
130
|
+
|
|
122
131
|
// Validate stored token before using it
|
|
123
132
|
const existingToken = getHostToken(host);
|
|
124
133
|
if (existingToken) {
|
|
@@ -216,19 +225,19 @@ export async function runConnect(apiUrl: string, cwd: string): Promise<void> {
|
|
|
216
225
|
});
|
|
217
226
|
|
|
218
227
|
if (res.ok) {
|
|
219
|
-
// better-auth's device-authorization plugin returns
|
|
220
|
-
//
|
|
221
|
-
//
|
|
228
|
+
// better-auth's device-authorization plugin returns an OAuth-style
|
|
229
|
+
// bundle: { access_token, token_type, expires_in, scope }. The
|
|
230
|
+
// access_token IS the first-party session token.
|
|
222
231
|
const data = (await res.json()) as {
|
|
223
|
-
|
|
224
|
-
|
|
232
|
+
access_token?: string;
|
|
233
|
+
expires_in?: number;
|
|
225
234
|
};
|
|
226
|
-
if (!data.
|
|
235
|
+
if (!data.access_token) {
|
|
227
236
|
s.stop("Auth response missing session token");
|
|
228
237
|
break;
|
|
229
238
|
}
|
|
230
|
-
token = data.
|
|
231
|
-
const tokenExpiresAt =
|
|
239
|
+
token = data.access_token;
|
|
240
|
+
const tokenExpiresAt = Date.now() + (data.expires_in ?? 0) * 1000;
|
|
232
241
|
storeHostToken(host, token, tokenExpiresAt);
|
|
233
242
|
break;
|
|
234
243
|
}
|