@stackable-labs/cli-app-extension 1.30.0 → 1.31.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/dist/index.js +352 -174
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1053,6 +1053,20 @@ var fetchExtensions = async (token, appId) => {
|
|
|
1053
1053
|
])
|
|
1054
1054
|
);
|
|
1055
1055
|
};
|
|
1056
|
+
var requestDevSessionToken = async (token, appId, extensionId) => {
|
|
1057
|
+
const baseUrl = getAdminApiBaseUrl();
|
|
1058
|
+
const res = await fetch(`${baseUrl}/app-extension/${appId}/dev-session`, {
|
|
1059
|
+
method: "POST",
|
|
1060
|
+
headers: authHeaders(token),
|
|
1061
|
+
body: JSON.stringify({ extensionId })
|
|
1062
|
+
});
|
|
1063
|
+
if (!res.ok) {
|
|
1064
|
+
const body = await res.text();
|
|
1065
|
+
throw new Error(`Failed to request dev session token: ${res.status} ${body}`);
|
|
1066
|
+
}
|
|
1067
|
+
const data = await res.json();
|
|
1068
|
+
return data.token;
|
|
1069
|
+
};
|
|
1056
1070
|
var updateExtension = async (token, appId, extensionId, payload) => {
|
|
1057
1071
|
const baseUrl = getAdminApiBaseUrl();
|
|
1058
1072
|
const res = await fetch(`${baseUrl}/app-extension/${appId}/extensions/${extensionId}`, {
|
|
@@ -2269,12 +2283,42 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2269
2283
|
};
|
|
2270
2284
|
|
|
2271
2285
|
// src/components/DevApp.tsx
|
|
2272
|
-
import { useRef, useState as
|
|
2273
|
-
import { useInput as
|
|
2286
|
+
import { useRef, useState as useState13, useEffect as useEffect6, useCallback as useCallback3 } from "react";
|
|
2287
|
+
import { useInput as useInput12, Box as Box19, Text as Text19 } from "ink";
|
|
2288
|
+
|
|
2289
|
+
// src/lib/devServer.ts
|
|
2290
|
+
import { spawn } from "child_process";
|
|
2291
|
+
var startDevServer = (projectRoot) => {
|
|
2292
|
+
const child = spawn("pnpm", ["dev"], {
|
|
2293
|
+
cwd: projectRoot,
|
|
2294
|
+
stdio: "pipe"
|
|
2295
|
+
});
|
|
2296
|
+
const stop = () => {
|
|
2297
|
+
child.kill("SIGTERM");
|
|
2298
|
+
};
|
|
2299
|
+
return { process: child, stop };
|
|
2300
|
+
};
|
|
2274
2301
|
|
|
2275
2302
|
// src/lib/tunnel.ts
|
|
2276
2303
|
import { Tunnel } from "cloudflared";
|
|
2277
|
-
var
|
|
2304
|
+
var MAX_RETRIES = 3;
|
|
2305
|
+
var RETRY_DELAY_MS = 2e3;
|
|
2306
|
+
var isValidTunnelUrl = (url) => {
|
|
2307
|
+
try {
|
|
2308
|
+
const { protocol, hostname } = new URL(url);
|
|
2309
|
+
if (protocol !== "https:" || !hostname.endsWith(".trycloudflare.com")) {
|
|
2310
|
+
return false;
|
|
2311
|
+
}
|
|
2312
|
+
const subdomain = hostname.replace(".trycloudflare.com", "");
|
|
2313
|
+
if (!subdomain || subdomain === "api") {
|
|
2314
|
+
return false;
|
|
2315
|
+
}
|
|
2316
|
+
return true;
|
|
2317
|
+
} catch {
|
|
2318
|
+
return false;
|
|
2319
|
+
}
|
|
2320
|
+
};
|
|
2321
|
+
var startTunnelOnce = (port) => new Promise((resolve, reject) => {
|
|
2278
2322
|
const tunnel = Tunnel.quick(`http://localhost:${port}`);
|
|
2279
2323
|
const timeout = setTimeout(() => {
|
|
2280
2324
|
tunnel.stop();
|
|
@@ -2282,6 +2326,10 @@ var startTunnel = (port) => new Promise((resolve, reject) => {
|
|
|
2282
2326
|
}, 3e4);
|
|
2283
2327
|
tunnel.once("url", (url) => {
|
|
2284
2328
|
clearTimeout(timeout);
|
|
2329
|
+
if (!isValidTunnelUrl(url)) {
|
|
2330
|
+
tunnel.stop();
|
|
2331
|
+
return reject(new Error(`Tunnel returned invalid URL: ${url}`));
|
|
2332
|
+
}
|
|
2285
2333
|
resolve({ url, stop: () => tunnel.stop() });
|
|
2286
2334
|
});
|
|
2287
2335
|
tunnel.once("error", (err) => {
|
|
@@ -2289,18 +2337,22 @@ var startTunnel = (port) => new Promise((resolve, reject) => {
|
|
|
2289
2337
|
reject(err);
|
|
2290
2338
|
});
|
|
2291
2339
|
});
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2340
|
+
var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
2341
|
+
var startTunnel = async (port) => {
|
|
2342
|
+
for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
|
|
2343
|
+
try {
|
|
2344
|
+
return await startTunnelOnce(port);
|
|
2345
|
+
} catch (err) {
|
|
2346
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2347
|
+
if (attempt < MAX_RETRIES && message.includes("invalid URL")) {
|
|
2348
|
+
console.log(`[dev] Tunnel returned invalid URL, retrying (attempt ${attempt + 1}/${MAX_RETRIES})...`);
|
|
2349
|
+
await delay(RETRY_DELAY_MS);
|
|
2350
|
+
} else {
|
|
2351
|
+
throw err;
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2355
|
+
throw new Error(`Tunnel failed to return a valid URL after ${MAX_RETRIES} attempts`);
|
|
2304
2356
|
};
|
|
2305
2357
|
|
|
2306
2358
|
// src/components/DevSetup.tsx
|
|
@@ -2352,9 +2404,71 @@ var DevSetup = ({ initialContext, token, onReady }) => {
|
|
|
2352
2404
|
};
|
|
2353
2405
|
|
|
2354
2406
|
// src/components/DevDashboard.tsx
|
|
2355
|
-
import { Box as
|
|
2356
|
-
import { useEffect as useEffect5 } from "react";
|
|
2407
|
+
import { Box as Box18, Text as Text18, useInput as useInput11 } from "ink";
|
|
2408
|
+
import { useEffect as useEffect5, useMemo } from "react";
|
|
2409
|
+
|
|
2410
|
+
// src/components/CopyableField.tsx
|
|
2411
|
+
import { useState as useState12, useCallback as useCallback2 } from "react";
|
|
2412
|
+
import { useInput as useInput10, Box as Box17, Text as Text17 } from "ink";
|
|
2413
|
+
import clipboard from "clipboardy";
|
|
2357
2414
|
import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2415
|
+
var CopyableField = ({
|
|
2416
|
+
label,
|
|
2417
|
+
value,
|
|
2418
|
+
shortcutKey,
|
|
2419
|
+
shortcutLabel,
|
|
2420
|
+
maxLength = 60,
|
|
2421
|
+
labelColor,
|
|
2422
|
+
children
|
|
2423
|
+
}) => {
|
|
2424
|
+
const [expanded, setExpanded] = useState12(false);
|
|
2425
|
+
const [copied, setCopied] = useState12(false);
|
|
2426
|
+
const handleCopy = useCallback2(async () => {
|
|
2427
|
+
if (expanded) {
|
|
2428
|
+
setExpanded(false);
|
|
2429
|
+
setCopied(false);
|
|
2430
|
+
return;
|
|
2431
|
+
}
|
|
2432
|
+
try {
|
|
2433
|
+
await clipboard.write(value);
|
|
2434
|
+
setExpanded(true);
|
|
2435
|
+
setCopied(true);
|
|
2436
|
+
setTimeout(() => {
|
|
2437
|
+
setCopied(false);
|
|
2438
|
+
setExpanded(false);
|
|
2439
|
+
}, 3e3);
|
|
2440
|
+
} catch {
|
|
2441
|
+
setExpanded(true);
|
|
2442
|
+
}
|
|
2443
|
+
}, [expanded, value]);
|
|
2444
|
+
useInput10((input) => {
|
|
2445
|
+
if (input === shortcutKey) {
|
|
2446
|
+
handleCopy();
|
|
2447
|
+
}
|
|
2448
|
+
});
|
|
2449
|
+
const truncated = value.length > maxLength ? `${value.slice(0, maxLength)}...` : value;
|
|
2450
|
+
const keyHint = shortcutLabel || shortcutKey;
|
|
2451
|
+
return /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", children: [
|
|
2452
|
+
/* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2453
|
+
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: label }),
|
|
2454
|
+
copied && /* @__PURE__ */ jsx17(Text17, { color: "green", bold: true, children: "Copied!" }),
|
|
2455
|
+
!copied && /* @__PURE__ */ jsxs17(Text17, { dimColor: true, children: [
|
|
2456
|
+
"press ",
|
|
2457
|
+
/* @__PURE__ */ jsxs17(Text17, { bold: true, color: "yellow", children: [
|
|
2458
|
+
"[",
|
|
2459
|
+
keyHint,
|
|
2460
|
+
"]"
|
|
2461
|
+
] }),
|
|
2462
|
+
" to copy (and see full value)"
|
|
2463
|
+
] })
|
|
2464
|
+
] }),
|
|
2465
|
+
/* @__PURE__ */ jsx17(Box17, { paddingLeft: 2, children: expanded ? /* @__PURE__ */ jsx17(Text17, { wrap: "wrap", children: value }) : children || /* @__PURE__ */ jsx17(Text17, { children: labelColor ? /* @__PURE__ */ jsx17(Text17, { color: labelColor, children: truncated }) : truncated }) })
|
|
2466
|
+
] });
|
|
2467
|
+
};
|
|
2468
|
+
|
|
2469
|
+
// src/components/DevDashboard.tsx
|
|
2470
|
+
import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2471
|
+
var toBase64Url = (input) => btoa(input).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
2358
2472
|
var DevDashboard = ({
|
|
2359
2473
|
previewTunnelUrl,
|
|
2360
2474
|
tunnelUrl,
|
|
@@ -2367,6 +2481,7 @@ var DevDashboard = ({
|
|
|
2367
2481
|
extensionPort,
|
|
2368
2482
|
previewPort,
|
|
2369
2483
|
manifestWarnings = [],
|
|
2484
|
+
devSessionToken,
|
|
2370
2485
|
onQuit
|
|
2371
2486
|
}) => {
|
|
2372
2487
|
useEffect5(() => {
|
|
@@ -2378,79 +2493,132 @@ var DevDashboard = ({
|
|
|
2378
2493
|
process.off("SIGINT", handler);
|
|
2379
2494
|
};
|
|
2380
2495
|
}, [onQuit]);
|
|
2381
|
-
|
|
2496
|
+
const devParamBlob = useMemo(() => {
|
|
2497
|
+
if (!tunnelUrl || !devSessionToken) return "";
|
|
2498
|
+
return toBase64Url(JSON.stringify({ url: tunnelUrl, token: devSessionToken }));
|
|
2499
|
+
}, [tunnelUrl, devSessionToken]);
|
|
2500
|
+
useInput11((input, key) => {
|
|
2382
2501
|
if (input === "q" || key.ctrl && input === "c") {
|
|
2383
2502
|
onQuit();
|
|
2384
2503
|
}
|
|
2385
2504
|
});
|
|
2386
|
-
return /* @__PURE__ */
|
|
2387
|
-
/* @__PURE__ */
|
|
2388
|
-
/* @__PURE__ */
|
|
2505
|
+
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
|
|
2506
|
+
/* @__PURE__ */ jsx18(Banner, { userId, orgId }),
|
|
2507
|
+
/* @__PURE__ */ jsxs18(
|
|
2389
2508
|
StepShell,
|
|
2390
2509
|
{
|
|
2391
2510
|
title: "dev",
|
|
2392
|
-
hint: `Live development ${tunnelUrl ? "with" : "w/o"} Tunnel`,
|
|
2393
|
-
footer: /* @__PURE__ */
|
|
2511
|
+
hint: `Live development ${tunnelUrl ? "with" : "w/o"} Tunnel \u2014 ${appName ? `${appName} ` : ""}(${appId})`,
|
|
2512
|
+
footer: /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", gap: 1, children: [
|
|
2513
|
+
devParamBlob && /* @__PURE__ */ jsxs18(Text18, { dimColor: true, children: [
|
|
2514
|
+
"Press ",
|
|
2515
|
+
/* @__PURE__ */ jsx18(Text18, { bold: true, color: "yellow", children: "[d]" }),
|
|
2516
|
+
" to copy Dev Param, ",
|
|
2517
|
+
/* @__PURE__ */ jsx18(Text18, { bold: true, color: "yellow", children: "[s]" }),
|
|
2518
|
+
" to copy Staging Param"
|
|
2519
|
+
] }),
|
|
2520
|
+
/* @__PURE__ */ jsxs18(Text18, { dimColor: true, children: [
|
|
2521
|
+
"Press ",
|
|
2522
|
+
/* @__PURE__ */ jsx18(Text18, { bold: true, color: "yellow", children: "[q]" }),
|
|
2523
|
+
" or Ctrl-C to quit"
|
|
2524
|
+
] })
|
|
2525
|
+
] }),
|
|
2394
2526
|
children: [
|
|
2395
|
-
/* @__PURE__ */
|
|
2396
|
-
/* @__PURE__ */
|
|
2397
|
-
/* @__PURE__ */
|
|
2398
|
-
/* @__PURE__ */
|
|
2527
|
+
/* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
|
|
2528
|
+
/* @__PURE__ */ jsxs18(Box18, { gap: 2, children: [
|
|
2529
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Extension:" }),
|
|
2530
|
+
/* @__PURE__ */ jsxs18(Text18, { children: [
|
|
2399
2531
|
extensionName,
|
|
2400
2532
|
" (",
|
|
2401
2533
|
extensionId,
|
|
2402
2534
|
")"
|
|
2403
2535
|
] })
|
|
2404
2536
|
] }),
|
|
2405
|
-
/* @__PURE__ */
|
|
2406
|
-
/* @__PURE__ */
|
|
2407
|
-
/* @__PURE__ */
|
|
2408
|
-
] }),
|
|
2409
|
-
/* @__PURE__ */ jsxs17(Box17, { gap: 2, children: [
|
|
2410
|
-
/* @__PURE__ */ jsx17(Text17, { dimColor: true, children: "Bundle URL:" }),
|
|
2411
|
-
/* @__PURE__ */ jsx17(Text17, { children: tunnelUrl || `http://localhost:${extensionPort}` })
|
|
2537
|
+
/* @__PURE__ */ jsxs18(Box18, { gap: 2, children: [
|
|
2538
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Bundle URL:" }),
|
|
2539
|
+
/* @__PURE__ */ jsx18(Text18, { children: tunnelUrl || `http://localhost:${extensionPort}` })
|
|
2412
2540
|
] })
|
|
2413
2541
|
] }),
|
|
2414
|
-
/* @__PURE__ */
|
|
2415
|
-
previewTunnelUrl && /* @__PURE__ */
|
|
2416
|
-
/* @__PURE__ */
|
|
2417
|
-
/* @__PURE__ */
|
|
2542
|
+
/* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
|
|
2543
|
+
previewTunnelUrl && /* @__PURE__ */ jsxs18(Box18, { gap: 2, children: [
|
|
2544
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Tunnel Dev - Preview:" }),
|
|
2545
|
+
/* @__PURE__ */ jsx18(Text18, { children: previewTunnelUrl })
|
|
2418
2546
|
] }),
|
|
2419
|
-
/* @__PURE__ */
|
|
2420
|
-
/* @__PURE__ */
|
|
2421
|
-
/* @__PURE__ */
|
|
2547
|
+
/* @__PURE__ */ jsxs18(Box18, { gap: 2, children: [
|
|
2548
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Local Dev - Preview:" }),
|
|
2549
|
+
/* @__PURE__ */ jsxs18(Text18, { children: [
|
|
2422
2550
|
"http://localhost:",
|
|
2423
2551
|
previewPort
|
|
2424
2552
|
] })
|
|
2425
2553
|
] })
|
|
2426
2554
|
] }),
|
|
2427
|
-
/* @__PURE__ */
|
|
2428
|
-
tunnelUrl && /* @__PURE__ */
|
|
2429
|
-
/* @__PURE__ */
|
|
2430
|
-
/* @__PURE__ */
|
|
2555
|
+
/* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
|
|
2556
|
+
tunnelUrl && /* @__PURE__ */ jsxs18(Box18, { gap: 2, children: [
|
|
2557
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Tunnel Dev - Extension:" }),
|
|
2558
|
+
/* @__PURE__ */ jsx18(Text18, { children: tunnelUrl })
|
|
2431
2559
|
] }),
|
|
2432
|
-
/* @__PURE__ */
|
|
2433
|
-
/* @__PURE__ */
|
|
2434
|
-
/* @__PURE__ */
|
|
2560
|
+
/* @__PURE__ */ jsxs18(Box18, { gap: 2, children: [
|
|
2561
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Local Dev - Extension:" }),
|
|
2562
|
+
/* @__PURE__ */ jsxs18(Text18, { children: [
|
|
2435
2563
|
"http://localhost:",
|
|
2436
2564
|
extensionPort
|
|
2437
2565
|
] })
|
|
2438
2566
|
] })
|
|
2439
2567
|
] }),
|
|
2440
|
-
|
|
2441
|
-
/* @__PURE__ */
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2568
|
+
tunnelUrl && devSessionToken && /* @__PURE__ */ jsxs18(Fragment2, { children: [
|
|
2569
|
+
/* @__PURE__ */ jsx18(
|
|
2570
|
+
CopyableField,
|
|
2571
|
+
{
|
|
2572
|
+
label: "Dev Param (no encryption):",
|
|
2573
|
+
value: `?_stackable_dev=${extensionId}:${devParamBlob}`,
|
|
2574
|
+
shortcutKey: "d",
|
|
2575
|
+
children: /* @__PURE__ */ jsxs18(Text18, { children: [
|
|
2576
|
+
"?",
|
|
2577
|
+
/* @__PURE__ */ jsx18(Text18, { color: "yellow", children: "_stackable_dev" }),
|
|
2578
|
+
"=",
|
|
2579
|
+
/* @__PURE__ */ jsx18(Text18, { color: "cyan", children: extensionId }),
|
|
2580
|
+
":",
|
|
2581
|
+
devParamBlob.slice(0, 20),
|
|
2582
|
+
"..."
|
|
2583
|
+
] })
|
|
2584
|
+
}
|
|
2585
|
+
),
|
|
2586
|
+
/* @__PURE__ */ jsx18(
|
|
2587
|
+
CopyableField,
|
|
2588
|
+
{
|
|
2589
|
+
label: "Staging Param (with encryption):",
|
|
2590
|
+
value: `?_stackable_staging=${extensionId}:${devParamBlob}`,
|
|
2591
|
+
shortcutKey: "s",
|
|
2592
|
+
children: /* @__PURE__ */ jsxs18(Text18, { children: [
|
|
2593
|
+
"?",
|
|
2594
|
+
/* @__PURE__ */ jsx18(Text18, { color: "yellow", children: "_stackable_staging" }),
|
|
2595
|
+
"=",
|
|
2596
|
+
/* @__PURE__ */ jsx18(Text18, { color: "cyan", children: extensionId }),
|
|
2597
|
+
":",
|
|
2598
|
+
devParamBlob.slice(0, 20),
|
|
2599
|
+
"..."
|
|
2600
|
+
] })
|
|
2601
|
+
}
|
|
2602
|
+
)
|
|
2603
|
+
] }),
|
|
2604
|
+
tunnelUrl && !devSessionToken && /* @__PURE__ */ jsxs18(Box18, { gap: 2, children: [
|
|
2605
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, children: "Host Dev - Query Param:" }),
|
|
2606
|
+
/* @__PURE__ */ jsxs18(Text18, { children: [
|
|
2607
|
+
"?",
|
|
2608
|
+
/* @__PURE__ */ jsx18(Text18, { color: "yellow", children: "_stackable_dev" }),
|
|
2609
|
+
"=",
|
|
2610
|
+
/* @__PURE__ */ jsx18(Text18, { color: "cyan", children: extensionId }),
|
|
2611
|
+
":",
|
|
2612
|
+
tunnelUrl
|
|
2445
2613
|
] })
|
|
2446
|
-
] })
|
|
2447
|
-
manifestWarnings.length > 0 && /* @__PURE__ */
|
|
2448
|
-
/* @__PURE__ */
|
|
2449
|
-
manifestWarnings.map((w, i) => /* @__PURE__ */
|
|
2614
|
+
] }),
|
|
2615
|
+
manifestWarnings.length > 0 && /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
2616
|
+
/* @__PURE__ */ jsx18(Text18, { color: "yellow", bold: true, children: "Local manifest differs from registry:" }),
|
|
2617
|
+
manifestWarnings.map((w, i) => /* @__PURE__ */ jsxs18(Text18, { color: "yellow", children: [
|
|
2450
2618
|
" ",
|
|
2451
2619
|
w
|
|
2452
2620
|
] }, i)),
|
|
2453
|
-
/* @__PURE__ */
|
|
2621
|
+
/* @__PURE__ */ jsx18(Text18, { dimColor: true, children: " Run `pnpm --config.dlx-cache-max-age=0 dlx @stackable-labs/cli-app-extension@latest update` to review and sync." })
|
|
2454
2622
|
] })
|
|
2455
2623
|
]
|
|
2456
2624
|
}
|
|
@@ -2459,17 +2627,18 @@ var DevDashboard = ({
|
|
|
2459
2627
|
};
|
|
2460
2628
|
|
|
2461
2629
|
// src/components/DevApp.tsx
|
|
2462
|
-
import { jsx as
|
|
2630
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
2463
2631
|
var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
2464
|
-
const [state, setState] =
|
|
2465
|
-
const [devContext, setDevContext] =
|
|
2466
|
-
const [resolvedContext, setResolvedContext] =
|
|
2467
|
-
const [tunnelUrl, setTunnelUrl] =
|
|
2468
|
-
const [previewTunnelUrl, setPreviewTunnelUrl] =
|
|
2469
|
-
const [tunnelHandle, setTunnelHandle] =
|
|
2470
|
-
const [previewTunnelHandle, setPreviewTunnelHandle] =
|
|
2471
|
-
const [devServerHandle, setDevServerHandle] =
|
|
2472
|
-
const [manifestWarnings, setManifestWarnings] =
|
|
2632
|
+
const [state, setState] = useState13("setup");
|
|
2633
|
+
const [devContext, setDevContext] = useState13(null);
|
|
2634
|
+
const [resolvedContext, setResolvedContext] = useState13(null);
|
|
2635
|
+
const [tunnelUrl, setTunnelUrl] = useState13(null);
|
|
2636
|
+
const [previewTunnelUrl, setPreviewTunnelUrl] = useState13(null);
|
|
2637
|
+
const [tunnelHandle, setTunnelHandle] = useState13(null);
|
|
2638
|
+
const [previewTunnelHandle, setPreviewTunnelHandle] = useState13(null);
|
|
2639
|
+
const [devServerHandle, setDevServerHandle] = useState13(null);
|
|
2640
|
+
const [manifestWarnings, setManifestWarnings] = useState13([]);
|
|
2641
|
+
const [devSessionToken, setDevSessionToken] = useState13(null);
|
|
2473
2642
|
const shuttingDown = useRef(false);
|
|
2474
2643
|
const useTunnel = options.tunnel !== false;
|
|
2475
2644
|
useEffect6(() => {
|
|
@@ -2480,7 +2649,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2480
2649
|
setDevContext(ctx);
|
|
2481
2650
|
});
|
|
2482
2651
|
}, [options.dir]);
|
|
2483
|
-
const handleSetupReady =
|
|
2652
|
+
const handleSetupReady = useCallback3(async (resolved) => {
|
|
2484
2653
|
if (!devContext) return;
|
|
2485
2654
|
setResolvedContext(resolved);
|
|
2486
2655
|
console.log(`[dev] Saving context: appId=${resolved.appId} extensionId=${resolved.extensionId}`);
|
|
@@ -2538,6 +2707,14 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2538
2707
|
} else {
|
|
2539
2708
|
console.log("[dev] Tunnel disabled (--no-tunnel)");
|
|
2540
2709
|
}
|
|
2710
|
+
try {
|
|
2711
|
+
console.log("[dev] Requesting dev session token...");
|
|
2712
|
+
const sessionToken = await requestDevSessionToken(token, resolved.appId, resolved.extensionId);
|
|
2713
|
+
console.log("[dev] Dev session token received");
|
|
2714
|
+
setDevSessionToken(sessionToken);
|
|
2715
|
+
} catch (err) {
|
|
2716
|
+
console.warn("[dev] Failed to obtain dev session token \u2014 dev/staging mode URLs will not include auth token:", err);
|
|
2717
|
+
}
|
|
2541
2718
|
console.log(`[dev] Starting dev server in ${devContext.projectRoot}`);
|
|
2542
2719
|
const serverHandle = startDevServer(devContext.projectRoot);
|
|
2543
2720
|
setDevServerHandle(serverHandle);
|
|
@@ -2579,7 +2756,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2579
2756
|
console.log("[dev] Done");
|
|
2580
2757
|
process.exit(0);
|
|
2581
2758
|
};
|
|
2582
|
-
|
|
2759
|
+
useInput12((input, key) => {
|
|
2583
2760
|
if (input === "c" && key.ctrl) {
|
|
2584
2761
|
if (state === "running") {
|
|
2585
2762
|
handleQuit();
|
|
@@ -2590,7 +2767,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2590
2767
|
});
|
|
2591
2768
|
if (state === "setup" && devContext) {
|
|
2592
2769
|
if (!devContext.appId || !devContext.extensionId) {
|
|
2593
|
-
return /* @__PURE__ */
|
|
2770
|
+
return /* @__PURE__ */ jsx19(
|
|
2594
2771
|
DevSetup,
|
|
2595
2772
|
{
|
|
2596
2773
|
token,
|
|
@@ -2602,7 +2779,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2602
2779
|
return null;
|
|
2603
2780
|
}
|
|
2604
2781
|
if (state === "running" && devContext && resolvedContext) {
|
|
2605
|
-
return /* @__PURE__ */
|
|
2782
|
+
return /* @__PURE__ */ jsx19(
|
|
2606
2783
|
DevDashboard,
|
|
2607
2784
|
{
|
|
2608
2785
|
previewTunnelUrl,
|
|
@@ -2616,6 +2793,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2616
2793
|
extensionPort: options.extensionPort ? parseInt(options.extensionPort, 10) : devContext.extensionPort,
|
|
2617
2794
|
previewPort: options.previewPort ? parseInt(options.previewPort, 10) : devContext.previewPort,
|
|
2618
2795
|
manifestWarnings,
|
|
2796
|
+
devSessionToken,
|
|
2619
2797
|
onQuit: handleQuit
|
|
2620
2798
|
}
|
|
2621
2799
|
);
|
|
@@ -2623,13 +2801,13 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2623
2801
|
if (state === "stopping") {
|
|
2624
2802
|
return null;
|
|
2625
2803
|
}
|
|
2626
|
-
return /* @__PURE__ */
|
|
2804
|
+
return /* @__PURE__ */ jsx19(Box19, { children: /* @__PURE__ */ jsx19(Text19, { children: "Loading..." }) });
|
|
2627
2805
|
};
|
|
2628
2806
|
|
|
2629
2807
|
// src/components/AIScaffold.tsx
|
|
2630
|
-
import { Box as
|
|
2808
|
+
import { Box as Box20, Text as Text20, useApp as useApp2 } from "ink";
|
|
2631
2809
|
import Spinner4 from "ink-spinner";
|
|
2632
|
-
import { useState as
|
|
2810
|
+
import { useState as useState14, useEffect as useEffect7 } from "react";
|
|
2633
2811
|
|
|
2634
2812
|
// src/lib/aiDocs.ts
|
|
2635
2813
|
import { existsSync, readFileSync } from "fs";
|
|
@@ -2682,12 +2860,12 @@ var downloadAndExtractAiDocs = async (targetDir, version2) => {
|
|
|
2682
2860
|
};
|
|
2683
2861
|
|
|
2684
2862
|
// src/components/AIScaffold.tsx
|
|
2685
|
-
import { jsx as
|
|
2863
|
+
import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2686
2864
|
var AIScaffold = ({ version: version2 }) => {
|
|
2687
2865
|
const { exit } = useApp2();
|
|
2688
|
-
const [state, setState] =
|
|
2689
|
-
const [files, setFiles] =
|
|
2690
|
-
const [errorMessage, setErrorMessage] =
|
|
2866
|
+
const [state, setState] = useState14("validating");
|
|
2867
|
+
const [files, setFiles] = useState14([]);
|
|
2868
|
+
const [errorMessage, setErrorMessage] = useState14("");
|
|
2691
2869
|
useEffect7(() => {
|
|
2692
2870
|
const run = async () => {
|
|
2693
2871
|
const projectDir = process.cwd();
|
|
@@ -2711,35 +2889,35 @@ var AIScaffold = ({ version: version2 }) => {
|
|
|
2711
2889
|
};
|
|
2712
2890
|
run();
|
|
2713
2891
|
}, []);
|
|
2714
|
-
return /* @__PURE__ */
|
|
2715
|
-
/* @__PURE__ */
|
|
2716
|
-
/* @__PURE__ */
|
|
2717
|
-
state === "validating" && /* @__PURE__ */
|
|
2718
|
-
/* @__PURE__ */
|
|
2719
|
-
/* @__PURE__ */
|
|
2892
|
+
return /* @__PURE__ */ jsxs19(Box20, { flexDirection: "column", children: [
|
|
2893
|
+
/* @__PURE__ */ jsx20(Banner, {}),
|
|
2894
|
+
/* @__PURE__ */ jsxs19(StepShell, { title: "AI Editor Config", children: [
|
|
2895
|
+
state === "validating" && /* @__PURE__ */ jsxs19(Box20, { gap: 1, children: [
|
|
2896
|
+
/* @__PURE__ */ jsx20(Text20, { color: "cyan", children: /* @__PURE__ */ jsx20(Spinner4, { type: "dots" }) }),
|
|
2897
|
+
/* @__PURE__ */ jsx20(Text20, { children: "Checking project..." })
|
|
2720
2898
|
] }),
|
|
2721
|
-
state === "downloading" && /* @__PURE__ */
|
|
2722
|
-
/* @__PURE__ */
|
|
2723
|
-
/* @__PURE__ */
|
|
2899
|
+
state === "downloading" && /* @__PURE__ */ jsxs19(Box20, { gap: 1, children: [
|
|
2900
|
+
/* @__PURE__ */ jsx20(Text20, { color: "cyan", children: /* @__PURE__ */ jsx20(Spinner4, { type: "dots" }) }),
|
|
2901
|
+
/* @__PURE__ */ jsxs19(Text20, { children: [
|
|
2724
2902
|
"Downloading AI editor configs (",
|
|
2725
2903
|
version2,
|
|
2726
2904
|
")..."
|
|
2727
2905
|
] })
|
|
2728
2906
|
] }),
|
|
2729
|
-
state === "done" && /* @__PURE__ */
|
|
2730
|
-
/* @__PURE__ */
|
|
2731
|
-
/* @__PURE__ */
|
|
2732
|
-
/* @__PURE__ */
|
|
2907
|
+
state === "done" && /* @__PURE__ */ jsxs19(Box20, { flexDirection: "column", gap: 1, children: [
|
|
2908
|
+
/* @__PURE__ */ jsxs19(Box20, { gap: 1, children: [
|
|
2909
|
+
/* @__PURE__ */ jsx20(Text20, { color: "green", bold: true, children: "\u2714" }),
|
|
2910
|
+
/* @__PURE__ */ jsxs19(Text20, { bold: true, children: [
|
|
2733
2911
|
"AI editor configs installed (",
|
|
2734
2912
|
files.length,
|
|
2735
2913
|
" files)"
|
|
2736
2914
|
] })
|
|
2737
2915
|
] }),
|
|
2738
|
-
/* @__PURE__ */
|
|
2916
|
+
/* @__PURE__ */ jsx20(Box20, { flexDirection: "column", marginLeft: 2, children: files.map((f) => /* @__PURE__ */ jsx20(Text20, { dimColor: true, children: f }, f)) })
|
|
2739
2917
|
] }),
|
|
2740
|
-
state === "error" && /* @__PURE__ */
|
|
2741
|
-
/* @__PURE__ */
|
|
2742
|
-
/* @__PURE__ */
|
|
2918
|
+
state === "error" && /* @__PURE__ */ jsxs19(Box20, { gap: 1, children: [
|
|
2919
|
+
/* @__PURE__ */ jsx20(Text20, { color: "red", children: "\u2716" }),
|
|
2920
|
+
/* @__PURE__ */ jsx20(Text20, { children: errorMessage })
|
|
2743
2921
|
] })
|
|
2744
2922
|
] })
|
|
2745
2923
|
] });
|
|
@@ -2747,10 +2925,10 @@ var AIScaffold = ({ version: version2 }) => {
|
|
|
2747
2925
|
|
|
2748
2926
|
// src/components/AuthLogin.tsx
|
|
2749
2927
|
import { createServer } from "http";
|
|
2750
|
-
import { Box as
|
|
2928
|
+
import { Box as Box21, Text as Text21, useApp as useApp3 } from "ink";
|
|
2751
2929
|
import Spinner5 from "ink-spinner";
|
|
2752
2930
|
import open from "open";
|
|
2753
|
-
import { useState as
|
|
2931
|
+
import { useState as useState15, useEffect as useEffect8 } from "react";
|
|
2754
2932
|
|
|
2755
2933
|
// src/lib/auth.ts
|
|
2756
2934
|
import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir2, unlink } from "fs/promises";
|
|
@@ -2803,7 +2981,7 @@ var getToken = async () => {
|
|
|
2803
2981
|
};
|
|
2804
2982
|
|
|
2805
2983
|
// src/components/AuthLogin.tsx
|
|
2806
|
-
import { jsx as
|
|
2984
|
+
import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2807
2985
|
var LOGIN_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
2808
2986
|
var callbackPage = (heading, sub, redirectUrl) => `<!DOCTYPE html>
|
|
2809
2987
|
<html><head><meta charset="utf-8"><title>Stackable CLI</title>
|
|
@@ -2814,11 +2992,11 @@ ${redirectUrl ? `<script>(function(){var s=3,el=document.getElementById('h');fun
|
|
|
2814
2992
|
</body></html>`;
|
|
2815
2993
|
var AuthLogin = ({ dashboardUrl }) => {
|
|
2816
2994
|
const { exit } = useApp3();
|
|
2817
|
-
const [state, setState] =
|
|
2818
|
-
const [loginUrl, setLoginUrl] =
|
|
2819
|
-
const [userIdLabel, setUserIdLabel] =
|
|
2820
|
-
const [orgIdLabel, setOrgIdLabel] =
|
|
2821
|
-
const [errorMessage, setErrorMessage] =
|
|
2995
|
+
const [state, setState] = useState15("waiting");
|
|
2996
|
+
const [loginUrl, setLoginUrl] = useState15("");
|
|
2997
|
+
const [userIdLabel, setUserIdLabel] = useState15("");
|
|
2998
|
+
const [orgIdLabel, setOrgIdLabel] = useState15("");
|
|
2999
|
+
const [errorMessage, setErrorMessage] = useState15("");
|
|
2822
3000
|
useEffect8(() => {
|
|
2823
3001
|
let server;
|
|
2824
3002
|
let timeout;
|
|
@@ -2894,38 +3072,38 @@ var AuthLogin = ({ dashboardUrl }) => {
|
|
|
2894
3072
|
server?.close();
|
|
2895
3073
|
};
|
|
2896
3074
|
}, []);
|
|
2897
|
-
return /* @__PURE__ */
|
|
2898
|
-
/* @__PURE__ */
|
|
2899
|
-
/* @__PURE__ */
|
|
2900
|
-
state === "waiting" && /* @__PURE__ */
|
|
2901
|
-
/* @__PURE__ */
|
|
2902
|
-
/* @__PURE__ */
|
|
2903
|
-
/* @__PURE__ */
|
|
3075
|
+
return /* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", children: [
|
|
3076
|
+
/* @__PURE__ */ jsx21(Banner, {}),
|
|
3077
|
+
/* @__PURE__ */ jsxs20(StepShell, { title: "Authenticate with Stackable", children: [
|
|
3078
|
+
state === "waiting" && /* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", gap: 1, children: [
|
|
3079
|
+
/* @__PURE__ */ jsxs20(Box21, { gap: 1, children: [
|
|
3080
|
+
/* @__PURE__ */ jsx21(Text21, { color: "cyan", children: /* @__PURE__ */ jsx21(Spinner5, { type: "dots" }) }),
|
|
3081
|
+
/* @__PURE__ */ jsx21(Text21, { children: "Waiting for browser authentication..." })
|
|
2904
3082
|
] }),
|
|
2905
|
-
loginUrl && /* @__PURE__ */
|
|
3083
|
+
loginUrl && /* @__PURE__ */ jsxs20(Text21, { dimColor: true, children: [
|
|
2906
3084
|
" ",
|
|
2907
3085
|
loginUrl
|
|
2908
3086
|
] })
|
|
2909
3087
|
] }),
|
|
2910
|
-
state === "success" && /* @__PURE__ */
|
|
2911
|
-
/* @__PURE__ */
|
|
2912
|
-
/* @__PURE__ */
|
|
2913
|
-
/* @__PURE__ */
|
|
2914
|
-
/* @__PURE__ */
|
|
3088
|
+
state === "success" && /* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", gap: 1, children: [
|
|
3089
|
+
/* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", children: [
|
|
3090
|
+
/* @__PURE__ */ jsxs20(Box21, { gap: 2, children: [
|
|
3091
|
+
/* @__PURE__ */ jsx21(Text21, { dimColor: true, children: "User:" }),
|
|
3092
|
+
/* @__PURE__ */ jsx21(Text21, { color: "cyan", children: userIdLabel })
|
|
2915
3093
|
] }),
|
|
2916
|
-
/* @__PURE__ */
|
|
2917
|
-
/* @__PURE__ */
|
|
2918
|
-
/* @__PURE__ */
|
|
3094
|
+
/* @__PURE__ */ jsxs20(Box21, { gap: 2, children: [
|
|
3095
|
+
/* @__PURE__ */ jsx21(Text21, { dimColor: true, children: "Org: " }),
|
|
3096
|
+
/* @__PURE__ */ jsx21(Text21, { color: "cyan", children: orgIdLabel })
|
|
2919
3097
|
] })
|
|
2920
3098
|
] }),
|
|
2921
|
-
/* @__PURE__ */
|
|
2922
|
-
/* @__PURE__ */
|
|
2923
|
-
/* @__PURE__ */
|
|
3099
|
+
/* @__PURE__ */ jsxs20(Box21, { gap: 1, children: [
|
|
3100
|
+
/* @__PURE__ */ jsx21(Text21, { color: "green", bold: true, children: "\u2714" }),
|
|
3101
|
+
/* @__PURE__ */ jsx21(Text21, { bold: true, children: "Authenticated" })
|
|
2924
3102
|
] })
|
|
2925
3103
|
] }),
|
|
2926
|
-
state === "error" && /* @__PURE__ */
|
|
2927
|
-
/* @__PURE__ */
|
|
2928
|
-
/* @__PURE__ */
|
|
3104
|
+
state === "error" && /* @__PURE__ */ jsxs20(Box21, { gap: 1, children: [
|
|
3105
|
+
/* @__PURE__ */ jsx21(Text21, { color: "red", children: "\u2716" }),
|
|
3106
|
+
/* @__PURE__ */ jsx21(Text21, { children: errorMessage })
|
|
2929
3107
|
] })
|
|
2930
3108
|
] })
|
|
2931
3109
|
] });
|
|
@@ -2933,70 +3111,70 @@ var AuthLogin = ({ dashboardUrl }) => {
|
|
|
2933
3111
|
|
|
2934
3112
|
// src/components/AuthLogout.tsx
|
|
2935
3113
|
import { useEffect as useEffect9 } from "react";
|
|
2936
|
-
import { Box as
|
|
2937
|
-
import { jsx as
|
|
3114
|
+
import { Box as Box22, Text as Text22, useApp as useApp4 } from "ink";
|
|
3115
|
+
import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
2938
3116
|
var AuthLogout = () => {
|
|
2939
3117
|
const { exit } = useApp4();
|
|
2940
3118
|
useEffect9(() => {
|
|
2941
3119
|
exit();
|
|
2942
3120
|
}, [exit]);
|
|
2943
|
-
return /* @__PURE__ */
|
|
2944
|
-
/* @__PURE__ */
|
|
2945
|
-
/* @__PURE__ */
|
|
2946
|
-
/* @__PURE__ */
|
|
2947
|
-
/* @__PURE__ */
|
|
3121
|
+
return /* @__PURE__ */ jsxs21(Box22, { flexDirection: "column", children: [
|
|
3122
|
+
/* @__PURE__ */ jsx22(Banner, {}),
|
|
3123
|
+
/* @__PURE__ */ jsx22(StepShell, { title: "Authenticate with Stackable", children: /* @__PURE__ */ jsxs21(Box22, { gap: 1, children: [
|
|
3124
|
+
/* @__PURE__ */ jsx22(Text22, { color: "green", bold: true, children: "\u2714" }),
|
|
3125
|
+
/* @__PURE__ */ jsx22(Text22, { bold: true, children: "Logged out" })
|
|
2948
3126
|
] }) })
|
|
2949
3127
|
] });
|
|
2950
3128
|
};
|
|
2951
3129
|
|
|
2952
3130
|
// src/components/AuthStatus.tsx
|
|
2953
3131
|
import { useEffect as useEffect10 } from "react";
|
|
2954
|
-
import { useApp as useApp5, Box as
|
|
2955
|
-
import { jsx as
|
|
3132
|
+
import { useApp as useApp5, Box as Box23, Text as Text23 } from "ink";
|
|
3133
|
+
import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2956
3134
|
var AuthStatus = ({ state, userId, orgId, expiry }) => {
|
|
2957
3135
|
const { exit } = useApp5();
|
|
2958
3136
|
useEffect10(() => {
|
|
2959
3137
|
exit();
|
|
2960
3138
|
}, [exit]);
|
|
2961
|
-
return /* @__PURE__ */
|
|
2962
|
-
/* @__PURE__ */
|
|
2963
|
-
/* @__PURE__ */
|
|
2964
|
-
state === "authenticated" && /* @__PURE__ */
|
|
2965
|
-
/* @__PURE__ */
|
|
2966
|
-
/* @__PURE__ */
|
|
2967
|
-
/* @__PURE__ */
|
|
2968
|
-
/* @__PURE__ */
|
|
3139
|
+
return /* @__PURE__ */ jsxs22(Box23, { flexDirection: "column", children: [
|
|
3140
|
+
/* @__PURE__ */ jsx23(Banner, {}),
|
|
3141
|
+
/* @__PURE__ */ jsxs22(StepShell, { title: "Authenticate with Stackable", children: [
|
|
3142
|
+
state === "authenticated" && /* @__PURE__ */ jsxs22(Box23, { flexDirection: "column", gap: 1, children: [
|
|
3143
|
+
/* @__PURE__ */ jsxs22(Box23, { flexDirection: "column", children: [
|
|
3144
|
+
/* @__PURE__ */ jsxs22(Box23, { gap: 2, children: [
|
|
3145
|
+
/* @__PURE__ */ jsx23(Text23, { dimColor: true, children: "User:" }),
|
|
3146
|
+
/* @__PURE__ */ jsx23(Text23, { color: "cyan", children: userId })
|
|
2969
3147
|
] }),
|
|
2970
|
-
/* @__PURE__ */
|
|
2971
|
-
/* @__PURE__ */
|
|
2972
|
-
/* @__PURE__ */
|
|
3148
|
+
/* @__PURE__ */ jsxs22(Box23, { gap: 2, children: [
|
|
3149
|
+
/* @__PURE__ */ jsx23(Text23, { dimColor: true, children: "Org: " }),
|
|
3150
|
+
/* @__PURE__ */ jsx23(Text23, { color: "cyan", children: orgId })
|
|
2973
3151
|
] }),
|
|
2974
|
-
expiry && /* @__PURE__ */
|
|
2975
|
-
/* @__PURE__ */
|
|
2976
|
-
/* @__PURE__ */
|
|
3152
|
+
expiry && /* @__PURE__ */ jsxs22(Box23, { gap: 2, children: [
|
|
3153
|
+
/* @__PURE__ */ jsx23(Text23, { dimColor: true, children: "Exp: " }),
|
|
3154
|
+
/* @__PURE__ */ jsx23(Text23, { color: "cyan", children: expiry.toLocaleDateString() })
|
|
2977
3155
|
] })
|
|
2978
3156
|
] }),
|
|
2979
|
-
/* @__PURE__ */
|
|
2980
|
-
/* @__PURE__ */
|
|
2981
|
-
/* @__PURE__ */
|
|
3157
|
+
/* @__PURE__ */ jsxs22(Box23, { gap: 1, children: [
|
|
3158
|
+
/* @__PURE__ */ jsx23(Text23, { color: "green", bold: true, children: "\u2714" }),
|
|
3159
|
+
/* @__PURE__ */ jsx23(Text23, { bold: true, children: "Authenticated" })
|
|
2982
3160
|
] })
|
|
2983
3161
|
] }),
|
|
2984
|
-
state === "expired" && /* @__PURE__ */
|
|
2985
|
-
/* @__PURE__ */
|
|
2986
|
-
/* @__PURE__ */
|
|
2987
|
-
/* @__PURE__ */
|
|
3162
|
+
state === "expired" && /* @__PURE__ */ jsxs22(Box23, { flexDirection: "column", gap: 1, children: [
|
|
3163
|
+
/* @__PURE__ */ jsxs22(Box23, { gap: 1, children: [
|
|
3164
|
+
/* @__PURE__ */ jsx23(Text23, { color: "red", children: "\u2716" }),
|
|
3165
|
+
/* @__PURE__ */ jsxs22(Text23, { children: [
|
|
2988
3166
|
"Session expired",
|
|
2989
3167
|
expiry ? ` (${expiry.toLocaleDateString()})` : ""
|
|
2990
3168
|
] })
|
|
2991
3169
|
] }),
|
|
2992
|
-
/* @__PURE__ */
|
|
3170
|
+
/* @__PURE__ */ jsx23(Text23, { dimColor: true, children: "Run `stackable-app-extension auth login` to re-authenticate." })
|
|
2993
3171
|
] }),
|
|
2994
|
-
state === "not-logged-in" && /* @__PURE__ */
|
|
2995
|
-
/* @__PURE__ */
|
|
2996
|
-
/* @__PURE__ */
|
|
2997
|
-
/* @__PURE__ */
|
|
3172
|
+
state === "not-logged-in" && /* @__PURE__ */ jsxs22(Box23, { flexDirection: "column", gap: 1, children: [
|
|
3173
|
+
/* @__PURE__ */ jsxs22(Box23, { gap: 1, children: [
|
|
3174
|
+
/* @__PURE__ */ jsx23(Text23, { color: "red", children: "\u2716" }),
|
|
3175
|
+
/* @__PURE__ */ jsx23(Text23, { children: "Not logged in" })
|
|
2998
3176
|
] }),
|
|
2999
|
-
/* @__PURE__ */
|
|
3177
|
+
/* @__PURE__ */ jsx23(Text23, { dimColor: true, children: "Run `stackable-app-extension auth login`" })
|
|
3000
3178
|
] })
|
|
3001
3179
|
] })
|
|
3002
3180
|
] });
|
|
@@ -3050,7 +3228,7 @@ var checkForUpdate = (currentVersion) => {
|
|
|
3050
3228
|
};
|
|
3051
3229
|
|
|
3052
3230
|
// src/index.tsx
|
|
3053
|
-
import { jsx as
|
|
3231
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
3054
3232
|
var require2 = createRequire(import.meta.url);
|
|
3055
3233
|
var { version } = require2("../package.json");
|
|
3056
3234
|
checkForUpdate(version);
|
|
@@ -3063,7 +3241,7 @@ var ensureToken = async () => {
|
|
|
3063
3241
|
const message = err instanceof Error ? err.message : String(err);
|
|
3064
3242
|
const isExpired = message.toLowerCase().includes("expired");
|
|
3065
3243
|
render(
|
|
3066
|
-
/* @__PURE__ */
|
|
3244
|
+
/* @__PURE__ */ jsx24(AuthStatus, { state: isExpired ? "expired" : "not-logged-in" })
|
|
3067
3245
|
);
|
|
3068
3246
|
return null;
|
|
3069
3247
|
}
|
|
@@ -3076,7 +3254,7 @@ program.command("create" /* CREATE */).description("Create a new Extension proje
|
|
|
3076
3254
|
}
|
|
3077
3255
|
const { token, userId, orgId } = auth2;
|
|
3078
3256
|
render(
|
|
3079
|
-
/* @__PURE__ */
|
|
3257
|
+
/* @__PURE__ */ jsx24(
|
|
3080
3258
|
App,
|
|
3081
3259
|
{
|
|
3082
3260
|
command: "create" /* CREATE */,
|
|
@@ -3096,7 +3274,7 @@ program.command("scaffold" /* SCAFFOLD */).description("Scaffold a local project
|
|
|
3096
3274
|
}
|
|
3097
3275
|
const { token, userId, orgId } = auth2;
|
|
3098
3276
|
render(
|
|
3099
|
-
/* @__PURE__ */
|
|
3277
|
+
/* @__PURE__ */ jsx24(
|
|
3100
3278
|
App,
|
|
3101
3279
|
{
|
|
3102
3280
|
command: "scaffold" /* SCAFFOLD */,
|
|
@@ -3115,7 +3293,7 @@ program.command("update" /* UPDATE */).description("Update an existing Extension
|
|
|
3115
3293
|
}
|
|
3116
3294
|
const { token, userId, orgId } = auth2;
|
|
3117
3295
|
render(
|
|
3118
|
-
/* @__PURE__ */
|
|
3296
|
+
/* @__PURE__ */ jsx24(
|
|
3119
3297
|
App,
|
|
3120
3298
|
{
|
|
3121
3299
|
command: "update" /* UPDATE */,
|
|
@@ -3135,7 +3313,7 @@ program.command("dev" /* DEV */).description("Start dev servers with a public tu
|
|
|
3135
3313
|
}
|
|
3136
3314
|
const { token, userId, orgId } = auth2;
|
|
3137
3315
|
render(
|
|
3138
|
-
/* @__PURE__ */
|
|
3316
|
+
/* @__PURE__ */ jsx24(
|
|
3139
3317
|
DevApp,
|
|
3140
3318
|
{
|
|
3141
3319
|
options,
|
|
@@ -3150,17 +3328,17 @@ program.command("dev" /* DEV */).description("Start dev servers with a public tu
|
|
|
3150
3328
|
var DASHBOARD_URL = process.env.ADMIN_DASHBOARD_URL ?? "https://admin.stackablelabs.io";
|
|
3151
3329
|
var auth = program.command("auth").description("Manage CLI authentication");
|
|
3152
3330
|
auth.command("login").description("Authenticate with Stackable via browser").action(async () => {
|
|
3153
|
-
render(/* @__PURE__ */
|
|
3331
|
+
render(/* @__PURE__ */ jsx24(AuthLogin, { dashboardUrl: DASHBOARD_URL }));
|
|
3154
3332
|
});
|
|
3155
3333
|
auth.command("logout").description("Clear stored CLI credentials").action(async () => {
|
|
3156
3334
|
await clearAuthState();
|
|
3157
|
-
render(/* @__PURE__ */
|
|
3335
|
+
render(/* @__PURE__ */ jsx24(AuthLogout, {}));
|
|
3158
3336
|
});
|
|
3159
3337
|
auth.command("status").description("Show current authentication status").action(async () => {
|
|
3160
3338
|
const state = await readAuthState();
|
|
3161
3339
|
if (!state) {
|
|
3162
3340
|
render(
|
|
3163
|
-
/* @__PURE__ */
|
|
3341
|
+
/* @__PURE__ */ jsx24(AuthStatus, { state: "not-logged-in" })
|
|
3164
3342
|
);
|
|
3165
3343
|
return;
|
|
3166
3344
|
}
|
|
@@ -3168,11 +3346,11 @@ auth.command("status").description("Show current authentication status").action(
|
|
|
3168
3346
|
const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
|
|
3169
3347
|
const expiry = payload.exp ? new Date(payload.exp * 1e3) : null;
|
|
3170
3348
|
if (expiry && Date.now() >= expiry.getTime()) {
|
|
3171
|
-
render(/* @__PURE__ */
|
|
3349
|
+
render(/* @__PURE__ */ jsx24(AuthStatus, { state: "expired", expiry }));
|
|
3172
3350
|
return;
|
|
3173
3351
|
}
|
|
3174
3352
|
render(
|
|
3175
|
-
/* @__PURE__ */
|
|
3353
|
+
/* @__PURE__ */ jsx24(
|
|
3176
3354
|
AuthStatus,
|
|
3177
3355
|
{
|
|
3178
3356
|
state: "authenticated",
|
|
@@ -3185,6 +3363,6 @@ auth.command("status").description("Show current authentication status").action(
|
|
|
3185
3363
|
});
|
|
3186
3364
|
var ai = program.command("ai").description("AI editor configuration tools");
|
|
3187
3365
|
ai.command("scaffold").description("Download AI editor config files into your Extension project").option("--version <version>", 'AI docs version (semver or "latest")', "latest").action(async (options) => {
|
|
3188
|
-
render(/* @__PURE__ */
|
|
3366
|
+
render(/* @__PURE__ */ jsx24(AIScaffold, { version: options.version }));
|
|
3189
3367
|
});
|
|
3190
3368
|
program.parse(process.argv.filter((arg) => arg !== "--"));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stackable-labs/cli-app-extension",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.31.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"bin": {
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
],
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"adm-zip": "0.x",
|
|
16
|
+
"clipboardy": "5.x",
|
|
16
17
|
"cloudflared": "0.x",
|
|
17
18
|
"commander": "12.x",
|
|
18
19
|
"giget": "3.x",
|