@stackable-labs/cli-app-extension 1.37.0 → 1.39.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 +606 -767
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'module';
|
|
3
|
+
import { program } from 'commander';
|
|
4
|
+
import { render, useApp, Box, Text, useInput, useFocus, useFocusManager } from 'ink';
|
|
5
|
+
import { unlink, readFile, writeFile, mkdir, readdir, rm } from 'fs/promises';
|
|
6
|
+
import { join, dirname } from 'path';
|
|
7
|
+
import Spinner5 from 'ink-spinner';
|
|
8
|
+
import { useState, useCallback, useEffect, useRef, useMemo } from 'react';
|
|
9
|
+
import { delay } from '@stackable-labs/lib-utils-js';
|
|
10
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
11
|
+
import TextInput from 'ink-text-input';
|
|
12
|
+
import { execFile, spawn } from 'child_process';
|
|
13
|
+
import { promisify } from 'util';
|
|
14
|
+
import { installDependencies } from 'nypm';
|
|
15
|
+
import { downloadTemplate } from 'giget';
|
|
16
|
+
import { Tunnel } from 'cloudflared';
|
|
17
|
+
import clipboard from 'clipboardy';
|
|
18
|
+
import { existsSync, readFileSync } from 'fs';
|
|
19
|
+
import AdmZip from 'adm-zip';
|
|
20
|
+
import { createServer } from 'http';
|
|
21
|
+
import open from 'open';
|
|
22
|
+
import { homedir } from 'os';
|
|
23
|
+
import https from 'https';
|
|
2
24
|
|
|
3
|
-
// src/index.tsx
|
|
4
|
-
import { createRequire } from "module";
|
|
5
|
-
import { program } from "commander";
|
|
6
|
-
import { render } from "ink";
|
|
7
|
-
|
|
8
|
-
// src/App.tsx
|
|
9
|
-
import { readFile as readFile3 } from "fs/promises";
|
|
10
|
-
import { join as join3 } from "path";
|
|
11
|
-
import { Box as Box15, Text as Text15, useApp } from "ink";
|
|
12
|
-
import Spinner4 from "ink-spinner";
|
|
13
|
-
import { useCallback as useCallback2, useEffect as useEffect4, useState as useState11 } from "react";
|
|
14
|
-
|
|
15
|
-
// src/components/Banner.tsx
|
|
16
|
-
import { Box, Text } from "ink";
|
|
17
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
18
25
|
var WORDMARK = [
|
|
19
26
|
" _ _ _ _ ",
|
|
20
27
|
" ___| |_ __ _ ___| | ____ _| |__ | | ___",
|
|
@@ -68,11 +75,6 @@ var Banner = ({ userId, orgId } = {}) => {
|
|
|
68
75
|
] });
|
|
69
76
|
};
|
|
70
77
|
|
|
71
|
-
// src/components/Confirm.tsx
|
|
72
|
-
import { Box as Box3, Text as Text3, useFocus, useFocusManager, useInput as useInput2 } from "ink";
|
|
73
|
-
import TextInput from "ink-text-input";
|
|
74
|
-
import { useEffect, useState } from "react";
|
|
75
|
-
|
|
76
78
|
// src/constants.ts
|
|
77
79
|
var TEMPLATE_SOURCES = {
|
|
78
80
|
minimal: "github:stackable-labs/templates/app-extension-minimal",
|
|
@@ -106,10 +108,6 @@ var TARGET_PERMISSION_MAP = {
|
|
|
106
108
|
"slot.footer": [],
|
|
107
109
|
"slot.footer-links": []
|
|
108
110
|
};
|
|
109
|
-
|
|
110
|
-
// src/components/StepShell.tsx
|
|
111
|
-
import { Box as Box2, Text as Text2, useInput } from "ink";
|
|
112
|
-
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
113
111
|
var divider = (width) => "\u2500".repeat(width);
|
|
114
112
|
var INNER_DIVIDER_WIDTH = 40;
|
|
115
113
|
var StepShell = ({ title, hint, children, footer, onBack }) => {
|
|
@@ -119,29 +117,26 @@ var StepShell = ({ title, hint, children, footer, onBack }) => {
|
|
|
119
117
|
onBack();
|
|
120
118
|
}
|
|
121
119
|
});
|
|
122
|
-
return /* @__PURE__ */
|
|
123
|
-
/* @__PURE__ */
|
|
124
|
-
/* @__PURE__ */
|
|
125
|
-
/* @__PURE__ */
|
|
126
|
-
onBack && /* @__PURE__ */
|
|
127
|
-
/* @__PURE__ */
|
|
128
|
-
/* @__PURE__ */
|
|
120
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 0, children: [
|
|
121
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: divider(termWidth) }),
|
|
122
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 1, paddingY: 1, gap: 1, children: [
|
|
123
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 0, children: [
|
|
124
|
+
onBack && /* @__PURE__ */ jsxs(Box, { gap: 1, marginBottom: 1, children: [
|
|
125
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2190 Back" }),
|
|
126
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "(Esc)" })
|
|
129
127
|
] }),
|
|
130
|
-
/* @__PURE__ */
|
|
131
|
-
hint && /* @__PURE__ */
|
|
128
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: title }),
|
|
129
|
+
hint && /* @__PURE__ */ jsx(Text, { dimColor: true, children: hint })
|
|
132
130
|
] }),
|
|
133
|
-
/* @__PURE__ */
|
|
131
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: divider(INNER_DIVIDER_WIDTH) }),
|
|
134
132
|
children
|
|
135
133
|
] }),
|
|
136
|
-
footer && /* @__PURE__ */
|
|
137
|
-
/* @__PURE__ */
|
|
138
|
-
/* @__PURE__ */
|
|
134
|
+
footer && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
135
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: divider(termWidth) }),
|
|
136
|
+
/* @__PURE__ */ jsx(Box, { paddingX: 1, paddingTop: 1, children: footer })
|
|
139
137
|
] })
|
|
140
138
|
] });
|
|
141
139
|
};
|
|
142
|
-
|
|
143
|
-
// src/components/Confirm.tsx
|
|
144
|
-
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
145
140
|
var compareSemver = (a, b) => {
|
|
146
141
|
const pa = a.split(".").map(Number);
|
|
147
142
|
const pb = b.split(".").map(Number);
|
|
@@ -154,7 +149,7 @@ var compareSemver = (a, b) => {
|
|
|
154
149
|
var VersionRow = ({ currentVersion, value, onChange, onFocusChange, onConfirm, onCancel, selected }) => {
|
|
155
150
|
const { isFocused } = useFocus();
|
|
156
151
|
const { focusPrevious, focusNext } = useFocusManager();
|
|
157
|
-
|
|
152
|
+
useInput((_, key) => {
|
|
158
153
|
if (!isFocused) return;
|
|
159
154
|
if (key.upArrow) {
|
|
160
155
|
focusPrevious();
|
|
@@ -177,17 +172,17 @@ var VersionRow = ({ currentVersion, value, onChange, onFocusChange, onConfirm, o
|
|
|
177
172
|
const isValid = /^\d+\.\d+\.\d+$/.test(value) && compareSemver(value, currentVersion) > 0;
|
|
178
173
|
const showError = isFocused && value !== "" && !isValid;
|
|
179
174
|
const hasChange = value !== currentVersion;
|
|
180
|
-
return /* @__PURE__ */
|
|
181
|
-
/* @__PURE__ */
|
|
182
|
-
/* @__PURE__ */
|
|
183
|
-
/* @__PURE__ */
|
|
175
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
176
|
+
/* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
177
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Version " }),
|
|
178
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
184
179
|
currentVersion,
|
|
185
180
|
hasChange ? " \u2192 " : ""
|
|
186
181
|
] }),
|
|
187
|
-
isFocused ? /* @__PURE__ */
|
|
188
|
-
isFocused && /* @__PURE__ */
|
|
182
|
+
isFocused ? /* @__PURE__ */ jsx(TextInput, { value, onChange, placeholder: value }) : hasChange && /* @__PURE__ */ jsx(Text, { dimColor: true, children: value }),
|
|
183
|
+
isFocused && /* @__PURE__ */ jsx(Text, { dimColor: true, children: "(edit to override)" })
|
|
189
184
|
] }),
|
|
190
|
-
showError && /* @__PURE__ */
|
|
185
|
+
showError && /* @__PURE__ */ jsx(Text, { color: "red", children: " Version must be greater than " + currentVersion })
|
|
191
186
|
] });
|
|
192
187
|
};
|
|
193
188
|
var Confirm = ({
|
|
@@ -214,7 +209,7 @@ var Confirm = ({
|
|
|
214
209
|
}) => {
|
|
215
210
|
const [selected, setSelected] = useState("y");
|
|
216
211
|
const [overrideFocused, setOverrideFocused] = useState(false);
|
|
217
|
-
|
|
212
|
+
useInput((input, key) => {
|
|
218
213
|
if (overrideFocused) return;
|
|
219
214
|
if (key.leftArrow || key.rightArrow) {
|
|
220
215
|
setSelected((s) => s === "y" ? "n" : "y");
|
|
@@ -238,29 +233,29 @@ var Confirm = ({
|
|
|
238
233
|
}
|
|
239
234
|
}
|
|
240
235
|
});
|
|
241
|
-
return /* @__PURE__ */
|
|
236
|
+
return /* @__PURE__ */ jsx(
|
|
242
237
|
StepShell,
|
|
243
238
|
{
|
|
244
239
|
title: command === "update" /* UPDATE */ ? "Ready to update" : "Ready to scaffold",
|
|
245
240
|
hint: "Review your settings before proceeding",
|
|
246
241
|
onBack,
|
|
247
|
-
footer: /* @__PURE__ */
|
|
242
|
+
footer: /* @__PURE__ */ jsxs(Text, { children: [
|
|
248
243
|
"Proceed?",
|
|
249
244
|
" ",
|
|
250
|
-
/* @__PURE__ */
|
|
251
|
-
/* @__PURE__ */
|
|
252
|
-
/* @__PURE__ */
|
|
245
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "green", inverse: selected === "y", children: "Y" }),
|
|
246
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "/" }),
|
|
247
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "red", inverse: selected === "n", children: "n" })
|
|
253
248
|
] }),
|
|
254
|
-
children: /* @__PURE__ */
|
|
255
|
-
/* @__PURE__ */
|
|
256
|
-
/* @__PURE__ */
|
|
257
|
-
/* @__PURE__ */
|
|
249
|
+
children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
250
|
+
/* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
251
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Name " }),
|
|
252
|
+
/* @__PURE__ */ jsx(Text, { dimColor: !!extensionVersion, children: name })
|
|
258
253
|
] }),
|
|
259
|
-
templateFlavor && /* @__PURE__ */
|
|
260
|
-
/* @__PURE__ */
|
|
261
|
-
/* @__PURE__ */
|
|
254
|
+
templateFlavor && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
255
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Template " }),
|
|
256
|
+
/* @__PURE__ */ jsx(Text, { children: TEMPLATE_FLAVOR_META[templateFlavor].label })
|
|
262
257
|
] }),
|
|
263
|
-
extensionVersion && command === "update" /* UPDATE */ && newVersion && onVersionOverride && /* @__PURE__ */
|
|
258
|
+
extensionVersion && command === "update" /* UPDATE */ && newVersion && onVersionOverride && /* @__PURE__ */ jsx(
|
|
264
259
|
VersionRow,
|
|
265
260
|
{
|
|
266
261
|
currentVersion: extensionVersion,
|
|
@@ -272,84 +267,84 @@ var Confirm = ({
|
|
|
272
267
|
selected
|
|
273
268
|
}
|
|
274
269
|
),
|
|
275
|
-
extensionVersion && !(command === "update" /* UPDATE */ && newVersion && onVersionOverride) && /* @__PURE__ */
|
|
276
|
-
/* @__PURE__ */
|
|
277
|
-
/* @__PURE__ */
|
|
270
|
+
extensionVersion && !(command === "update" /* UPDATE */ && newVersion && onVersionOverride) && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
271
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Version " }),
|
|
272
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
278
273
|
extensionVersion,
|
|
279
274
|
newVersion && newVersion !== extensionVersion ? ` \u2192 ${newVersion}` : ""
|
|
280
275
|
] })
|
|
281
276
|
] }),
|
|
282
|
-
command !== "update" /* UPDATE */ && outputDir && /* @__PURE__ */
|
|
283
|
-
/* @__PURE__ */
|
|
284
|
-
/* @__PURE__ */
|
|
277
|
+
command !== "update" /* UPDATE */ && outputDir && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
278
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Directory " }),
|
|
279
|
+
/* @__PURE__ */ jsx(Text, { children: outputDir })
|
|
285
280
|
] }),
|
|
286
|
-
command !== "update" /* UPDATE */ && extensionPort !== void 0 && /* @__PURE__ */
|
|
287
|
-
/* @__PURE__ */
|
|
288
|
-
/* @__PURE__ */
|
|
281
|
+
command !== "update" /* UPDATE */ && extensionPort !== void 0 && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
282
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Extension port" }),
|
|
283
|
+
/* @__PURE__ */ jsx(Text, { children: extensionPort })
|
|
289
284
|
] }),
|
|
290
|
-
command !== "update" /* UPDATE */ && previewPort !== void 0 && /* @__PURE__ */
|
|
291
|
-
/* @__PURE__ */
|
|
292
|
-
/* @__PURE__ */
|
|
285
|
+
command !== "update" /* UPDATE */ && previewPort !== void 0 && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
286
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Preview port " }),
|
|
287
|
+
/* @__PURE__ */ jsx(Text, { children: previewPort })
|
|
293
288
|
] }),
|
|
294
|
-
command === "update" /* UPDATE */ && bundleUrl && /* @__PURE__ */
|
|
295
|
-
/* @__PURE__ */
|
|
296
|
-
/* @__PURE__ */
|
|
289
|
+
command === "update" /* UPDATE */ && bundleUrl && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
290
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Bundle URL " }),
|
|
291
|
+
/* @__PURE__ */ jsx(Text, { children: bundleUrl })
|
|
297
292
|
] }),
|
|
298
|
-
command === "update" /* UPDATE */ && enabled !== void 0 && /* @__PURE__ */
|
|
299
|
-
/* @__PURE__ */
|
|
300
|
-
/* @__PURE__ */
|
|
293
|
+
command === "update" /* UPDATE */ && enabled !== void 0 && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
294
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Enabled " }),
|
|
295
|
+
/* @__PURE__ */ jsx(Text, { color: enabled ? "green" : "red", children: enabled ? "Yes" : "No" })
|
|
301
296
|
] }),
|
|
302
|
-
/* @__PURE__ */
|
|
303
|
-
/* @__PURE__ */
|
|
304
|
-
/* @__PURE__ */
|
|
297
|
+
/* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
298
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Targets " }),
|
|
299
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
305
300
|
targets.map((t) => {
|
|
306
301
|
const isAdded = registryTargets && !registryTargets.includes(t);
|
|
307
|
-
return /* @__PURE__ */
|
|
308
|
-
/* @__PURE__ */
|
|
309
|
-
/* @__PURE__ */
|
|
310
|
-
isAdded && /* @__PURE__ */
|
|
302
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
303
|
+
/* @__PURE__ */ jsx(Text, { color: "green", children: "\u2022 " }),
|
|
304
|
+
/* @__PURE__ */ jsx(Text, { children: t }),
|
|
305
|
+
isAdded && /* @__PURE__ */ jsx(Text, { color: "green", dimColor: true, children: "(+ added)" })
|
|
311
306
|
] }, t);
|
|
312
307
|
}),
|
|
313
|
-
registryTargets?.filter((t) => !targets.includes(t)).map((t) => /* @__PURE__ */
|
|
314
|
-
/* @__PURE__ */
|
|
315
|
-
/* @__PURE__ */
|
|
316
|
-
/* @__PURE__ */
|
|
308
|
+
registryTargets?.filter((t) => !targets.includes(t)).map((t) => /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
309
|
+
/* @__PURE__ */ jsx(Text, { color: "red", children: "\u2022 " }),
|
|
310
|
+
/* @__PURE__ */ jsx(Text, { color: "red", dimColor: true, strikethrough: true, children: t }),
|
|
311
|
+
/* @__PURE__ */ jsx(Text, { color: "red", dimColor: true, children: "(- removed)" })
|
|
317
312
|
] }, t))
|
|
318
313
|
] })
|
|
319
314
|
] }),
|
|
320
|
-
permissions && (permissions.length > 0 || registryPermissions?.some((p) => !permissions.includes(p))) && /* @__PURE__ */
|
|
321
|
-
/* @__PURE__ */
|
|
322
|
-
/* @__PURE__ */
|
|
315
|
+
permissions && (permissions.length > 0 || registryPermissions?.some((p) => !permissions.includes(p))) && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
316
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Permissions " }),
|
|
317
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
323
318
|
permissions.map((p) => {
|
|
324
319
|
const isAdded = registryPermissions && !registryPermissions.includes(p);
|
|
325
|
-
return /* @__PURE__ */
|
|
326
|
-
/* @__PURE__ */
|
|
327
|
-
/* @__PURE__ */
|
|
328
|
-
isAdded && /* @__PURE__ */
|
|
320
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
321
|
+
/* @__PURE__ */ jsx(Text, { color: "green", children: "\u2022 " }),
|
|
322
|
+
/* @__PURE__ */ jsx(Text, { children: p }),
|
|
323
|
+
isAdded && /* @__PURE__ */ jsx(Text, { color: "green", dimColor: true, children: "(+ added)" })
|
|
329
324
|
] }, p);
|
|
330
325
|
}),
|
|
331
|
-
registryPermissions?.filter((p) => !permissions.includes(p)).map((p) => /* @__PURE__ */
|
|
332
|
-
/* @__PURE__ */
|
|
333
|
-
/* @__PURE__ */
|
|
334
|
-
/* @__PURE__ */
|
|
326
|
+
registryPermissions?.filter((p) => !permissions.includes(p)).map((p) => /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
327
|
+
/* @__PURE__ */ jsx(Text, { color: "red", children: "\u2022 " }),
|
|
328
|
+
/* @__PURE__ */ jsx(Text, { color: "red", dimColor: true, strikethrough: true, children: p }),
|
|
329
|
+
/* @__PURE__ */ jsx(Text, { color: "red", dimColor: true, children: "(- removed)" })
|
|
335
330
|
] }, p))
|
|
336
331
|
] })
|
|
337
332
|
] }),
|
|
338
|
-
allowedDomains && (allowedDomains.length > 0 || registryAllowedDomains?.some((d) => !allowedDomains.includes(d))) && /* @__PURE__ */
|
|
339
|
-
/* @__PURE__ */
|
|
340
|
-
/* @__PURE__ */
|
|
333
|
+
allowedDomains && (allowedDomains.length > 0 || registryAllowedDomains?.some((d) => !allowedDomains.includes(d))) && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
334
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Domains " }),
|
|
335
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
341
336
|
allowedDomains.map((d) => {
|
|
342
337
|
const isAdded = registryAllowedDomains && !registryAllowedDomains.includes(d);
|
|
343
|
-
return /* @__PURE__ */
|
|
344
|
-
/* @__PURE__ */
|
|
345
|
-
/* @__PURE__ */
|
|
346
|
-
isAdded && /* @__PURE__ */
|
|
338
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
339
|
+
/* @__PURE__ */ jsx(Text, { color: "green", children: "\u2022 " }),
|
|
340
|
+
/* @__PURE__ */ jsx(Text, { children: d }),
|
|
341
|
+
isAdded && /* @__PURE__ */ jsx(Text, { color: "green", dimColor: true, children: "(+ added)" })
|
|
347
342
|
] }, d);
|
|
348
343
|
}),
|
|
349
|
-
registryAllowedDomains?.filter((d) => !allowedDomains.includes(d)).map((d) => /* @__PURE__ */
|
|
350
|
-
/* @__PURE__ */
|
|
351
|
-
/* @__PURE__ */
|
|
352
|
-
/* @__PURE__ */
|
|
344
|
+
registryAllowedDomains?.filter((d) => !allowedDomains.includes(d)).map((d) => /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
345
|
+
/* @__PURE__ */ jsx(Text, { color: "red", children: "\u2022 " }),
|
|
346
|
+
/* @__PURE__ */ jsx(Text, { color: "red", dimColor: true, strikethrough: true, children: d }),
|
|
347
|
+
/* @__PURE__ */ jsx(Text, { color: "red", dimColor: true, children: "(- removed)" })
|
|
353
348
|
] }, d))
|
|
354
349
|
] })
|
|
355
350
|
] })
|
|
@@ -357,75 +352,59 @@ var Confirm = ({
|
|
|
357
352
|
}
|
|
358
353
|
);
|
|
359
354
|
};
|
|
360
|
-
|
|
361
|
-
// src/components/Done.tsx
|
|
362
|
-
import { Box as Box4, Text as Text4 } from "ink";
|
|
363
|
-
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
364
355
|
var FLAVOR_HINTS = {
|
|
365
356
|
minimal: "A clean slate \u2014 add surfaces and capabilities as you need them.",
|
|
366
357
|
starter: "Common patterns included \u2014 customize and build from here.",
|
|
367
358
|
"kitchen-sink": "We threw in everything \u2014 including the kitchen sink. Poke around, steal patterns, then delete what you don't need."
|
|
368
359
|
};
|
|
369
|
-
var Done = ({ name, outputDir, templateFlavor }) => /* @__PURE__ */
|
|
370
|
-
/* @__PURE__ */
|
|
371
|
-
/* @__PURE__ */
|
|
372
|
-
/* @__PURE__ */
|
|
360
|
+
var Done = ({ name, outputDir, templateFlavor }) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
361
|
+
/* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
362
|
+
/* @__PURE__ */ jsx(Text, { color: "green", bold: true, children: "\u2714" }),
|
|
363
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Extension scaffolded successfully!" })
|
|
373
364
|
] }),
|
|
374
|
-
/* @__PURE__ */
|
|
375
|
-
/* @__PURE__ */
|
|
365
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [
|
|
366
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
376
367
|
"Created: ",
|
|
377
|
-
/* @__PURE__ */
|
|
368
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: name })
|
|
378
369
|
] }),
|
|
379
|
-
templateFlavor && /* @__PURE__ */
|
|
370
|
+
templateFlavor && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
380
371
|
"Template: ",
|
|
381
|
-
/* @__PURE__ */
|
|
372
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: TEMPLATE_FLAVOR_META[templateFlavor].label })
|
|
382
373
|
] }),
|
|
383
|
-
/* @__PURE__ */
|
|
374
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
384
375
|
"Location: ",
|
|
385
|
-
/* @__PURE__ */
|
|
376
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: outputDir })
|
|
386
377
|
] })
|
|
387
378
|
] }),
|
|
388
|
-
templateFlavor && /* @__PURE__ */
|
|
389
|
-
/* @__PURE__ */
|
|
390
|
-
/* @__PURE__ */
|
|
391
|
-
/* @__PURE__ */
|
|
392
|
-
/* @__PURE__ */
|
|
393
|
-
/* @__PURE__ */
|
|
394
|
-
/* @__PURE__ */
|
|
395
|
-
/* @__PURE__ */
|
|
396
|
-
/* @__PURE__ */
|
|
379
|
+
templateFlavor && /* @__PURE__ */ jsx(Box, { marginLeft: 2, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: FLAVOR_HINTS[templateFlavor] }) }),
|
|
380
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, borderStyle: "round", borderColor: "green", paddingX: 2, paddingY: 1, children: [
|
|
381
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Next steps:" }),
|
|
382
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, gap: 1, children: [
|
|
383
|
+
/* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
384
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "1." }),
|
|
385
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
386
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "cd " }),
|
|
387
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: outputDir })
|
|
397
388
|
] })
|
|
398
389
|
] }),
|
|
399
|
-
/* @__PURE__ */
|
|
400
|
-
/* @__PURE__ */
|
|
401
|
-
/* @__PURE__ */
|
|
390
|
+
/* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
391
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "2." }),
|
|
392
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: "pnpm install" })
|
|
402
393
|
] }),
|
|
403
|
-
/* @__PURE__ */
|
|
404
|
-
/* @__PURE__ */
|
|
405
|
-
/* @__PURE__ */
|
|
394
|
+
/* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
395
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "3." }),
|
|
396
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: "pnpm dev" })
|
|
406
397
|
] })
|
|
407
398
|
] })
|
|
408
399
|
] })
|
|
409
400
|
] });
|
|
410
|
-
|
|
411
|
-
// src/components/NamePrompt.tsx
|
|
412
|
-
import { Box as Box6, Text as Text6 } from "ink";
|
|
413
|
-
import TextInput2 from "ink-text-input";
|
|
414
|
-
import { useState as useState2 } from "react";
|
|
415
|
-
|
|
416
|
-
// src/components/BackableInput.tsx
|
|
417
|
-
import { Box as Box5, Text as Text5 } from "ink";
|
|
418
|
-
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
419
|
-
var BackableInput = ({ label, hint, onBack, children, error }) => /* @__PURE__ */ jsx5(StepShell, { title: label, hint, onBack, children: /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", gap: 1, children: [
|
|
401
|
+
var BackableInput = ({ label, hint, onBack, children, error }) => /* @__PURE__ */ jsx(StepShell, { title: label, hint, onBack, children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
420
402
|
children(true),
|
|
421
|
-
error && /* @__PURE__ */
|
|
403
|
+
error && /* @__PURE__ */ jsx(Text, { color: "red", children: error })
|
|
422
404
|
] }) });
|
|
423
|
-
|
|
424
|
-
// src/components/NamePrompt.tsx
|
|
425
|
-
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
426
405
|
var NamePrompt = ({ initialValue = "", onSubmit, onBack }) => {
|
|
427
|
-
const [value, setValue] =
|
|
428
|
-
const [error, setError] =
|
|
406
|
+
const [value, setValue] = useState(initialValue);
|
|
407
|
+
const [error, setError] = useState();
|
|
429
408
|
const handleSubmit = (val) => {
|
|
430
409
|
const trimmed = val.trim();
|
|
431
410
|
if (trimmed.length === 0) {
|
|
@@ -435,33 +414,27 @@ var NamePrompt = ({ initialValue = "", onSubmit, onBack }) => {
|
|
|
435
414
|
setError(void 0);
|
|
436
415
|
onSubmit(trimmed);
|
|
437
416
|
};
|
|
438
|
-
return /* @__PURE__ */
|
|
439
|
-
/* @__PURE__ */
|
|
440
|
-
/* @__PURE__ */
|
|
417
|
+
return /* @__PURE__ */ jsx(BackableInput, { label: "What is your Extension name?", hint: "Press Enter to confirm", onBack, error, children: (isFocused) => /* @__PURE__ */ jsxs(Box, { children: [
|
|
418
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "> " }),
|
|
419
|
+
/* @__PURE__ */ jsx(TextInput, { value, onChange: setValue, onSubmit: handleSubmit, focus: isFocused })
|
|
441
420
|
] }) });
|
|
442
421
|
};
|
|
443
|
-
|
|
444
|
-
// src/components/SettingsPrompt.tsx
|
|
445
|
-
import { Box as Box7, Text as Text7, useFocus as useFocus2, useFocusManager as useFocusManager2, useInput as useInput3 } from "ink";
|
|
446
|
-
import TextInput3 from "ink-text-input";
|
|
447
|
-
import { useState as useState3 } from "react";
|
|
448
|
-
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
449
422
|
var DEFAULT_EXTENSION_PORT = 6543;
|
|
450
423
|
var DEFAULT_PREVIEW_PORT = DEFAULT_EXTENSION_PORT + 1;
|
|
451
424
|
var FieldRow = ({ label, value, onChange, onSubmit, onConfirm, placeholder, autoFocus, isFirst, isLast }) => {
|
|
452
|
-
const { isFocused } =
|
|
453
|
-
const { focusNext, focusPrevious } =
|
|
454
|
-
|
|
425
|
+
const { isFocused } = useFocus({ autoFocus });
|
|
426
|
+
const { focusNext, focusPrevious } = useFocusManager();
|
|
427
|
+
useInput((_input, key) => {
|
|
455
428
|
if (!isFocused) return;
|
|
456
429
|
if (key.downArrow && !isLast) focusNext();
|
|
457
430
|
if (key.upArrow && !isFirst) focusPrevious();
|
|
458
431
|
});
|
|
459
|
-
return /* @__PURE__ */
|
|
460
|
-
/* @__PURE__ */
|
|
461
|
-
isFocused ? /* @__PURE__ */
|
|
462
|
-
/* @__PURE__ */
|
|
463
|
-
/* @__PURE__ */
|
|
464
|
-
|
|
432
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
433
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: label }),
|
|
434
|
+
isFocused ? /* @__PURE__ */ jsxs(Box, { children: [
|
|
435
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u2192 " }),
|
|
436
|
+
/* @__PURE__ */ jsx(
|
|
437
|
+
TextInput,
|
|
465
438
|
{
|
|
466
439
|
value,
|
|
467
440
|
onChange,
|
|
@@ -473,13 +446,13 @@ var FieldRow = ({ label, value, onChange, onSubmit, onConfirm, placeholder, auto
|
|
|
473
446
|
focus: isFocused
|
|
474
447
|
}
|
|
475
448
|
)
|
|
476
|
-
] }) : /* @__PURE__ */
|
|
449
|
+
] }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: value })
|
|
477
450
|
] });
|
|
478
451
|
};
|
|
479
452
|
var SettingsPrompt = ({ defaultDir, onSubmit, onBack }) => {
|
|
480
|
-
const [extensionPort, setExtensionPort] =
|
|
481
|
-
const [previewPort, setPreviewPort] =
|
|
482
|
-
const [outputDir, setOutputDir] =
|
|
453
|
+
const [extensionPort, setExtensionPort] = useState(String(DEFAULT_EXTENSION_PORT));
|
|
454
|
+
const [previewPort, setPreviewPort] = useState(String(DEFAULT_PREVIEW_PORT));
|
|
455
|
+
const [outputDir, setOutputDir] = useState(defaultDir);
|
|
483
456
|
const handleConfirm = (resolvedExtPort, resolvedPrevPort, resolvedDir) => {
|
|
484
457
|
const dir = resolvedDir.trim();
|
|
485
458
|
if (!dir) return;
|
|
@@ -510,14 +483,14 @@ var SettingsPrompt = ({ defaultDir, onSubmit, onBack }) => {
|
|
|
510
483
|
setOutputDir(trimmed);
|
|
511
484
|
return [extensionPort, previewPort, trimmed];
|
|
512
485
|
};
|
|
513
|
-
return /* @__PURE__ */
|
|
486
|
+
return /* @__PURE__ */ jsx(
|
|
514
487
|
StepShell,
|
|
515
488
|
{
|
|
516
489
|
title: "Project settings",
|
|
517
490
|
hint: "\u2191\u2193 or Tab to move between fields, Enter to confirm",
|
|
518
491
|
onBack,
|
|
519
|
-
children: /* @__PURE__ */
|
|
520
|
-
/* @__PURE__ */
|
|
492
|
+
children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
493
|
+
/* @__PURE__ */ jsx(
|
|
521
494
|
FieldRow,
|
|
522
495
|
{
|
|
523
496
|
label: "Extension port ",
|
|
@@ -530,7 +503,7 @@ var SettingsPrompt = ({ defaultDir, onSubmit, onBack }) => {
|
|
|
530
503
|
isFirst: true
|
|
531
504
|
}
|
|
532
505
|
),
|
|
533
|
-
/* @__PURE__ */
|
|
506
|
+
/* @__PURE__ */ jsx(
|
|
534
507
|
FieldRow,
|
|
535
508
|
{
|
|
536
509
|
label: "Preview port ",
|
|
@@ -541,7 +514,7 @@ var SettingsPrompt = ({ defaultDir, onSubmit, onBack }) => {
|
|
|
541
514
|
placeholder: String(DEFAULT_PREVIEW_PORT)
|
|
542
515
|
}
|
|
543
516
|
),
|
|
544
|
-
/* @__PURE__ */
|
|
517
|
+
/* @__PURE__ */ jsx(
|
|
545
518
|
FieldRow,
|
|
546
519
|
{
|
|
547
520
|
label: "Output directory",
|
|
@@ -557,10 +530,6 @@ var SettingsPrompt = ({ defaultDir, onSubmit, onBack }) => {
|
|
|
557
530
|
);
|
|
558
531
|
};
|
|
559
532
|
|
|
560
|
-
// src/components/ManifestReviewPrompt.tsx
|
|
561
|
-
import { Box as Box8, Text as Text8, useInput as useInput4 } from "ink";
|
|
562
|
-
import { useState as useState4 } from "react";
|
|
563
|
-
|
|
564
533
|
// src/lib/manifest-diff.ts
|
|
565
534
|
var diffManifestValues = (localValues, registryValues) => {
|
|
566
535
|
const localSet = new Set(localValues ?? []);
|
|
@@ -575,9 +544,6 @@ var diffManifestValues = (localValues, registryValues) => {
|
|
|
575
544
|
return inRegistry ? { value, status: "unchanged", enabled: true } : { value, status: "new", enabled: false };
|
|
576
545
|
});
|
|
577
546
|
};
|
|
578
|
-
|
|
579
|
-
// src/components/ManifestReviewPrompt.tsx
|
|
580
|
-
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
581
547
|
var statusLabel = (status) => {
|
|
582
548
|
switch (status) {
|
|
583
549
|
case "new":
|
|
@@ -604,9 +570,9 @@ var ManifestReviewPrompt = ({
|
|
|
604
570
|
onSubmit,
|
|
605
571
|
onBack
|
|
606
572
|
}) => {
|
|
607
|
-
const [permItems, setPermItems] =
|
|
608
|
-
const [domainItems, setDomainItems] =
|
|
609
|
-
const [cursor, setCursor] =
|
|
573
|
+
const [permItems, setPermItems] = useState(() => diffManifestValues(localManifest?.permissions, registryManifest.permissions));
|
|
574
|
+
const [domainItems, setDomainItems] = useState(() => diffManifestValues(localManifest?.allowedDomains, registryManifest.allowedDomains));
|
|
575
|
+
const [cursor, setCursor] = useState(0);
|
|
610
576
|
const totalItems = permItems.length + domainItems.length;
|
|
611
577
|
const cursorInPerms = cursor < permItems.length;
|
|
612
578
|
const cursorInDomains = cursor >= permItems.length;
|
|
@@ -625,7 +591,7 @@ var ManifestReviewPrompt = ({
|
|
|
625
591
|
});
|
|
626
592
|
};
|
|
627
593
|
const domainSectionStart = permItems.length;
|
|
628
|
-
|
|
594
|
+
useInput((input, key) => {
|
|
629
595
|
if (key.downArrow) {
|
|
630
596
|
setCursor((c) => Math.min(c + 1, totalItems - 1));
|
|
631
597
|
return;
|
|
@@ -658,49 +624,43 @@ var ManifestReviewPrompt = ({
|
|
|
658
624
|
});
|
|
659
625
|
const renderItem = (item, index) => {
|
|
660
626
|
const isCursor = index === cursor;
|
|
661
|
-
return /* @__PURE__ */
|
|
662
|
-
/* @__PURE__ */
|
|
663
|
-
/* @__PURE__ */
|
|
664
|
-
/* @__PURE__ */
|
|
665
|
-
statusLabel(item.status) && /* @__PURE__ */
|
|
627
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
628
|
+
/* @__PURE__ */ jsx(Text, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
|
|
629
|
+
/* @__PURE__ */ jsx(Text, { color: item.enabled ? "green" : "gray", children: item.enabled ? "\u25C9" : "\u25CB" }),
|
|
630
|
+
/* @__PURE__ */ jsx(Text, { bold: isCursor, children: item.value }),
|
|
631
|
+
statusLabel(item.status) && /* @__PURE__ */ jsx(Text, { color: statusColor(item.status), dimColor: true, children: statusLabel(item.status) })
|
|
666
632
|
] }, item.value);
|
|
667
633
|
};
|
|
668
|
-
return /* @__PURE__ */
|
|
634
|
+
return /* @__PURE__ */ jsx(
|
|
669
635
|
StepShell,
|
|
670
636
|
{
|
|
671
637
|
title: "Review Manifest changes",
|
|
672
638
|
hint: "Tab/shift-tab to jump section, \u2191/\u2193 navigate. Enter to submit",
|
|
673
639
|
onBack,
|
|
674
|
-
children: /* @__PURE__ */
|
|
675
|
-
!localManifest && /* @__PURE__ */
|
|
676
|
-
/* @__PURE__ */
|
|
677
|
-
/* @__PURE__ */
|
|
678
|
-
/* @__PURE__ */
|
|
679
|
-
permItems.length > 0 ? permItems.map((item, i) => renderItem(item, i)) : /* @__PURE__ */
|
|
680
|
-
cursorInPerms && /* @__PURE__ */
|
|
640
|
+
children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
641
|
+
!localManifest && /* @__PURE__ */ jsx(Text, { color: "yellow", children: "No local manifest.json found \u2014 showing registry values only" }),
|
|
642
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
643
|
+
/* @__PURE__ */ jsx(Text, { dimColor: !cursorInPerms, bold: cursorInPerms, children: "Permissions".padEnd(14) }),
|
|
644
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingLeft: 2, children: [
|
|
645
|
+
permItems.length > 0 ? permItems.map((item, i) => renderItem(item, i)) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: " (none)" }),
|
|
646
|
+
cursorInPerms && /* @__PURE__ */ jsx(Text, { dimColor: true, children: " (space to toggle)" })
|
|
681
647
|
] })
|
|
682
648
|
] }),
|
|
683
|
-
/* @__PURE__ */
|
|
684
|
-
/* @__PURE__ */
|
|
685
|
-
/* @__PURE__ */
|
|
686
|
-
domainItems.length > 0 ? domainItems.map((item, i) => renderItem(item, i + permItems.length)) : /* @__PURE__ */
|
|
687
|
-
cursorInDomains && /* @__PURE__ */
|
|
649
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
650
|
+
/* @__PURE__ */ jsx(Text, { dimColor: !cursorInDomains, bold: cursorInDomains, children: "Allowed Domains".padEnd(14) }),
|
|
651
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingLeft: 2, children: [
|
|
652
|
+
domainItems.length > 0 ? domainItems.map((item, i) => renderItem(item, i + permItems.length)) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: " (none)" }),
|
|
653
|
+
cursorInDomains && /* @__PURE__ */ jsx(Text, { dimColor: true, children: " (space to toggle)" })
|
|
688
654
|
] })
|
|
689
655
|
] })
|
|
690
656
|
] })
|
|
691
657
|
}
|
|
692
658
|
);
|
|
693
659
|
};
|
|
694
|
-
|
|
695
|
-
// src/components/UpdateSettingsPrompt.tsx
|
|
696
|
-
import { Box as Box9, Text as Text9, useFocus as useFocus3, useFocusManager as useFocusManager3, useInput as useInput5 } from "ink";
|
|
697
|
-
import TextInput4 from "ink-text-input";
|
|
698
|
-
import { useState as useState5 } from "react";
|
|
699
|
-
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
700
660
|
var FieldRow2 = ({ label, value, onChange, placeholder, autoFocus, isFirst, isLast, onSubmitAll }) => {
|
|
701
|
-
const { isFocused } =
|
|
702
|
-
const { focusNext, focusPrevious } =
|
|
703
|
-
|
|
661
|
+
const { isFocused } = useFocus({ autoFocus });
|
|
662
|
+
const { focusNext, focusPrevious } = useFocusManager();
|
|
663
|
+
useInput((_, key) => {
|
|
704
664
|
if (!isFocused) return;
|
|
705
665
|
if (key.downArrow) {
|
|
706
666
|
if (!isLast) focusNext();
|
|
@@ -714,16 +674,16 @@ var FieldRow2 = ({ label, value, onChange, placeholder, autoFocus, isFirst, isLa
|
|
|
714
674
|
onSubmitAll();
|
|
715
675
|
}
|
|
716
676
|
});
|
|
717
|
-
return /* @__PURE__ */
|
|
718
|
-
/* @__PURE__ */
|
|
719
|
-
isFocused ? /* @__PURE__ */
|
|
677
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
678
|
+
/* @__PURE__ */ jsx(Text, { dimColor: !isFocused, bold: isFocused, children: label.padEnd(14) }),
|
|
679
|
+
isFocused ? /* @__PURE__ */ jsx(TextInput, { value, onChange, placeholder }) : /* @__PURE__ */ jsx(Text, { dimColor: true, children: value || placeholder || "" })
|
|
720
680
|
] });
|
|
721
681
|
};
|
|
722
682
|
var TargetToggleRow = ({ targets, availableTargets, onToggle, autoFocus, isLast, onSubmitAll }) => {
|
|
723
|
-
const { isFocused } =
|
|
724
|
-
const { focusNext, focusPrevious } =
|
|
725
|
-
const [cursor, setCursor] =
|
|
726
|
-
|
|
683
|
+
const { isFocused } = useFocus({ autoFocus });
|
|
684
|
+
const { focusNext, focusPrevious } = useFocusManager();
|
|
685
|
+
const [cursor, setCursor] = useState(0);
|
|
686
|
+
useInput((input, key) => {
|
|
727
687
|
if (!isFocused) return;
|
|
728
688
|
if (key.downArrow) {
|
|
729
689
|
if (cursor < availableTargets.length - 1) {
|
|
@@ -749,26 +709,26 @@ var TargetToggleRow = ({ targets, availableTargets, onToggle, autoFocus, isLast,
|
|
|
749
709
|
onSubmitAll();
|
|
750
710
|
}
|
|
751
711
|
});
|
|
752
|
-
return /* @__PURE__ */
|
|
753
|
-
/* @__PURE__ */
|
|
754
|
-
/* @__PURE__ */
|
|
712
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
713
|
+
/* @__PURE__ */ jsx(Text, { dimColor: !isFocused, bold: isFocused, children: "Targets".padEnd(14) }),
|
|
714
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingLeft: 2, children: [
|
|
755
715
|
availableTargets.map((t, i) => {
|
|
756
716
|
const selected = targets.includes(t);
|
|
757
717
|
const isCursor = isFocused && i === cursor;
|
|
758
|
-
return /* @__PURE__ */
|
|
759
|
-
/* @__PURE__ */
|
|
760
|
-
/* @__PURE__ */
|
|
761
|
-
/* @__PURE__ */
|
|
718
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
719
|
+
/* @__PURE__ */ jsx(Text, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
|
|
720
|
+
/* @__PURE__ */ jsx(Text, { color: selected ? "green" : "gray", children: selected ? "\u25C9" : "\u25CB" }),
|
|
721
|
+
/* @__PURE__ */ jsx(Text, { bold: isCursor, children: t })
|
|
762
722
|
] }, t);
|
|
763
723
|
}),
|
|
764
|
-
isFocused && /* @__PURE__ */
|
|
724
|
+
isFocused && /* @__PURE__ */ jsx(Text, { dimColor: true, children: " (space to toggle)" })
|
|
765
725
|
] })
|
|
766
726
|
] });
|
|
767
727
|
};
|
|
768
728
|
var EnabledToggleRow = ({ enabled, onToggle, autoFocus, isLast, onSubmitAll }) => {
|
|
769
|
-
const { isFocused } =
|
|
770
|
-
const { focusNext, focusPrevious } =
|
|
771
|
-
|
|
729
|
+
const { isFocused } = useFocus({ autoFocus });
|
|
730
|
+
const { focusNext, focusPrevious } = useFocusManager();
|
|
731
|
+
useInput((input, key) => {
|
|
772
732
|
if (!isFocused) return;
|
|
773
733
|
if (key.downArrow) {
|
|
774
734
|
if (!isLast) focusNext();
|
|
@@ -786,16 +746,16 @@ var EnabledToggleRow = ({ enabled, onToggle, autoFocus, isLast, onSubmitAll }) =
|
|
|
786
746
|
onSubmitAll();
|
|
787
747
|
}
|
|
788
748
|
});
|
|
789
|
-
return /* @__PURE__ */
|
|
790
|
-
/* @__PURE__ */
|
|
791
|
-
/* @__PURE__ */
|
|
792
|
-
isFocused && /* @__PURE__ */
|
|
749
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
750
|
+
/* @__PURE__ */ jsx(Text, { dimColor: !isFocused, bold: isFocused, children: "Enabled".padEnd(14) }),
|
|
751
|
+
/* @__PURE__ */ jsx(Text, { color: enabled ? "green" : "red", bold: isFocused, children: enabled ? "Yes" : "No" }),
|
|
752
|
+
isFocused && /* @__PURE__ */ jsx(Text, { dimColor: true, children: "(space/arrows to toggle)" })
|
|
793
753
|
] });
|
|
794
754
|
};
|
|
795
755
|
var ForceMajorToggleRow = ({ forceMajor, onToggle, autoFocus, isLast, onSubmitAll }) => {
|
|
796
|
-
const { isFocused } =
|
|
797
|
-
const { focusPrevious, focusNext } =
|
|
798
|
-
|
|
756
|
+
const { isFocused } = useFocus({ autoFocus });
|
|
757
|
+
const { focusPrevious, focusNext } = useFocusManager();
|
|
758
|
+
useInput((input, key) => {
|
|
799
759
|
if (!isFocused) return;
|
|
800
760
|
if (key.downArrow) {
|
|
801
761
|
if (!isLast) focusNext();
|
|
@@ -813,10 +773,10 @@ var ForceMajorToggleRow = ({ forceMajor, onToggle, autoFocus, isLast, onSubmitAl
|
|
|
813
773
|
onSubmitAll();
|
|
814
774
|
}
|
|
815
775
|
});
|
|
816
|
-
return /* @__PURE__ */
|
|
817
|
-
/* @__PURE__ */
|
|
818
|
-
/* @__PURE__ */
|
|
819
|
-
isFocused && /* @__PURE__ */
|
|
776
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
777
|
+
/* @__PURE__ */ jsx(Text, { dimColor: !isFocused, bold: isFocused, children: "Force major".padEnd(14) }),
|
|
778
|
+
/* @__PURE__ */ jsx(Text, { color: forceMajor ? "yellow" : "gray", bold: isFocused, children: forceMajor ? "Yes" : "No" }),
|
|
779
|
+
isFocused && /* @__PURE__ */ jsx(Text, { dimColor: true, children: "(space/arrows to toggle)" })
|
|
820
780
|
] });
|
|
821
781
|
};
|
|
822
782
|
var UpdateSettingsPrompt = ({
|
|
@@ -829,12 +789,12 @@ var UpdateSettingsPrompt = ({
|
|
|
829
789
|
onSubmit,
|
|
830
790
|
onBack
|
|
831
791
|
}) => {
|
|
832
|
-
const [nameValue, setNameValue] =
|
|
833
|
-
const [targetsValue, setTargetsValue] =
|
|
834
|
-
const [bundleUrlValue, setBundleUrlValue] =
|
|
835
|
-
const [allowedDomainsValue, setAllowedDomainsValue] =
|
|
836
|
-
const [enabledValue, setEnabledValue] =
|
|
837
|
-
const [forceMajorValue, setForceMajorValue] =
|
|
792
|
+
const [nameValue, setNameValue] = useState(initialName);
|
|
793
|
+
const [targetsValue, setTargetsValue] = useState(initialTargets);
|
|
794
|
+
const [bundleUrlValue, setBundleUrlValue] = useState(initialBundleUrl);
|
|
795
|
+
const [allowedDomainsValue, setAllowedDomainsValue] = useState(initialAllowedDomains.join(", "));
|
|
796
|
+
const [enabledValue, setEnabledValue] = useState(initialEnabled);
|
|
797
|
+
const [forceMajorValue, setForceMajorValue] = useState(false);
|
|
838
798
|
const handleToggleTarget = (target) => {
|
|
839
799
|
setTargetsValue((prev) => prev.includes(target) ? prev.filter((t) => t !== target) : [...prev, target]);
|
|
840
800
|
};
|
|
@@ -849,14 +809,14 @@ var UpdateSettingsPrompt = ({
|
|
|
849
809
|
forceMajor: forceMajorValue
|
|
850
810
|
});
|
|
851
811
|
};
|
|
852
|
-
return /* @__PURE__ */
|
|
812
|
+
return /* @__PURE__ */ jsx(
|
|
853
813
|
StepShell,
|
|
854
814
|
{
|
|
855
815
|
title: "Update Extension settings",
|
|
856
816
|
hint: "Tab/shift-tab to jump section, \u2191/\u2193 navigate. Enter to submit",
|
|
857
817
|
onBack,
|
|
858
|
-
children: /* @__PURE__ */
|
|
859
|
-
/* @__PURE__ */
|
|
818
|
+
children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
819
|
+
/* @__PURE__ */ jsx(
|
|
860
820
|
FieldRow2,
|
|
861
821
|
{
|
|
862
822
|
label: "Name",
|
|
@@ -868,7 +828,7 @@ var UpdateSettingsPrompt = ({
|
|
|
868
828
|
onSubmitAll: handleSubmitAll
|
|
869
829
|
}
|
|
870
830
|
),
|
|
871
|
-
/* @__PURE__ */
|
|
831
|
+
/* @__PURE__ */ jsx(
|
|
872
832
|
TargetToggleRow,
|
|
873
833
|
{
|
|
874
834
|
targets: targetsValue,
|
|
@@ -877,7 +837,7 @@ var UpdateSettingsPrompt = ({
|
|
|
877
837
|
onSubmitAll: handleSubmitAll
|
|
878
838
|
}
|
|
879
839
|
),
|
|
880
|
-
/* @__PURE__ */
|
|
840
|
+
/* @__PURE__ */ jsx(
|
|
881
841
|
FieldRow2,
|
|
882
842
|
{
|
|
883
843
|
label: "Bundle URL",
|
|
@@ -887,7 +847,7 @@ var UpdateSettingsPrompt = ({
|
|
|
887
847
|
onSubmitAll: handleSubmitAll
|
|
888
848
|
}
|
|
889
849
|
),
|
|
890
|
-
/* @__PURE__ */
|
|
850
|
+
/* @__PURE__ */ jsx(
|
|
891
851
|
FieldRow2,
|
|
892
852
|
{
|
|
893
853
|
label: "Allowed Domains",
|
|
@@ -897,7 +857,7 @@ var UpdateSettingsPrompt = ({
|
|
|
897
857
|
onSubmitAll: handleSubmitAll
|
|
898
858
|
}
|
|
899
859
|
),
|
|
900
|
-
/* @__PURE__ */
|
|
860
|
+
/* @__PURE__ */ jsx(
|
|
901
861
|
EnabledToggleRow,
|
|
902
862
|
{
|
|
903
863
|
enabled: enabledValue,
|
|
@@ -905,7 +865,7 @@ var UpdateSettingsPrompt = ({
|
|
|
905
865
|
onSubmitAll: handleSubmitAll
|
|
906
866
|
}
|
|
907
867
|
),
|
|
908
|
-
/* @__PURE__ */
|
|
868
|
+
/* @__PURE__ */ jsx(
|
|
909
869
|
ForceMajorToggleRow,
|
|
910
870
|
{
|
|
911
871
|
forceMajor: forceMajorValue,
|
|
@@ -918,35 +878,25 @@ var UpdateSettingsPrompt = ({
|
|
|
918
878
|
}
|
|
919
879
|
);
|
|
920
880
|
};
|
|
921
|
-
|
|
922
|
-
// src/components/ScaffoldProgress.tsx
|
|
923
|
-
import { Box as Box10, Text as Text10 } from "ink";
|
|
924
|
-
import Spinner from "ink-spinner";
|
|
925
|
-
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
926
881
|
var stepIcon = (status) => {
|
|
927
882
|
switch (status) {
|
|
928
883
|
case "running":
|
|
929
|
-
return /* @__PURE__ */
|
|
884
|
+
return /* @__PURE__ */ jsx(Spinner5, { type: "dots" });
|
|
930
885
|
case "done":
|
|
931
|
-
return /* @__PURE__ */
|
|
886
|
+
return /* @__PURE__ */ jsx(Text, { color: "green", children: "\u2714" });
|
|
932
887
|
case "error":
|
|
933
|
-
return /* @__PURE__ */
|
|
888
|
+
return /* @__PURE__ */ jsx(Text, { color: "red", children: "\u2716" });
|
|
934
889
|
default:
|
|
935
|
-
return /* @__PURE__ */
|
|
890
|
+
return /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u25CB" });
|
|
936
891
|
}
|
|
937
892
|
};
|
|
938
|
-
var ScaffoldProgress = ({ steps }) => /* @__PURE__ */
|
|
939
|
-
/* @__PURE__ */
|
|
940
|
-
/* @__PURE__ */
|
|
893
|
+
var ScaffoldProgress = ({ steps }) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
894
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Scaffolding your Extension\u2026" }),
|
|
895
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", children: steps.map((step) => /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
941
896
|
stepIcon(step.status),
|
|
942
|
-
/* @__PURE__ */
|
|
897
|
+
/* @__PURE__ */ jsx(Text, { dimColor: step.status === "pending", color: step.status === "running" ? "cyan" : void 0, children: step.label })
|
|
943
898
|
] }, step.label)) })
|
|
944
899
|
] });
|
|
945
|
-
|
|
946
|
-
// src/components/TargetSelect.tsx
|
|
947
|
-
import { Box as Box11, Text as Text11, useInput as useInput6 } from "ink";
|
|
948
|
-
import { useState as useState6 } from "react";
|
|
949
|
-
import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
950
900
|
var TARGET_DESCRIPTIONS = {
|
|
951
901
|
"slot.header": "Renders content in the panel header area",
|
|
952
902
|
"slot.content": "Renders the main panel body (includes store + navigation state)",
|
|
@@ -954,12 +904,12 @@ var TARGET_DESCRIPTIONS = {
|
|
|
954
904
|
"slot.footer-links": "Renders a link row in the global footer"
|
|
955
905
|
};
|
|
956
906
|
var TargetSelect = ({ availableTargets, preSelected, onSubmit, onBack }) => {
|
|
957
|
-
const [cursor, setCursor] =
|
|
958
|
-
const [selected, setSelected] =
|
|
907
|
+
const [cursor, setCursor] = useState(0);
|
|
908
|
+
const [selected, setSelected] = useState(
|
|
959
909
|
new Set(preSelected ?? (availableTargets.includes("slot.content") ? ["slot.content"] : []))
|
|
960
910
|
);
|
|
961
|
-
const [error, setError] =
|
|
962
|
-
|
|
911
|
+
const [error, setError] = useState();
|
|
912
|
+
useInput((input, key) => {
|
|
963
913
|
if (key.upArrow) {
|
|
964
914
|
setCursor((c) => Math.max(0, c - 1));
|
|
965
915
|
return;
|
|
@@ -990,39 +940,34 @@ var TargetSelect = ({ availableTargets, preSelected, onSubmit, onBack }) => {
|
|
|
990
940
|
onSubmit([...selected]);
|
|
991
941
|
}
|
|
992
942
|
});
|
|
993
|
-
return /* @__PURE__ */
|
|
943
|
+
return /* @__PURE__ */ jsxs(
|
|
994
944
|
StepShell,
|
|
995
945
|
{
|
|
996
946
|
title: "Select Surface targets/slots",
|
|
997
947
|
hint: "Space to toggle, Enter to confirm",
|
|
998
948
|
onBack,
|
|
999
949
|
children: [
|
|
1000
|
-
/* @__PURE__ */
|
|
950
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", gap: 1, children: availableTargets.map((target, i) => {
|
|
1001
951
|
const isSelected = selected.has(target);
|
|
1002
952
|
const isCursor = i === cursor;
|
|
1003
|
-
return /* @__PURE__ */
|
|
1004
|
-
/* @__PURE__ */
|
|
1005
|
-
/* @__PURE__ */
|
|
1006
|
-
/* @__PURE__ */
|
|
1007
|
-
/* @__PURE__ */
|
|
1008
|
-
/* @__PURE__ */
|
|
953
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
954
|
+
/* @__PURE__ */ jsx(Text, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
|
|
955
|
+
/* @__PURE__ */ jsx(Text, { color: isSelected ? "green" : void 0, children: isSelected ? "\u25C9" : "\u25CB" }),
|
|
956
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
957
|
+
/* @__PURE__ */ jsx(Text, { bold: isSelected, children: target }),
|
|
958
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: TARGET_DESCRIPTIONS[target] ?? target })
|
|
1009
959
|
] })
|
|
1010
960
|
] }, target);
|
|
1011
961
|
}) }),
|
|
1012
|
-
error && /* @__PURE__ */
|
|
962
|
+
error && /* @__PURE__ */ jsx(Text, { color: "red", children: error })
|
|
1013
963
|
]
|
|
1014
964
|
}
|
|
1015
965
|
);
|
|
1016
966
|
};
|
|
1017
|
-
|
|
1018
|
-
// src/components/TemplateSelect.tsx
|
|
1019
|
-
import { Box as Box12, Text as Text12, useInput as useInput7 } from "ink";
|
|
1020
|
-
import { useState as useState7 } from "react";
|
|
1021
|
-
import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1022
967
|
var FLAVORS = ["minimal", "starter", "kitchen-sink"];
|
|
1023
968
|
var TemplateSelect = ({ onSubmit, onBack }) => {
|
|
1024
|
-
const [cursor, setCursor] =
|
|
1025
|
-
|
|
969
|
+
const [cursor, setCursor] = useState(1);
|
|
970
|
+
useInput((_input, key) => {
|
|
1026
971
|
if (key.upArrow) {
|
|
1027
972
|
setCursor((c) => Math.max(0, c - 1));
|
|
1028
973
|
return;
|
|
@@ -1035,21 +980,21 @@ var TemplateSelect = ({ onSubmit, onBack }) => {
|
|
|
1035
980
|
onSubmit(FLAVORS[cursor]);
|
|
1036
981
|
}
|
|
1037
982
|
});
|
|
1038
|
-
return /* @__PURE__ */
|
|
983
|
+
return /* @__PURE__ */ jsx(
|
|
1039
984
|
StepShell,
|
|
1040
985
|
{
|
|
1041
986
|
title: "Choose a template",
|
|
1042
987
|
hint: "\u2191\u2193 to navigate, Enter to select",
|
|
1043
988
|
onBack,
|
|
1044
|
-
children: /* @__PURE__ */
|
|
989
|
+
children: /* @__PURE__ */ jsx(Box, { flexDirection: "column", gap: 1, children: FLAVORS.map((flavor, i) => {
|
|
1045
990
|
const meta = TEMPLATE_FLAVOR_META[flavor];
|
|
1046
991
|
const isCursor = i === cursor;
|
|
1047
|
-
return /* @__PURE__ */
|
|
1048
|
-
/* @__PURE__ */
|
|
1049
|
-
/* @__PURE__ */
|
|
1050
|
-
/* @__PURE__ */
|
|
1051
|
-
/* @__PURE__ */
|
|
1052
|
-
/* @__PURE__ */
|
|
992
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
993
|
+
/* @__PURE__ */ jsx(Text, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
|
|
994
|
+
/* @__PURE__ */ jsx(Text, { color: isCursor ? "green" : void 0, children: isCursor ? "\u25C9" : "\u25CB" }),
|
|
995
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
996
|
+
/* @__PURE__ */ jsx(Text, { bold: isCursor, children: meta.label }),
|
|
997
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: meta.description })
|
|
1053
998
|
] })
|
|
1054
999
|
] }, flavor);
|
|
1055
1000
|
}) })
|
|
@@ -1057,11 +1002,6 @@ var TemplateSelect = ({ onSubmit, onBack }) => {
|
|
|
1057
1002
|
);
|
|
1058
1003
|
};
|
|
1059
1004
|
|
|
1060
|
-
// src/components/AppSelect.tsx
|
|
1061
|
-
import { Box as Box13, Text as Text13, useInput as useInput8 } from "ink";
|
|
1062
|
-
import Spinner2 from "ink-spinner";
|
|
1063
|
-
import { useEffect as useEffect2, useState as useState8 } from "react";
|
|
1064
|
-
|
|
1065
1005
|
// src/lib/api.ts
|
|
1066
1006
|
var DEFAULT_ADMIN_API_URL = "https://api-use1.stackablelabs.io/admin";
|
|
1067
1007
|
var DEFAULT_PUBLIC_API_URL = "https://api.stackablelabs.io/app-extension/v1";
|
|
@@ -1193,18 +1133,15 @@ var updateExtension = async (token, appId, extensionId, payload) => {
|
|
|
1193
1133
|
throw new Error(`Failed to update extension: ${res.status} ${body}`);
|
|
1194
1134
|
}
|
|
1195
1135
|
};
|
|
1196
|
-
|
|
1197
|
-
// src/components/AppSelect.tsx
|
|
1198
|
-
import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1199
1136
|
var AppSelect = ({ token, userId, orgId, onSubmit }) => {
|
|
1200
|
-
const [apps, setApps] =
|
|
1201
|
-
const [loading, setLoading] =
|
|
1202
|
-
const [error, setError] =
|
|
1203
|
-
const [cursor, setCursor] =
|
|
1204
|
-
|
|
1137
|
+
const [apps, setApps] = useState([]);
|
|
1138
|
+
const [loading, setLoading] = useState(true);
|
|
1139
|
+
const [error, setError] = useState();
|
|
1140
|
+
const [cursor, setCursor] = useState(0);
|
|
1141
|
+
useEffect(() => {
|
|
1205
1142
|
fetchApps(token).then(setApps).catch((err) => setError(err instanceof Error ? err.message : String(err))).finally(() => setLoading(false));
|
|
1206
1143
|
}, [token]);
|
|
1207
|
-
|
|
1144
|
+
useInput((_, key) => {
|
|
1208
1145
|
if (loading || error || apps.length === 0) return;
|
|
1209
1146
|
if (key.upArrow) {
|
|
1210
1147
|
setCursor((c) => Math.max(0, c - 1));
|
|
@@ -1216,26 +1153,26 @@ var AppSelect = ({ token, userId, orgId, onSubmit }) => {
|
|
|
1216
1153
|
});
|
|
1217
1154
|
const renderContent = () => {
|
|
1218
1155
|
if (loading) {
|
|
1219
|
-
return /* @__PURE__ */
|
|
1220
|
-
/* @__PURE__ */
|
|
1221
|
-
/* @__PURE__ */
|
|
1156
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
1157
|
+
/* @__PURE__ */ jsx(Spinner5, { type: "dots" }),
|
|
1158
|
+
/* @__PURE__ */ jsx(Text, { children: "Loading available Apps\u2026" })
|
|
1222
1159
|
] });
|
|
1223
1160
|
}
|
|
1224
1161
|
if (error) {
|
|
1225
|
-
return /* @__PURE__ */
|
|
1226
|
-
/* @__PURE__ */
|
|
1227
|
-
/* @__PURE__ */
|
|
1162
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
1163
|
+
/* @__PURE__ */ jsx(Text, { color: "red", bold: true, children: "Failed to load Apps" }),
|
|
1164
|
+
/* @__PURE__ */ jsx(Text, { color: "red", children: error })
|
|
1228
1165
|
] });
|
|
1229
1166
|
}
|
|
1230
1167
|
if (apps.length === 0) {
|
|
1231
|
-
return /* @__PURE__ */
|
|
1168
|
+
return /* @__PURE__ */ jsx(Text, { color: "yellow", children: "No Apps available. Contact your administrator." });
|
|
1232
1169
|
}
|
|
1233
|
-
return /* @__PURE__ */
|
|
1170
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: apps.map((app, i) => {
|
|
1234
1171
|
const isCursor = i === cursor;
|
|
1235
|
-
return /* @__PURE__ */
|
|
1236
|
-
/* @__PURE__ */
|
|
1237
|
-
/* @__PURE__ */
|
|
1238
|
-
/* @__PURE__ */
|
|
1172
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
1173
|
+
/* @__PURE__ */ jsx(Text, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
|
|
1174
|
+
/* @__PURE__ */ jsx(Text, { bold: isCursor, children: app.name }),
|
|
1175
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1239
1176
|
"(",
|
|
1240
1177
|
app.id,
|
|
1241
1178
|
")"
|
|
@@ -1243,26 +1180,20 @@ var AppSelect = ({ token, userId, orgId, onSubmit }) => {
|
|
|
1243
1180
|
] }, app.id);
|
|
1244
1181
|
}) });
|
|
1245
1182
|
};
|
|
1246
|
-
return /* @__PURE__ */
|
|
1247
|
-
/* @__PURE__ */
|
|
1248
|
-
/* @__PURE__ */
|
|
1183
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
1184
|
+
/* @__PURE__ */ jsx(Banner, { userId, orgId }),
|
|
1185
|
+
/* @__PURE__ */ jsx(StepShell, { title: "Select the App you are building an Extension for:", children: renderContent() })
|
|
1249
1186
|
] });
|
|
1250
1187
|
};
|
|
1251
|
-
|
|
1252
|
-
// src/components/ExtensionSelect.tsx
|
|
1253
|
-
import { Box as Box14, Text as Text14, useInput as useInput9 } from "ink";
|
|
1254
|
-
import Spinner3 from "ink-spinner";
|
|
1255
|
-
import { useEffect as useEffect3, useState as useState9 } from "react";
|
|
1256
|
-
import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1257
1188
|
var ExtensionSelect = ({ appId, token, command, onSubmit, onBack }) => {
|
|
1258
|
-
const [extensions, setExtensions] =
|
|
1259
|
-
const [loading, setLoading] =
|
|
1260
|
-
const [error, setError] =
|
|
1261
|
-
const [cursor, setCursor] =
|
|
1262
|
-
|
|
1189
|
+
const [extensions, setExtensions] = useState([]);
|
|
1190
|
+
const [loading, setLoading] = useState(true);
|
|
1191
|
+
const [error, setError] = useState();
|
|
1192
|
+
const [cursor, setCursor] = useState(0);
|
|
1193
|
+
useEffect(() => {
|
|
1263
1194
|
fetchExtensions(token, appId).then((byId) => setExtensions(Object.values(byId))).catch((err) => setError(err instanceof Error ? err.message : String(err))).finally(() => setLoading(false));
|
|
1264
1195
|
}, [appId, token]);
|
|
1265
|
-
|
|
1196
|
+
useInput((_, key) => {
|
|
1266
1197
|
if (key.upArrow) {
|
|
1267
1198
|
if (!loading && !error && extensions.length > 0) {
|
|
1268
1199
|
setCursor((c) => Math.max(0, c - 1));
|
|
@@ -1283,30 +1214,30 @@ var ExtensionSelect = ({ appId, token, command, onSubmit, onBack }) => {
|
|
|
1283
1214
|
});
|
|
1284
1215
|
const renderContent = () => {
|
|
1285
1216
|
if (loading) {
|
|
1286
|
-
return /* @__PURE__ */
|
|
1287
|
-
/* @__PURE__ */
|
|
1288
|
-
/* @__PURE__ */
|
|
1217
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
1218
|
+
/* @__PURE__ */ jsx(Spinner5, { type: "dots" }),
|
|
1219
|
+
/* @__PURE__ */ jsx(Text, { children: "Loading Extensions\u2026" })
|
|
1289
1220
|
] });
|
|
1290
1221
|
}
|
|
1291
1222
|
if (error) {
|
|
1292
|
-
return /* @__PURE__ */
|
|
1293
|
-
/* @__PURE__ */
|
|
1294
|
-
/* @__PURE__ */
|
|
1223
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
1224
|
+
/* @__PURE__ */ jsx(Text, { color: "red", bold: true, children: "Failed to load Extensions" }),
|
|
1225
|
+
/* @__PURE__ */ jsx(Text, { color: "red", children: error })
|
|
1295
1226
|
] });
|
|
1296
1227
|
}
|
|
1297
1228
|
if (extensions.length === 0) {
|
|
1298
|
-
return /* @__PURE__ */
|
|
1229
|
+
return /* @__PURE__ */ jsx(Text, { color: "yellow", children: "No Extensions found for this App." });
|
|
1299
1230
|
}
|
|
1300
|
-
return /* @__PURE__ */
|
|
1231
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: extensions.map((ext, i) => {
|
|
1301
1232
|
const isCursor = i === cursor;
|
|
1302
|
-
return /* @__PURE__ */
|
|
1303
|
-
/* @__PURE__ */
|
|
1304
|
-
/* @__PURE__ */
|
|
1305
|
-
/* @__PURE__ */
|
|
1233
|
+
return /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
1234
|
+
/* @__PURE__ */ jsx(Text, { color: isCursor ? "cyan" : void 0, children: isCursor ? "\u276F" : " " }),
|
|
1235
|
+
/* @__PURE__ */ jsx(Text, { bold: isCursor, children: ext.manifest.name }),
|
|
1236
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1306
1237
|
"v",
|
|
1307
1238
|
ext.manifest.version
|
|
1308
1239
|
] }),
|
|
1309
|
-
/* @__PURE__ */
|
|
1240
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
1310
1241
|
"(",
|
|
1311
1242
|
ext.id,
|
|
1312
1243
|
")"
|
|
@@ -1314,7 +1245,7 @@ var ExtensionSelect = ({ appId, token, command, onSubmit, onBack }) => {
|
|
|
1314
1245
|
] }, ext.id);
|
|
1315
1246
|
}) });
|
|
1316
1247
|
};
|
|
1317
|
-
return /* @__PURE__ */
|
|
1248
|
+
return /* @__PURE__ */ jsx(
|
|
1318
1249
|
StepShell,
|
|
1319
1250
|
{
|
|
1320
1251
|
title: command === "update" /* UPDATE */ ? "Select an Extension to update:" : "Select an existing Extension to scaffold:",
|
|
@@ -1323,9 +1254,6 @@ var ExtensionSelect = ({ appId, token, command, onSubmit, onBack }) => {
|
|
|
1323
1254
|
}
|
|
1324
1255
|
);
|
|
1325
1256
|
};
|
|
1326
|
-
|
|
1327
|
-
// src/hooks/useWizardSteps.ts
|
|
1328
|
-
import { useCallback, useMemo, useState as useState10 } from "react";
|
|
1329
1257
|
var STEPS = {
|
|
1330
1258
|
["create" /* CREATE */]: ["app", "name", "template", "targets", "settings", "confirm"],
|
|
1331
1259
|
["scaffold" /* SCAFFOLD */]: ["app", "extensionSelect", "template", "confirmTargets", "settings", "confirm"],
|
|
@@ -1364,7 +1292,7 @@ var computeActiveSteps = (conditions) => {
|
|
|
1364
1292
|
return base.filter((s) => !skipped.has(s));
|
|
1365
1293
|
};
|
|
1366
1294
|
var useWizardSteps = (opts) => {
|
|
1367
|
-
const [step, setStep] =
|
|
1295
|
+
const [step, setStep] = useState("app");
|
|
1368
1296
|
const activeSteps = useMemo(
|
|
1369
1297
|
() => computeActiveSteps(opts),
|
|
1370
1298
|
[
|
|
@@ -1407,11 +1335,6 @@ var useWizardSteps = (opts) => {
|
|
|
1407
1335
|
}, []);
|
|
1408
1336
|
return { step, activeSteps, goForward, goBack, goTo };
|
|
1409
1337
|
};
|
|
1410
|
-
|
|
1411
|
-
// src/lib/postScaffold.ts
|
|
1412
|
-
import { execFile } from "child_process";
|
|
1413
|
-
import { promisify } from "util";
|
|
1414
|
-
import { installDependencies } from "nypm";
|
|
1415
1338
|
var execFileAsync = promisify(execFile);
|
|
1416
1339
|
var gitInit = async (dir) => {
|
|
1417
1340
|
try {
|
|
@@ -1425,19 +1348,10 @@ var postScaffold = async (options) => {
|
|
|
1425
1348
|
if (!options.skipGit) {
|
|
1426
1349
|
await gitInit(options.outputDir);
|
|
1427
1350
|
}
|
|
1428
|
-
|
|
1351
|
+
{
|
|
1429
1352
|
await installDependencies({ cwd: options.outputDir, silent: true });
|
|
1430
1353
|
}
|
|
1431
1354
|
};
|
|
1432
|
-
|
|
1433
|
-
// src/lib/scaffold.ts
|
|
1434
|
-
import { readFile as readFile2, readdir, rm, writeFile as writeFile2 } from "fs/promises";
|
|
1435
|
-
import { join as join2 } from "path";
|
|
1436
|
-
import { downloadTemplate } from "giget";
|
|
1437
|
-
|
|
1438
|
-
// src/lib/devContext.ts
|
|
1439
|
-
import { readFile, writeFile } from "fs/promises";
|
|
1440
|
-
import { join } from "path";
|
|
1441
1355
|
var parseEnvFile = (content) => {
|
|
1442
1356
|
const lines = content.split("\n");
|
|
1443
1357
|
const env = {};
|
|
@@ -1541,7 +1455,7 @@ var deriveScaffoldPermissions = (targets) => {
|
|
|
1541
1455
|
};
|
|
1542
1456
|
var upsertOrRemove = async (filePath, shouldExist, content) => {
|
|
1543
1457
|
if (shouldExist) {
|
|
1544
|
-
await
|
|
1458
|
+
await writeFile(filePath, content);
|
|
1545
1459
|
return;
|
|
1546
1460
|
}
|
|
1547
1461
|
await rm(filePath, { force: true });
|
|
@@ -1553,7 +1467,7 @@ var walkFiles = async (rootDir) => {
|
|
|
1553
1467
|
if (entry.name === ".git" || entry.name === "node_modules" || entry.name === "dist") {
|
|
1554
1468
|
continue;
|
|
1555
1469
|
}
|
|
1556
|
-
const fullPath =
|
|
1470
|
+
const fullPath = join(rootDir, entry.name);
|
|
1557
1471
|
if (entry.isDirectory()) {
|
|
1558
1472
|
files.push(...await walkFiles(fullPath));
|
|
1559
1473
|
continue;
|
|
@@ -1568,7 +1482,7 @@ var replacePlaceholders = async (rootDir, replacements) => {
|
|
|
1568
1482
|
if (!isTextFile(filePath)) {
|
|
1569
1483
|
continue;
|
|
1570
1484
|
}
|
|
1571
|
-
let content = await
|
|
1485
|
+
let content = await readFile(filePath, "utf8");
|
|
1572
1486
|
let changed = false;
|
|
1573
1487
|
for (const [needle, value] of Object.entries(replacements)) {
|
|
1574
1488
|
if (content.includes(needle)) {
|
|
@@ -1577,18 +1491,18 @@ var replacePlaceholders = async (rootDir, replacements) => {
|
|
|
1577
1491
|
}
|
|
1578
1492
|
}
|
|
1579
1493
|
if (changed) {
|
|
1580
|
-
await
|
|
1494
|
+
await writeFile(filePath, content);
|
|
1581
1495
|
}
|
|
1582
1496
|
}
|
|
1583
1497
|
};
|
|
1584
1498
|
var generateManifest = async (rootDir, extensionName, targets, permissions) => {
|
|
1585
|
-
const manifestPath =
|
|
1586
|
-
const raw = await
|
|
1499
|
+
const manifestPath = join(rootDir, "packages/extension/public/manifest.json");
|
|
1500
|
+
const raw = await readFile(manifestPath, "utf8");
|
|
1587
1501
|
const manifest = JSON.parse(raw);
|
|
1588
1502
|
manifest.name = extensionName;
|
|
1589
1503
|
manifest.targets = targets;
|
|
1590
1504
|
manifest.permissions = permissions;
|
|
1591
|
-
await
|
|
1505
|
+
await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}
|
|
1592
1506
|
`);
|
|
1593
1507
|
};
|
|
1594
1508
|
var buildFooterSurface = (targets) => {
|
|
@@ -1615,12 +1529,12 @@ ${blocks.join("\n")}
|
|
|
1615
1529
|
`;
|
|
1616
1530
|
};
|
|
1617
1531
|
var generateSurfaceFiles = async (rootDir, targets) => {
|
|
1618
|
-
const surfaceDir =
|
|
1532
|
+
const surfaceDir = join(rootDir, "packages/extension/src/surfaces");
|
|
1619
1533
|
const wantsHeader = targets.includes("slot.header");
|
|
1620
1534
|
const wantsContent = targets.includes("slot.content");
|
|
1621
1535
|
const wantsFooter = targets.includes("slot.footer") || targets.includes("slot.footer-links");
|
|
1622
1536
|
await upsertOrRemove(
|
|
1623
|
-
|
|
1537
|
+
join(surfaceDir, "Header.tsx"),
|
|
1624
1538
|
wantsHeader,
|
|
1625
1539
|
`import { ui, Surface } from '@stackable-labs/sdk-extension-react'
|
|
1626
1540
|
|
|
@@ -1634,7 +1548,7 @@ export function Header() {
|
|
|
1634
1548
|
`
|
|
1635
1549
|
);
|
|
1636
1550
|
await upsertOrRemove(
|
|
1637
|
-
|
|
1551
|
+
join(surfaceDir, "Content.tsx"),
|
|
1638
1552
|
wantsContent,
|
|
1639
1553
|
`import { ui, useStore, useContextData, Surface } from '@stackable-labs/sdk-extension-react'
|
|
1640
1554
|
import { appStore } from '../store'
|
|
@@ -1667,14 +1581,14 @@ export function Content() {
|
|
|
1667
1581
|
`
|
|
1668
1582
|
);
|
|
1669
1583
|
await upsertOrRemove(
|
|
1670
|
-
|
|
1584
|
+
join(rootDir, "packages/extension/src/store.ts"),
|
|
1671
1585
|
wantsContent,
|
|
1672
1586
|
"import { createStore } from '@stackable-labs/sdk-extension-react'\n\nexport type ViewState = { type: 'menu' }\n\nexport interface AppState {\n viewState: ViewState\n}\n\nexport const appStore = createStore<AppState>({\n viewState: { type: 'menu' },\n})\n"
|
|
1673
1587
|
);
|
|
1674
|
-
await upsertOrRemove(
|
|
1588
|
+
await upsertOrRemove(join(surfaceDir, "Footer.tsx"), wantsFooter, buildFooterSurface(targets));
|
|
1675
1589
|
};
|
|
1676
1590
|
var rewriteExtensionIndex = async (rootDir, extensionId, targets) => {
|
|
1677
|
-
const indexPath =
|
|
1591
|
+
const indexPath = join(rootDir, "packages/extension/src/index.tsx");
|
|
1678
1592
|
const imports = ["import { createExtension } from '@stackable-labs/sdk-extension-react'"];
|
|
1679
1593
|
const components = [];
|
|
1680
1594
|
if (targets.includes("slot.header")) {
|
|
@@ -1700,10 +1614,10 @@ ${components.join("\n")}
|
|
|
1700
1614
|
{ extensionId: '${toKebabCase(extensionId)}' },
|
|
1701
1615
|
)
|
|
1702
1616
|
`;
|
|
1703
|
-
await
|
|
1617
|
+
await writeFile(indexPath, content);
|
|
1704
1618
|
};
|
|
1705
1619
|
var rewritePreviewApp = async (rootDir, targets, permissions) => {
|
|
1706
|
-
const appPath =
|
|
1620
|
+
const appPath = join(rootDir, "packages/preview/src/App.tsx");
|
|
1707
1621
|
const includeDataQuery = permissions.includes("data:query");
|
|
1708
1622
|
const includeToast = permissions.includes("actions:toast");
|
|
1709
1623
|
const includeInvoke = permissions.includes("actions:invoke");
|
|
@@ -1782,17 +1696,17 @@ export default function App() {
|
|
|
1782
1696
|
)
|
|
1783
1697
|
}
|
|
1784
1698
|
`;
|
|
1785
|
-
await
|
|
1699
|
+
await writeFile(appPath, appContent);
|
|
1786
1700
|
};
|
|
1787
1701
|
var patchViteAllowedHosts = async (rootDir) => {
|
|
1788
1702
|
const configs = [
|
|
1789
|
-
|
|
1790
|
-
|
|
1703
|
+
join(rootDir, "packages/extension/vite.config.ts"),
|
|
1704
|
+
join(rootDir, "packages/preview/vite.config.ts")
|
|
1791
1705
|
];
|
|
1792
1706
|
for (const configPath of configs) {
|
|
1793
1707
|
let content;
|
|
1794
1708
|
try {
|
|
1795
|
-
content = await
|
|
1709
|
+
content = await readFile(configPath, "utf8");
|
|
1796
1710
|
} catch {
|
|
1797
1711
|
continue;
|
|
1798
1712
|
}
|
|
@@ -1802,38 +1716,38 @@ var patchViteAllowedHosts = async (rootDir) => {
|
|
|
1802
1716
|
"server: {\n allowedHosts: true,"
|
|
1803
1717
|
);
|
|
1804
1718
|
if (patched !== content) {
|
|
1805
|
-
await
|
|
1719
|
+
await writeFile(configPath, patched);
|
|
1806
1720
|
}
|
|
1807
1721
|
}
|
|
1808
1722
|
};
|
|
1809
1723
|
var rewriteTurboJson = async (rootDir) => {
|
|
1810
|
-
const turboPath =
|
|
1811
|
-
const raw = await
|
|
1724
|
+
const turboPath = join(rootDir, "turbo.json");
|
|
1725
|
+
const raw = await readFile(turboPath, "utf8");
|
|
1812
1726
|
const turbo = JSON.parse(raw);
|
|
1813
1727
|
delete turbo["extends"];
|
|
1814
1728
|
turbo["globalEnv"] = ["VITE_EXTENSION_PORT", "VITE_PREVIEW_PORT", "VITE_EXTENSION_BUNDLE_URL"];
|
|
1815
|
-
await
|
|
1729
|
+
await writeFile(turboPath, `${JSON.stringify(turbo, null, 2)}
|
|
1816
1730
|
`);
|
|
1817
1731
|
};
|
|
1818
1732
|
var writeEnvFile2 = async (dir, extensionPort, previewPort) => {
|
|
1819
|
-
const envPath =
|
|
1733
|
+
const envPath = join(dir, ".env");
|
|
1820
1734
|
const content = `VITE_EXTENSION_PORT=${extensionPort}
|
|
1821
1735
|
VITE_PREVIEW_PORT=${previewPort}
|
|
1822
1736
|
`;
|
|
1823
|
-
await
|
|
1737
|
+
await writeFile(envPath, content);
|
|
1824
1738
|
};
|
|
1825
1739
|
var updateGitignore = async (dir) => {
|
|
1826
|
-
const gitignorePath =
|
|
1740
|
+
const gitignorePath = join(dir, ".gitignore");
|
|
1827
1741
|
let gitignore = "";
|
|
1828
1742
|
try {
|
|
1829
|
-
gitignore = await
|
|
1743
|
+
gitignore = await readFile(gitignorePath, "utf8");
|
|
1830
1744
|
} catch {
|
|
1831
1745
|
}
|
|
1832
1746
|
if (!gitignore.includes(".env.stackable")) {
|
|
1833
1747
|
const newGitignore = gitignore ? `${gitignore}
|
|
1834
1748
|
.env.stackable
|
|
1835
1749
|
` : ".env.stackable\n";
|
|
1836
|
-
await
|
|
1750
|
+
await writeFile(gitignorePath, newGitignore);
|
|
1837
1751
|
}
|
|
1838
1752
|
};
|
|
1839
1753
|
var scaffold = async (options) => {
|
|
@@ -1863,32 +1777,25 @@ var scaffold = async (options) => {
|
|
|
1863
1777
|
await writeEnvFile2(dir, options.extensionPort, options.previewPort);
|
|
1864
1778
|
await updateGitignore(dir);
|
|
1865
1779
|
await writeDevContext(dir, {
|
|
1866
|
-
projectRoot: dir,
|
|
1867
|
-
orgId: null,
|
|
1868
1780
|
appId: options.appId,
|
|
1869
1781
|
extensionId: toKebabCase(options.extensionId || options.name),
|
|
1870
1782
|
appName: options.appName || null,
|
|
1871
1783
|
extensionName: options.name,
|
|
1872
1784
|
extensionPort: options.extensionPort,
|
|
1873
|
-
previewPort: options.previewPort
|
|
1874
|
-
manifest: null
|
|
1875
|
-
});
|
|
1785
|
+
previewPort: options.previewPort});
|
|
1876
1786
|
if (options.projectFiles) {
|
|
1877
|
-
const extensionSrcDir =
|
|
1787
|
+
const extensionSrcDir = join(dir, "packages/extension/src");
|
|
1878
1788
|
for (const [filename, content] of Object.entries(options.projectFiles)) {
|
|
1879
|
-
await
|
|
1789
|
+
await writeFile(join(extensionSrcDir, filename), content);
|
|
1880
1790
|
}
|
|
1881
1791
|
}
|
|
1882
1792
|
if (options.projectManifest) {
|
|
1883
|
-
const manifestPath =
|
|
1884
|
-
await
|
|
1793
|
+
const manifestPath = join(dir, "packages/extension/public/manifest.json");
|
|
1794
|
+
await writeFile(manifestPath, `${JSON.stringify(options.projectManifest, null, 2)}
|
|
1885
1795
|
`);
|
|
1886
1796
|
}
|
|
1887
1797
|
return options;
|
|
1888
1798
|
};
|
|
1889
|
-
|
|
1890
|
-
// src/App.tsx
|
|
1891
|
-
import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1892
1799
|
var PROGRESS_STEPS = {
|
|
1893
1800
|
["create" /* CREATE */]: [
|
|
1894
1801
|
{ label: "Registering Extension", status: "pending" },
|
|
@@ -1926,39 +1833,39 @@ var deriveRegistryPermissions = (targets) => {
|
|
|
1926
1833
|
};
|
|
1927
1834
|
var App = ({ command, token, userId, orgId, initialName, initialExtensionId, options }) => {
|
|
1928
1835
|
const { exit } = useApp();
|
|
1929
|
-
const [name, setName] =
|
|
1930
|
-
const [extensionId, setExtensionId] =
|
|
1931
|
-
const [extensionVersion, setExtensionVersion] =
|
|
1932
|
-
const [bundleUrl, setBundleUrl] =
|
|
1933
|
-
const [enabled, setEnabled] =
|
|
1836
|
+
const [name, setName] = useState(initialName ?? options?.name ?? "");
|
|
1837
|
+
const [extensionId, setExtensionId] = useState(initialExtensionId ?? "");
|
|
1838
|
+
const [extensionVersion, setExtensionVersion] = useState("");
|
|
1839
|
+
const [bundleUrl, setBundleUrl] = useState(options?.bundleUrl ?? "");
|
|
1840
|
+
const [enabled, setEnabled] = useState(
|
|
1934
1841
|
options?.enabled !== void 0 ? options.enabled !== "false" : true
|
|
1935
1842
|
);
|
|
1936
|
-
const [versionOverride, setVersionOverride] =
|
|
1937
|
-
const [forceMajor, setForceMajor] =
|
|
1938
|
-
const [initialExtension, setInitialExtension] =
|
|
1939
|
-
const [templateFlavor, setTemplateFlavor] =
|
|
1843
|
+
const [versionOverride, setVersionOverride] = useState(void 0);
|
|
1844
|
+
const [forceMajor, setForceMajor] = useState(false);
|
|
1845
|
+
const [initialExtension, setInitialExtension] = useState(null);
|
|
1846
|
+
const [templateFlavor, setTemplateFlavor] = useState(
|
|
1940
1847
|
options?.template ?? "starter"
|
|
1941
1848
|
);
|
|
1942
|
-
const [targets, setTargets] =
|
|
1849
|
+
const [targets, setTargets] = useState(
|
|
1943
1850
|
options?.targets ? options.targets.split(",").map((t) => t.trim()) : []
|
|
1944
1851
|
);
|
|
1945
|
-
const [selectedApp, setSelectedApp] =
|
|
1946
|
-
const [extensionPort, setExtensionPort] =
|
|
1852
|
+
const [selectedApp, setSelectedApp] = useState(null);
|
|
1853
|
+
const [extensionPort, setExtensionPort] = useState(
|
|
1947
1854
|
options?.extensionPort ? parseInt(options.extensionPort, 10) : 6543
|
|
1948
1855
|
);
|
|
1949
|
-
const [previewPort, setPreviewPort] =
|
|
1856
|
+
const [previewPort, setPreviewPort] = useState(
|
|
1950
1857
|
options?.previewPort ? parseInt(options.previewPort, 10) : 6544
|
|
1951
1858
|
);
|
|
1952
|
-
const [registryManifest, setRegistryManifest] =
|
|
1953
|
-
const [localManifest, setLocalManifest] =
|
|
1954
|
-
const [confirmedPermissions, setConfirmedPermissions] =
|
|
1955
|
-
const [confirmedAllowedDomains, setConfirmedAllowedDomains] =
|
|
1956
|
-
const [userEditedAllowedDomains, setUserEditedAllowedDomains] =
|
|
1957
|
-
const [outputDir, setOutputDir] =
|
|
1958
|
-
const [studioProject, setStudioProject] =
|
|
1959
|
-
const [hasLocalProject, setHasLocalProject] =
|
|
1960
|
-
const [progressSteps, setProgressSteps] =
|
|
1961
|
-
const [errorMessage, setErrorMessage] =
|
|
1859
|
+
const [registryManifest, setRegistryManifest] = useState(null);
|
|
1860
|
+
const [localManifest, setLocalManifest] = useState(null);
|
|
1861
|
+
const [confirmedPermissions, setConfirmedPermissions] = useState([]);
|
|
1862
|
+
const [confirmedAllowedDomains, setConfirmedAllowedDomains] = useState([]);
|
|
1863
|
+
const [userEditedAllowedDomains, setUserEditedAllowedDomains] = useState([]);
|
|
1864
|
+
const [outputDir, setOutputDir] = useState("");
|
|
1865
|
+
const [studioProject, setStudioProject] = useState(null);
|
|
1866
|
+
const [hasLocalProject, setHasLocalProject] = useState(false);
|
|
1867
|
+
const [progressSteps, setProgressSteps] = useState(PROGRESS_STEPS[command]);
|
|
1868
|
+
const [errorMessage, setErrorMessage] = useState();
|
|
1962
1869
|
const { step, goForward, goBack, goTo } = useWizardSteps({
|
|
1963
1870
|
command,
|
|
1964
1871
|
initialName,
|
|
@@ -1968,7 +1875,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
1968
1875
|
hasLocalProject,
|
|
1969
1876
|
options
|
|
1970
1877
|
});
|
|
1971
|
-
const updateStep =
|
|
1878
|
+
const updateStep = useCallback((index, status) => {
|
|
1972
1879
|
setProgressSteps((prev) => prev.map((s, i) => i === index ? { ...s, status } : s));
|
|
1973
1880
|
}, []);
|
|
1974
1881
|
const handleAppSelect = async (app) => {
|
|
@@ -2018,8 +1925,8 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2018
1925
|
if (command === "update" /* UPDATE */ || command === "scaffold" /* SCAFFOLD */) {
|
|
2019
1926
|
const projectRoot = options?.dir || process.cwd();
|
|
2020
1927
|
try {
|
|
2021
|
-
const manifestPath =
|
|
2022
|
-
const content = await
|
|
1928
|
+
const manifestPath = join(projectRoot, "packages/extension/public/manifest.json");
|
|
1929
|
+
const content = await readFile(manifestPath, "utf8");
|
|
2023
1930
|
setLocalManifest(JSON.parse(content));
|
|
2024
1931
|
setHasLocalProject(true);
|
|
2025
1932
|
localProjectFound = true;
|
|
@@ -2040,13 +1947,13 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2040
1947
|
if (meta.skipTargetStep && meta.defaultTargets) {
|
|
2041
1948
|
setTargets(meta.defaultTargets);
|
|
2042
1949
|
if (options?.extensionPort || options?.previewPort) {
|
|
2043
|
-
setOutputDir(
|
|
1950
|
+
setOutputDir(join(process.cwd(), toKebabCase(initialName)));
|
|
2044
1951
|
}
|
|
2045
1952
|
}
|
|
2046
1953
|
}
|
|
2047
1954
|
goForward();
|
|
2048
1955
|
};
|
|
2049
|
-
|
|
1956
|
+
useEffect(() => {
|
|
2050
1957
|
if (!options?.appId) return;
|
|
2051
1958
|
fetchApps(token).then((apps) => {
|
|
2052
1959
|
const app = apps.find((a) => a.id === options.appId);
|
|
@@ -2061,7 +1968,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2061
1968
|
goTo("error");
|
|
2062
1969
|
});
|
|
2063
1970
|
}, []);
|
|
2064
|
-
|
|
1971
|
+
useEffect(() => {
|
|
2065
1972
|
if (options?.appId || !initialExtensionId) return;
|
|
2066
1973
|
if (command !== "update" /* UPDATE */ && command !== "scaffold" /* SCAFFOLD */) return;
|
|
2067
1974
|
resolveAppForExtension(token, initialExtensionId).then((result) => {
|
|
@@ -2094,8 +2001,8 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2094
2001
|
let localProjectFound = false;
|
|
2095
2002
|
const projectRoot = options?.dir || process.cwd();
|
|
2096
2003
|
try {
|
|
2097
|
-
const manifestPath =
|
|
2098
|
-
const content = await
|
|
2004
|
+
const manifestPath = join(projectRoot, "packages/extension/public/manifest.json");
|
|
2005
|
+
const content = await readFile(manifestPath, "utf8");
|
|
2099
2006
|
setLocalManifest(JSON.parse(content));
|
|
2100
2007
|
setHasLocalProject(true);
|
|
2101
2008
|
localProjectFound = true;
|
|
@@ -2107,7 +2014,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2107
2014
|
const handleConfirmTargets = (value) => {
|
|
2108
2015
|
setTargets(value);
|
|
2109
2016
|
if (options?.extensionPort || options?.previewPort) {
|
|
2110
|
-
setOutputDir(
|
|
2017
|
+
setOutputDir(join(process.cwd(), toKebabCase(name || extensionId)));
|
|
2111
2018
|
}
|
|
2112
2019
|
goForward();
|
|
2113
2020
|
};
|
|
@@ -2121,7 +2028,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2121
2028
|
}
|
|
2122
2029
|
}
|
|
2123
2030
|
if (options?.extensionPort || options?.previewPort) {
|
|
2124
|
-
setOutputDir(
|
|
2031
|
+
setOutputDir(join(process.cwd(), toKebabCase(value)));
|
|
2125
2032
|
}
|
|
2126
2033
|
goForward();
|
|
2127
2034
|
};
|
|
@@ -2132,14 +2039,14 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2132
2039
|
setTargets(meta.defaultTargets);
|
|
2133
2040
|
}
|
|
2134
2041
|
if (options?.extensionPort || options?.previewPort) {
|
|
2135
|
-
setOutputDir(
|
|
2042
|
+
setOutputDir(join(process.cwd(), toKebabCase(name || extensionId)));
|
|
2136
2043
|
}
|
|
2137
2044
|
goForward({ templateFlavor: flavor });
|
|
2138
2045
|
};
|
|
2139
2046
|
const handleTargets = (value) => {
|
|
2140
2047
|
setTargets(value);
|
|
2141
2048
|
if (options?.extensionPort || options?.previewPort) {
|
|
2142
|
-
setOutputDir(
|
|
2049
|
+
setOutputDir(join(process.cwd(), toKebabCase(name || extensionId)));
|
|
2143
2050
|
}
|
|
2144
2051
|
goForward();
|
|
2145
2052
|
};
|
|
@@ -2237,9 +2144,9 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2237
2144
|
}
|
|
2238
2145
|
}
|
|
2239
2146
|
if (command === "create" /* CREATE */) {
|
|
2240
|
-
const manifestPath =
|
|
2147
|
+
const manifestPath = join(outputDir, "packages/extension/public/manifest.json");
|
|
2241
2148
|
try {
|
|
2242
|
-
const manifestContent = await
|
|
2149
|
+
const manifestContent = await readFile(manifestPath, "utf8");
|
|
2243
2150
|
const manifest = JSON.parse(manifestContent);
|
|
2244
2151
|
await updateExtension(token, selectedApp.id, resolvedExtensionId, {
|
|
2245
2152
|
manifest: { ...manifest, allowedDomains: [] }
|
|
@@ -2248,7 +2155,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2248
2155
|
}
|
|
2249
2156
|
}
|
|
2250
2157
|
updateStep(scaffoldStepOffset + 1, "running");
|
|
2251
|
-
await
|
|
2158
|
+
await delay(200);
|
|
2252
2159
|
updateStep(scaffoldStepOffset + 1, "done");
|
|
2253
2160
|
if (!options?.skipInstall) {
|
|
2254
2161
|
updateStep(scaffoldStepOffset + 2, "running");
|
|
@@ -2270,15 +2177,15 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2270
2177
|
switch (step) {
|
|
2271
2178
|
case "app": {
|
|
2272
2179
|
if (options?.appId || initialExtensionId && (command === "update" /* UPDATE */ || command === "scaffold" /* SCAFFOLD */)) {
|
|
2273
|
-
return /* @__PURE__ */
|
|
2274
|
-
/* @__PURE__ */
|
|
2275
|
-
/* @__PURE__ */
|
|
2276
|
-
/* @__PURE__ */
|
|
2277
|
-
/* @__PURE__ */
|
|
2180
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
2181
|
+
/* @__PURE__ */ jsx(Banner, { userId, orgId }),
|
|
2182
|
+
/* @__PURE__ */ jsx(StepShell, { title: "Loading App\u2026", children: /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
2183
|
+
/* @__PURE__ */ jsx(Spinner5, { type: "dots" }),
|
|
2184
|
+
/* @__PURE__ */ jsx(Text, { children: options?.appId ? "Fetching app details\u2026" : "Resolving app from extension\u2026" })
|
|
2278
2185
|
] }) })
|
|
2279
2186
|
] });
|
|
2280
2187
|
}
|
|
2281
|
-
return /* @__PURE__ */
|
|
2188
|
+
return /* @__PURE__ */ jsx(
|
|
2282
2189
|
AppSelect,
|
|
2283
2190
|
{
|
|
2284
2191
|
token,
|
|
@@ -2289,7 +2196,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2289
2196
|
);
|
|
2290
2197
|
}
|
|
2291
2198
|
case "extensionSelect": {
|
|
2292
|
-
return /* @__PURE__ */
|
|
2199
|
+
return /* @__PURE__ */ jsx(
|
|
2293
2200
|
ExtensionSelect,
|
|
2294
2201
|
{
|
|
2295
2202
|
appId: selectedApp.id,
|
|
@@ -2301,7 +2208,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2301
2208
|
);
|
|
2302
2209
|
}
|
|
2303
2210
|
case "confirmTargets": {
|
|
2304
|
-
return /* @__PURE__ */
|
|
2211
|
+
return /* @__PURE__ */ jsx(
|
|
2305
2212
|
TargetSelect,
|
|
2306
2213
|
{
|
|
2307
2214
|
availableTargets: selectedApp?.targets ?? [],
|
|
@@ -2312,7 +2219,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2312
2219
|
);
|
|
2313
2220
|
}
|
|
2314
2221
|
case "name": {
|
|
2315
|
-
return /* @__PURE__ */
|
|
2222
|
+
return /* @__PURE__ */ jsx(
|
|
2316
2223
|
NamePrompt,
|
|
2317
2224
|
{
|
|
2318
2225
|
initialValue: name,
|
|
@@ -2322,7 +2229,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2322
2229
|
);
|
|
2323
2230
|
}
|
|
2324
2231
|
case "template": {
|
|
2325
|
-
return /* @__PURE__ */
|
|
2232
|
+
return /* @__PURE__ */ jsx(
|
|
2326
2233
|
TemplateSelect,
|
|
2327
2234
|
{
|
|
2328
2235
|
onSubmit: handleTemplateSelect,
|
|
@@ -2331,7 +2238,7 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2331
2238
|
);
|
|
2332
2239
|
}
|
|
2333
2240
|
case "targets": {
|
|
2334
|
-
return /* @__PURE__ */
|
|
2241
|
+
return /* @__PURE__ */ jsx(
|
|
2335
2242
|
TargetSelect,
|
|
2336
2243
|
{
|
|
2337
2244
|
availableTargets: selectedApp?.targets ?? [],
|
|
@@ -2342,17 +2249,17 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2342
2249
|
);
|
|
2343
2250
|
}
|
|
2344
2251
|
case "settings": {
|
|
2345
|
-
return /* @__PURE__ */
|
|
2252
|
+
return /* @__PURE__ */ jsx(
|
|
2346
2253
|
SettingsPrompt,
|
|
2347
2254
|
{
|
|
2348
|
-
defaultDir:
|
|
2255
|
+
defaultDir: join(process.cwd(), toKebabCase(name || extensionId)),
|
|
2349
2256
|
onSubmit: handleSettings,
|
|
2350
2257
|
onBack: goBack
|
|
2351
2258
|
}
|
|
2352
2259
|
);
|
|
2353
2260
|
}
|
|
2354
2261
|
case "confirm": {
|
|
2355
|
-
return /* @__PURE__ */
|
|
2262
|
+
return /* @__PURE__ */ jsx(
|
|
2356
2263
|
Confirm,
|
|
2357
2264
|
{
|
|
2358
2265
|
command,
|
|
@@ -2379,10 +2286,10 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2379
2286
|
);
|
|
2380
2287
|
}
|
|
2381
2288
|
case "scaffolding": {
|
|
2382
|
-
return /* @__PURE__ */
|
|
2289
|
+
return /* @__PURE__ */ jsx(ScaffoldProgress, { steps: progressSteps });
|
|
2383
2290
|
}
|
|
2384
2291
|
case "updateSettings": {
|
|
2385
|
-
return /* @__PURE__ */
|
|
2292
|
+
return /* @__PURE__ */ jsx(
|
|
2386
2293
|
UpdateSettingsPrompt,
|
|
2387
2294
|
{
|
|
2388
2295
|
name,
|
|
@@ -2406,8 +2313,17 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2406
2313
|
);
|
|
2407
2314
|
}
|
|
2408
2315
|
case "manifestReview": {
|
|
2409
|
-
const
|
|
2410
|
-
|
|
2316
|
+
const buildEffectiveManifest = () => {
|
|
2317
|
+
if (localManifest) {
|
|
2318
|
+
return { ...localManifest, allowedDomains: userEditedAllowedDomains };
|
|
2319
|
+
}
|
|
2320
|
+
if (userEditedAllowedDomains.length > 0) {
|
|
2321
|
+
return { name, version: "0.0.0", targets, permissions: [], allowedDomains: userEditedAllowedDomains };
|
|
2322
|
+
}
|
|
2323
|
+
return localManifest;
|
|
2324
|
+
};
|
|
2325
|
+
const effectiveLocalManifest = buildEffectiveManifest();
|
|
2326
|
+
return /* @__PURE__ */ jsx(
|
|
2411
2327
|
ManifestReviewPrompt,
|
|
2412
2328
|
{
|
|
2413
2329
|
localManifest: effectiveLocalManifest,
|
|
@@ -2422,49 +2338,42 @@ var App = ({ command, token, userId, orgId, initialName, initialExtensionId, opt
|
|
|
2422
2338
|
);
|
|
2423
2339
|
}
|
|
2424
2340
|
case "updating": {
|
|
2425
|
-
return /* @__PURE__ */
|
|
2341
|
+
return /* @__PURE__ */ jsx(ScaffoldProgress, { steps: progressSteps });
|
|
2426
2342
|
}
|
|
2427
2343
|
case "updateDone": {
|
|
2428
|
-
return /* @__PURE__ */
|
|
2429
|
-
/* @__PURE__ */
|
|
2430
|
-
/* @__PURE__ */
|
|
2344
|
+
return /* @__PURE__ */ jsx(StepShell, { title: "Extension updated", onBack: goBack, children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
2345
|
+
/* @__PURE__ */ jsx(Text, { color: "green", bold: true, children: "Extension updated successfully!" }),
|
|
2346
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
2431
2347
|
"Name: ",
|
|
2432
2348
|
name
|
|
2433
2349
|
] }),
|
|
2434
|
-
/* @__PURE__ */
|
|
2350
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
2435
2351
|
"ID: ",
|
|
2436
2352
|
extensionId
|
|
2437
2353
|
] }),
|
|
2438
|
-
/* @__PURE__ */
|
|
2354
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
2439
2355
|
"Version: ",
|
|
2440
2356
|
extensionVersion
|
|
2441
2357
|
] })
|
|
2442
2358
|
] }) });
|
|
2443
2359
|
}
|
|
2444
2360
|
case "done": {
|
|
2445
|
-
return /* @__PURE__ */
|
|
2361
|
+
return /* @__PURE__ */ jsx(Done, { name, outputDir, templateFlavor: command === "create" /* CREATE */ ? templateFlavor : void 0 });
|
|
2446
2362
|
}
|
|
2447
2363
|
case "error": {
|
|
2448
|
-
return /* @__PURE__ */
|
|
2449
|
-
/* @__PURE__ */
|
|
2450
|
-
errorMessage && /* @__PURE__ */
|
|
2364
|
+
return /* @__PURE__ */ jsx(StepShell, { title: "Operation failed", onBack: goBack, children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
2365
|
+
/* @__PURE__ */ jsx(Text, { color: "red", bold: true, children: "An error occurred" }),
|
|
2366
|
+
errorMessage && /* @__PURE__ */ jsx(Text, { color: "red", children: errorMessage })
|
|
2451
2367
|
] }) });
|
|
2452
2368
|
}
|
|
2453
2369
|
default: {
|
|
2454
|
-
return /* @__PURE__ */
|
|
2455
|
-
/* @__PURE__ */
|
|
2456
|
-
errorMessage && /* @__PURE__ */
|
|
2370
|
+
return /* @__PURE__ */ jsx(StepShell, { title: "Scaffold failed", onBack: goBack, children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
2371
|
+
/* @__PURE__ */ jsx(Text, { color: "red", bold: true, children: "An error occurred" }),
|
|
2372
|
+
errorMessage && /* @__PURE__ */ jsx(Text, { color: "red", children: errorMessage })
|
|
2457
2373
|
] }) });
|
|
2458
2374
|
}
|
|
2459
2375
|
}
|
|
2460
2376
|
};
|
|
2461
|
-
|
|
2462
|
-
// src/components/DevApp.tsx
|
|
2463
|
-
import { useRef, useState as useState14, useEffect as useEffect7, useCallback as useCallback4 } from "react";
|
|
2464
|
-
import { useInput as useInput12, Box as Box19, Text as Text19 } from "ink";
|
|
2465
|
-
|
|
2466
|
-
// src/lib/devServer.ts
|
|
2467
|
-
import { spawn } from "child_process";
|
|
2468
2377
|
var startDevServer = (projectRoot) => {
|
|
2469
2378
|
const child = spawn("pnpm", ["dev"], {
|
|
2470
2379
|
cwd: projectRoot,
|
|
@@ -2475,9 +2384,6 @@ var startDevServer = (projectRoot) => {
|
|
|
2475
2384
|
};
|
|
2476
2385
|
return { process: child, stop };
|
|
2477
2386
|
};
|
|
2478
|
-
|
|
2479
|
-
// src/lib/tunnel.ts
|
|
2480
|
-
import { Tunnel } from "cloudflared";
|
|
2481
2387
|
var MAX_RETRIES = 3;
|
|
2482
2388
|
var RETRY_DELAY_MS = 2e3;
|
|
2483
2389
|
var isValidTunnelUrl = (url) => {
|
|
@@ -2514,7 +2420,6 @@ var startTunnelOnce = (port) => new Promise((resolve, reject) => {
|
|
|
2514
2420
|
reject(err);
|
|
2515
2421
|
});
|
|
2516
2422
|
});
|
|
2517
|
-
var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
2518
2423
|
var startTunnel = async (port) => {
|
|
2519
2424
|
for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
|
|
2520
2425
|
try {
|
|
@@ -2531,15 +2436,10 @@ var startTunnel = async (port) => {
|
|
|
2531
2436
|
}
|
|
2532
2437
|
throw new Error(`Tunnel failed to return a valid URL after ${MAX_RETRIES} attempts`);
|
|
2533
2438
|
};
|
|
2534
|
-
|
|
2535
|
-
// src/components/DevSetup.tsx
|
|
2536
|
-
import { Box as Box16, Text as Text16 } from "ink";
|
|
2537
|
-
import { useState as useState12, useEffect as useEffect5 } from "react";
|
|
2538
|
-
import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2539
2439
|
var DevSetup = ({ initialContext, token, onReady }) => {
|
|
2540
|
-
const [step, setStep] =
|
|
2541
|
-
const [selectedApp, setSelectedApp] =
|
|
2542
|
-
|
|
2440
|
+
const [step, setStep] = useState("app");
|
|
2441
|
+
const [selectedApp, setSelectedApp] = useState(null);
|
|
2442
|
+
useEffect(() => {
|
|
2543
2443
|
if (initialContext.appId) {
|
|
2544
2444
|
setStep("extension");
|
|
2545
2445
|
}
|
|
@@ -2556,9 +2456,9 @@ var DevSetup = ({ initialContext, token, onReady }) => {
|
|
|
2556
2456
|
});
|
|
2557
2457
|
};
|
|
2558
2458
|
if (step === "app") {
|
|
2559
|
-
return /* @__PURE__ */
|
|
2560
|
-
/* @__PURE__ */
|
|
2561
|
-
/* @__PURE__ */
|
|
2459
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
2460
|
+
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { children: "Select the App for your extension:" }) }),
|
|
2461
|
+
/* @__PURE__ */ jsx(
|
|
2562
2462
|
AppSelect,
|
|
2563
2463
|
{
|
|
2564
2464
|
token,
|
|
@@ -2567,9 +2467,9 @@ var DevSetup = ({ initialContext, token, onReady }) => {
|
|
|
2567
2467
|
)
|
|
2568
2468
|
] });
|
|
2569
2469
|
}
|
|
2570
|
-
return /* @__PURE__ */
|
|
2571
|
-
/* @__PURE__ */
|
|
2572
|
-
/* @__PURE__ */
|
|
2470
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
2471
|
+
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { children: "Select the Extension to develop:" }) }),
|
|
2472
|
+
/* @__PURE__ */ jsx(
|
|
2573
2473
|
ExtensionSelect,
|
|
2574
2474
|
{
|
|
2575
2475
|
token,
|
|
@@ -2579,16 +2479,6 @@ var DevSetup = ({ initialContext, token, onReady }) => {
|
|
|
2579
2479
|
)
|
|
2580
2480
|
] });
|
|
2581
2481
|
};
|
|
2582
|
-
|
|
2583
|
-
// src/components/DevDashboard.tsx
|
|
2584
|
-
import { Box as Box18, Text as Text18, useInput as useInput11 } from "ink";
|
|
2585
|
-
import { useEffect as useEffect6, useMemo as useMemo2 } from "react";
|
|
2586
|
-
|
|
2587
|
-
// src/components/CopyableField.tsx
|
|
2588
|
-
import { useState as useState13, useCallback as useCallback3 } from "react";
|
|
2589
|
-
import { useInput as useInput10, Box as Box17, Text as Text17 } from "ink";
|
|
2590
|
-
import clipboard from "clipboardy";
|
|
2591
|
-
import { jsx as jsx17, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
2592
2482
|
var CopyableField = ({
|
|
2593
2483
|
label,
|
|
2594
2484
|
value,
|
|
@@ -2598,9 +2488,9 @@ var CopyableField = ({
|
|
|
2598
2488
|
labelColor,
|
|
2599
2489
|
children
|
|
2600
2490
|
}) => {
|
|
2601
|
-
const [expanded, setExpanded] =
|
|
2602
|
-
const [copied, setCopied] =
|
|
2603
|
-
const handleCopy =
|
|
2491
|
+
const [expanded, setExpanded] = useState(false);
|
|
2492
|
+
const [copied, setCopied] = useState(false);
|
|
2493
|
+
const handleCopy = useCallback(async () => {
|
|
2604
2494
|
if (expanded) {
|
|
2605
2495
|
setExpanded(false);
|
|
2606
2496
|
setCopied(false);
|
|
@@ -2618,20 +2508,20 @@ var CopyableField = ({
|
|
|
2618
2508
|
setExpanded(true);
|
|
2619
2509
|
}
|
|
2620
2510
|
}, [expanded, value]);
|
|
2621
|
-
|
|
2511
|
+
useInput((input) => {
|
|
2622
2512
|
if (input === shortcutKey) {
|
|
2623
2513
|
handleCopy();
|
|
2624
2514
|
}
|
|
2625
2515
|
});
|
|
2626
2516
|
const truncated = value.length > maxLength ? `${value.slice(0, maxLength)}...` : value;
|
|
2627
2517
|
const keyHint = shortcutLabel || shortcutKey;
|
|
2628
|
-
return /* @__PURE__ */
|
|
2629
|
-
/* @__PURE__ */
|
|
2630
|
-
/* @__PURE__ */
|
|
2631
|
-
copied && /* @__PURE__ */
|
|
2632
|
-
!copied && /* @__PURE__ */
|
|
2518
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
2519
|
+
/* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
2520
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: label }),
|
|
2521
|
+
copied && /* @__PURE__ */ jsx(Text, { color: "green", bold: true, children: "Copied!" }),
|
|
2522
|
+
!copied && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
2633
2523
|
"press ",
|
|
2634
|
-
/* @__PURE__ */
|
|
2524
|
+
/* @__PURE__ */ jsxs(Text, { bold: true, color: "yellow", children: [
|
|
2635
2525
|
"[",
|
|
2636
2526
|
keyHint,
|
|
2637
2527
|
"]"
|
|
@@ -2639,12 +2529,9 @@ var CopyableField = ({
|
|
|
2639
2529
|
" to copy (and see full value)"
|
|
2640
2530
|
] })
|
|
2641
2531
|
] }),
|
|
2642
|
-
/* @__PURE__ */
|
|
2532
|
+
/* @__PURE__ */ jsx(Box, { paddingLeft: 2, children: expanded ? /* @__PURE__ */ jsx(Text, { wrap: "wrap", children: value }) : children || /* @__PURE__ */ jsx(Text, { children: labelColor ? /* @__PURE__ */ jsx(Text, { color: labelColor, children: truncated }) : truncated }) })
|
|
2643
2533
|
] });
|
|
2644
2534
|
};
|
|
2645
|
-
|
|
2646
|
-
// src/components/DevDashboard.tsx
|
|
2647
|
-
import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
2648
2535
|
var toBase64Url = (input) => btoa(input).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
2649
2536
|
var DevDashboard = ({
|
|
2650
2537
|
previewTunnelUrl,
|
|
@@ -2661,7 +2548,7 @@ var DevDashboard = ({
|
|
|
2661
2548
|
devSessionToken,
|
|
2662
2549
|
onQuit
|
|
2663
2550
|
}) => {
|
|
2664
|
-
|
|
2551
|
+
useEffect(() => {
|
|
2665
2552
|
const handler = () => {
|
|
2666
2553
|
onQuit();
|
|
2667
2554
|
};
|
|
@@ -2670,107 +2557,107 @@ var DevDashboard = ({
|
|
|
2670
2557
|
process.off("SIGINT", handler);
|
|
2671
2558
|
};
|
|
2672
2559
|
}, [onQuit]);
|
|
2673
|
-
const devParamBlob =
|
|
2560
|
+
const devParamBlob = useMemo(() => {
|
|
2674
2561
|
if (!tunnelUrl || !devSessionToken) return "";
|
|
2675
2562
|
return toBase64Url(JSON.stringify({ url: tunnelUrl, token: devSessionToken }));
|
|
2676
2563
|
}, [tunnelUrl, devSessionToken]);
|
|
2677
|
-
|
|
2564
|
+
useInput((input, key) => {
|
|
2678
2565
|
if (input === "q" || key.ctrl && input === "c") {
|
|
2679
2566
|
onQuit();
|
|
2680
2567
|
}
|
|
2681
2568
|
});
|
|
2682
|
-
return /* @__PURE__ */
|
|
2683
|
-
/* @__PURE__ */
|
|
2684
|
-
/* @__PURE__ */
|
|
2569
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
2570
|
+
/* @__PURE__ */ jsx(Banner, { userId, orgId }),
|
|
2571
|
+
/* @__PURE__ */ jsxs(
|
|
2685
2572
|
StepShell,
|
|
2686
2573
|
{
|
|
2687
2574
|
title: "dev",
|
|
2688
2575
|
hint: `Live development ${tunnelUrl ? "with" : "w/o"} Tunnel \u2014 ${appName ? `${appName} ` : ""}(${appId})`,
|
|
2689
|
-
footer: /* @__PURE__ */
|
|
2690
|
-
devParamBlob && /* @__PURE__ */
|
|
2576
|
+
footer: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
2577
|
+
devParamBlob && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
2691
2578
|
"Press ",
|
|
2692
|
-
/* @__PURE__ */
|
|
2579
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "[d]" }),
|
|
2693
2580
|
" to copy Dev Param, ",
|
|
2694
|
-
/* @__PURE__ */
|
|
2581
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "[s]" }),
|
|
2695
2582
|
" to copy Staging Param"
|
|
2696
2583
|
] }),
|
|
2697
|
-
/* @__PURE__ */
|
|
2584
|
+
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
2698
2585
|
"Press ",
|
|
2699
|
-
/* @__PURE__ */
|
|
2586
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "[q]" }),
|
|
2700
2587
|
" or Ctrl-C to quit"
|
|
2701
2588
|
] })
|
|
2702
2589
|
] }),
|
|
2703
2590
|
children: [
|
|
2704
|
-
/* @__PURE__ */
|
|
2705
|
-
/* @__PURE__ */
|
|
2706
|
-
/* @__PURE__ */
|
|
2707
|
-
/* @__PURE__ */
|
|
2591
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
2592
|
+
/* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
2593
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Extension:" }),
|
|
2594
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2708
2595
|
extensionName,
|
|
2709
2596
|
" (",
|
|
2710
2597
|
extensionId,
|
|
2711
2598
|
")"
|
|
2712
2599
|
] })
|
|
2713
2600
|
] }),
|
|
2714
|
-
/* @__PURE__ */
|
|
2715
|
-
/* @__PURE__ */
|
|
2716
|
-
/* @__PURE__ */
|
|
2601
|
+
/* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
2602
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Bundle URL:" }),
|
|
2603
|
+
/* @__PURE__ */ jsx(Text, { children: tunnelUrl || `http://localhost:${extensionPort}` })
|
|
2717
2604
|
] })
|
|
2718
2605
|
] }),
|
|
2719
|
-
/* @__PURE__ */
|
|
2720
|
-
previewTunnelUrl && /* @__PURE__ */
|
|
2721
|
-
/* @__PURE__ */
|
|
2722
|
-
/* @__PURE__ */
|
|
2606
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
2607
|
+
previewTunnelUrl && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
2608
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Tunnel Dev - Preview:" }),
|
|
2609
|
+
/* @__PURE__ */ jsx(Text, { children: previewTunnelUrl })
|
|
2723
2610
|
] }),
|
|
2724
|
-
/* @__PURE__ */
|
|
2725
|
-
/* @__PURE__ */
|
|
2726
|
-
/* @__PURE__ */
|
|
2611
|
+
/* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
2612
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Local Dev - Preview:" }),
|
|
2613
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2727
2614
|
"http://localhost:",
|
|
2728
2615
|
previewPort
|
|
2729
2616
|
] })
|
|
2730
2617
|
] })
|
|
2731
2618
|
] }),
|
|
2732
|
-
/* @__PURE__ */
|
|
2733
|
-
tunnelUrl && /* @__PURE__ */
|
|
2734
|
-
/* @__PURE__ */
|
|
2735
|
-
/* @__PURE__ */
|
|
2619
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
2620
|
+
tunnelUrl && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
2621
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Tunnel Dev - Extension:" }),
|
|
2622
|
+
/* @__PURE__ */ jsx(Text, { children: tunnelUrl })
|
|
2736
2623
|
] }),
|
|
2737
|
-
/* @__PURE__ */
|
|
2738
|
-
/* @__PURE__ */
|
|
2739
|
-
/* @__PURE__ */
|
|
2624
|
+
/* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
2625
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Local Dev - Extension:" }),
|
|
2626
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2740
2627
|
"http://localhost:",
|
|
2741
2628
|
extensionPort
|
|
2742
2629
|
] })
|
|
2743
2630
|
] })
|
|
2744
2631
|
] }),
|
|
2745
|
-
tunnelUrl && devSessionToken && /* @__PURE__ */
|
|
2746
|
-
/* @__PURE__ */
|
|
2632
|
+
tunnelUrl && devSessionToken && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2633
|
+
/* @__PURE__ */ jsx(
|
|
2747
2634
|
CopyableField,
|
|
2748
2635
|
{
|
|
2749
2636
|
label: "Dev Param (no encryption):",
|
|
2750
2637
|
value: `?_stackable_dev=${extensionId}:${devParamBlob}`,
|
|
2751
2638
|
shortcutKey: "d",
|
|
2752
|
-
children: /* @__PURE__ */
|
|
2639
|
+
children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
2753
2640
|
"?",
|
|
2754
|
-
/* @__PURE__ */
|
|
2641
|
+
/* @__PURE__ */ jsx(Text, { color: "yellow", children: "_stackable_dev" }),
|
|
2755
2642
|
"=",
|
|
2756
|
-
/* @__PURE__ */
|
|
2643
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: extensionId }),
|
|
2757
2644
|
":",
|
|
2758
2645
|
devParamBlob.slice(0, 20),
|
|
2759
2646
|
"..."
|
|
2760
2647
|
] })
|
|
2761
2648
|
}
|
|
2762
2649
|
),
|
|
2763
|
-
/* @__PURE__ */
|
|
2650
|
+
/* @__PURE__ */ jsx(
|
|
2764
2651
|
CopyableField,
|
|
2765
2652
|
{
|
|
2766
2653
|
label: "Staging Param (with encryption):",
|
|
2767
2654
|
value: `?_stackable_staging=${extensionId}:${devParamBlob}`,
|
|
2768
2655
|
shortcutKey: "s",
|
|
2769
|
-
children: /* @__PURE__ */
|
|
2656
|
+
children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
2770
2657
|
"?",
|
|
2771
|
-
/* @__PURE__ */
|
|
2658
|
+
/* @__PURE__ */ jsx(Text, { color: "yellow", children: "_stackable_staging" }),
|
|
2772
2659
|
"=",
|
|
2773
|
-
/* @__PURE__ */
|
|
2660
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: extensionId }),
|
|
2774
2661
|
":",
|
|
2775
2662
|
devParamBlob.slice(0, 20),
|
|
2776
2663
|
"..."
|
|
@@ -2778,47 +2665,44 @@ var DevDashboard = ({
|
|
|
2778
2665
|
}
|
|
2779
2666
|
)
|
|
2780
2667
|
] }),
|
|
2781
|
-
tunnelUrl && !devSessionToken && /* @__PURE__ */
|
|
2782
|
-
/* @__PURE__ */
|
|
2783
|
-
/* @__PURE__ */
|
|
2668
|
+
tunnelUrl && !devSessionToken && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
2669
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Host Dev - Query Param:" }),
|
|
2670
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2784
2671
|
"?",
|
|
2785
|
-
/* @__PURE__ */
|
|
2672
|
+
/* @__PURE__ */ jsx(Text, { color: "yellow", children: "_stackable_dev" }),
|
|
2786
2673
|
"=",
|
|
2787
|
-
/* @__PURE__ */
|
|
2674
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: extensionId }),
|
|
2788
2675
|
":",
|
|
2789
2676
|
tunnelUrl
|
|
2790
2677
|
] })
|
|
2791
2678
|
] }),
|
|
2792
|
-
manifestWarnings.length > 0 && /* @__PURE__ */
|
|
2793
|
-
/* @__PURE__ */
|
|
2794
|
-
manifestWarnings.map((w, i) => /* @__PURE__ */
|
|
2679
|
+
manifestWarnings.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [
|
|
2680
|
+
/* @__PURE__ */ jsx(Text, { color: "yellow", bold: true, children: "Local manifest differs from registry:" }),
|
|
2681
|
+
manifestWarnings.map((w, i) => /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
2795
2682
|
" ",
|
|
2796
2683
|
w
|
|
2797
2684
|
] }, i)),
|
|
2798
|
-
/* @__PURE__ */
|
|
2685
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: " Run `pnpm --config.dlx-cache-max-age=0 dlx @stackable-labs/cli-app-extension@latest update` to review and sync." })
|
|
2799
2686
|
] })
|
|
2800
2687
|
]
|
|
2801
2688
|
}
|
|
2802
2689
|
)
|
|
2803
2690
|
] });
|
|
2804
2691
|
};
|
|
2805
|
-
|
|
2806
|
-
// src/components/DevApp.tsx
|
|
2807
|
-
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
2808
2692
|
var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
2809
|
-
const [state, setState] =
|
|
2810
|
-
const [devContext, setDevContext] =
|
|
2811
|
-
const [resolvedContext, setResolvedContext] =
|
|
2812
|
-
const [tunnelUrl, setTunnelUrl] =
|
|
2813
|
-
const [previewTunnelUrl, setPreviewTunnelUrl] =
|
|
2814
|
-
const [tunnelHandle, setTunnelHandle] =
|
|
2815
|
-
const [previewTunnelHandle, setPreviewTunnelHandle] =
|
|
2816
|
-
const [devServerHandle, setDevServerHandle] =
|
|
2817
|
-
const [manifestWarnings, setManifestWarnings] =
|
|
2818
|
-
const [devSessionToken, setDevSessionToken] =
|
|
2693
|
+
const [state, setState] = useState("setup");
|
|
2694
|
+
const [devContext, setDevContext] = useState(null);
|
|
2695
|
+
const [resolvedContext, setResolvedContext] = useState(null);
|
|
2696
|
+
const [tunnelUrl, setTunnelUrl] = useState(null);
|
|
2697
|
+
const [previewTunnelUrl, setPreviewTunnelUrl] = useState(null);
|
|
2698
|
+
const [tunnelHandle, setTunnelHandle] = useState(null);
|
|
2699
|
+
const [previewTunnelHandle, setPreviewTunnelHandle] = useState(null);
|
|
2700
|
+
const [devServerHandle, setDevServerHandle] = useState(null);
|
|
2701
|
+
const [manifestWarnings, setManifestWarnings] = useState([]);
|
|
2702
|
+
const [devSessionToken, setDevSessionToken] = useState(null);
|
|
2819
2703
|
const shuttingDown = useRef(false);
|
|
2820
2704
|
const useTunnel = options.tunnel !== false;
|
|
2821
|
-
|
|
2705
|
+
useEffect(() => {
|
|
2822
2706
|
const projectRoot = options.dir || process.cwd();
|
|
2823
2707
|
console.log(`[dev] Reading context from ${projectRoot}`);
|
|
2824
2708
|
readDevContext(projectRoot).then((ctx) => {
|
|
@@ -2826,7 +2710,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2826
2710
|
setDevContext(ctx);
|
|
2827
2711
|
});
|
|
2828
2712
|
}, [options.dir]);
|
|
2829
|
-
const handleSetupReady =
|
|
2713
|
+
const handleSetupReady = useCallback(async (resolved) => {
|
|
2830
2714
|
if (!devContext) return;
|
|
2831
2715
|
setResolvedContext(resolved);
|
|
2832
2716
|
console.log(`[dev] Saving context: appId=${resolved.appId} extensionId=${resolved.extensionId}`);
|
|
@@ -2898,7 +2782,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2898
2782
|
console.log("[dev] Ready");
|
|
2899
2783
|
setState("running");
|
|
2900
2784
|
}, [devContext, token, options.extensionPort, options.previewPort, useTunnel]);
|
|
2901
|
-
|
|
2785
|
+
useEffect(() => {
|
|
2902
2786
|
if (state === "setup" && devContext && devContext.appId && devContext.extensionId) {
|
|
2903
2787
|
handleSetupReady({
|
|
2904
2788
|
appId: devContext.appId,
|
|
@@ -2933,7 +2817,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2933
2817
|
console.log("[dev] Done");
|
|
2934
2818
|
process.exit(0);
|
|
2935
2819
|
};
|
|
2936
|
-
|
|
2820
|
+
useInput((input, key) => {
|
|
2937
2821
|
if (input === "c" && key.ctrl) {
|
|
2938
2822
|
if (state === "running") {
|
|
2939
2823
|
handleQuit();
|
|
@@ -2944,7 +2828,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2944
2828
|
});
|
|
2945
2829
|
if (state === "setup" && devContext) {
|
|
2946
2830
|
if (!devContext.appId || !devContext.extensionId) {
|
|
2947
|
-
return /* @__PURE__ */
|
|
2831
|
+
return /* @__PURE__ */ jsx(
|
|
2948
2832
|
DevSetup,
|
|
2949
2833
|
{
|
|
2950
2834
|
token,
|
|
@@ -2956,7 +2840,7 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2956
2840
|
return null;
|
|
2957
2841
|
}
|
|
2958
2842
|
if (state === "running" && devContext && resolvedContext) {
|
|
2959
|
-
return /* @__PURE__ */
|
|
2843
|
+
return /* @__PURE__ */ jsx(
|
|
2960
2844
|
DevDashboard,
|
|
2961
2845
|
{
|
|
2962
2846
|
previewTunnelUrl,
|
|
@@ -2978,19 +2862,8 @@ var DevApp = ({ token, userId, orgId, options = {} }) => {
|
|
|
2978
2862
|
if (state === "stopping") {
|
|
2979
2863
|
return null;
|
|
2980
2864
|
}
|
|
2981
|
-
return /* @__PURE__ */
|
|
2865
|
+
return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { children: "Loading..." }) });
|
|
2982
2866
|
};
|
|
2983
|
-
|
|
2984
|
-
// src/components/AIScaffold.tsx
|
|
2985
|
-
import { Box as Box20, Text as Text20, useApp as useApp2 } from "ink";
|
|
2986
|
-
import Spinner5 from "ink-spinner";
|
|
2987
|
-
import { useState as useState15, useEffect as useEffect8 } from "react";
|
|
2988
|
-
|
|
2989
|
-
// src/lib/aiDocs.ts
|
|
2990
|
-
import { existsSync, readFileSync } from "fs";
|
|
2991
|
-
import { join as join4, dirname } from "path";
|
|
2992
|
-
import { mkdir, writeFile as writeFile3 } from "fs/promises";
|
|
2993
|
-
import AdmZip from "adm-zip";
|
|
2994
2867
|
var DEFAULT_STATIC_CDN_URL = "https://static.stackablelabs.io";
|
|
2995
2868
|
var AI_DOCS_FILENAME = "extension-ai-docs.zip";
|
|
2996
2869
|
var getStaticCdnBaseUrl = () => process.env.STATIC_CDN_BASE_URL ?? DEFAULT_STATIC_CDN_URL;
|
|
@@ -3000,7 +2873,7 @@ var isValidManifest = (data) => {
|
|
|
3000
2873
|
return typeof m.name === "string" && m.name.length > 0 && typeof m.version === "string" && Array.isArray(m.targets) && Array.isArray(m.permissions) && Array.isArray(m.allowedDomains);
|
|
3001
2874
|
};
|
|
3002
2875
|
var isExtensionProject = (dir) => {
|
|
3003
|
-
const manifestPath =
|
|
2876
|
+
const manifestPath = join(dir, "packages/extension/public/manifest.json");
|
|
3004
2877
|
if (!existsSync(manifestPath)) {
|
|
3005
2878
|
return { valid: false, reason: "No manifest.json found at packages/extension/public/manifest.json \u2014 is this an Extension project?" };
|
|
3006
2879
|
}
|
|
@@ -3028,22 +2901,19 @@ var downloadAndExtractAiDocs = async (targetDir, version2) => {
|
|
|
3028
2901
|
const extractedFiles = [];
|
|
3029
2902
|
for (const entry of entries) {
|
|
3030
2903
|
if (entry.isDirectory) continue;
|
|
3031
|
-
const targetPath =
|
|
2904
|
+
const targetPath = join(targetDir, entry.entryName);
|
|
3032
2905
|
await mkdir(dirname(targetPath), { recursive: true });
|
|
3033
|
-
await
|
|
2906
|
+
await writeFile(targetPath, entry.getData());
|
|
3034
2907
|
extractedFiles.push(entry.entryName);
|
|
3035
2908
|
}
|
|
3036
2909
|
return { files: extractedFiles.sort() };
|
|
3037
2910
|
};
|
|
3038
|
-
|
|
3039
|
-
// src/components/AIScaffold.tsx
|
|
3040
|
-
import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
3041
2911
|
var AIScaffold = ({ version: version2 }) => {
|
|
3042
|
-
const { exit } =
|
|
3043
|
-
const [state, setState] =
|
|
3044
|
-
const [files, setFiles] =
|
|
3045
|
-
const [errorMessage, setErrorMessage] =
|
|
3046
|
-
|
|
2912
|
+
const { exit } = useApp();
|
|
2913
|
+
const [state, setState] = useState("validating");
|
|
2914
|
+
const [files, setFiles] = useState([]);
|
|
2915
|
+
const [errorMessage, setErrorMessage] = useState("");
|
|
2916
|
+
useEffect(() => {
|
|
3047
2917
|
const run = async () => {
|
|
3048
2918
|
const projectDir = process.cwd();
|
|
3049
2919
|
const check = isExtensionProject(projectDir);
|
|
@@ -3066,64 +2936,52 @@ var AIScaffold = ({ version: version2 }) => {
|
|
|
3066
2936
|
};
|
|
3067
2937
|
run();
|
|
3068
2938
|
}, []);
|
|
3069
|
-
return /* @__PURE__ */
|
|
3070
|
-
/* @__PURE__ */
|
|
3071
|
-
/* @__PURE__ */
|
|
3072
|
-
state === "validating" && /* @__PURE__ */
|
|
3073
|
-
/* @__PURE__ */
|
|
3074
|
-
/* @__PURE__ */
|
|
2939
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
2940
|
+
/* @__PURE__ */ jsx(Banner, {}),
|
|
2941
|
+
/* @__PURE__ */ jsxs(StepShell, { title: "AI Editor Config", children: [
|
|
2942
|
+
state === "validating" && /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
2943
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: /* @__PURE__ */ jsx(Spinner5, { type: "dots" }) }),
|
|
2944
|
+
/* @__PURE__ */ jsx(Text, { children: "Checking project..." })
|
|
3075
2945
|
] }),
|
|
3076
|
-
state === "downloading" && /* @__PURE__ */
|
|
3077
|
-
/* @__PURE__ */
|
|
3078
|
-
/* @__PURE__ */
|
|
2946
|
+
state === "downloading" && /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
2947
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: /* @__PURE__ */ jsx(Spinner5, { type: "dots" }) }),
|
|
2948
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
3079
2949
|
"Downloading AI editor configs (",
|
|
3080
2950
|
version2,
|
|
3081
2951
|
")..."
|
|
3082
2952
|
] })
|
|
3083
2953
|
] }),
|
|
3084
|
-
state === "done" && /* @__PURE__ */
|
|
3085
|
-
/* @__PURE__ */
|
|
3086
|
-
/* @__PURE__ */
|
|
3087
|
-
/* @__PURE__ */
|
|
2954
|
+
state === "done" && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
2955
|
+
/* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
2956
|
+
/* @__PURE__ */ jsx(Text, { color: "green", bold: true, children: "\u2714" }),
|
|
2957
|
+
/* @__PURE__ */ jsxs(Text, { bold: true, children: [
|
|
3088
2958
|
"AI editor configs installed (",
|
|
3089
2959
|
files.length,
|
|
3090
2960
|
" files)"
|
|
3091
2961
|
] })
|
|
3092
2962
|
] }),
|
|
3093
|
-
/* @__PURE__ */
|
|
2963
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", marginLeft: 2, children: files.map((f) => /* @__PURE__ */ jsx(Text, { dimColor: true, children: f }, f)) })
|
|
3094
2964
|
] }),
|
|
3095
|
-
state === "error" && /* @__PURE__ */
|
|
3096
|
-
/* @__PURE__ */
|
|
3097
|
-
/* @__PURE__ */
|
|
2965
|
+
state === "error" && /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
2966
|
+
/* @__PURE__ */ jsx(Text, { color: "red", children: "\u2716" }),
|
|
2967
|
+
/* @__PURE__ */ jsx(Text, { children: errorMessage })
|
|
3098
2968
|
] })
|
|
3099
2969
|
] })
|
|
3100
2970
|
] });
|
|
3101
2971
|
};
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
import { createServer } from "http";
|
|
3105
|
-
import { Box as Box21, Text as Text21, useApp as useApp3 } from "ink";
|
|
3106
|
-
import Spinner6 from "ink-spinner";
|
|
3107
|
-
import open from "open";
|
|
3108
|
-
import { useState as useState16, useEffect as useEffect9 } from "react";
|
|
3109
|
-
|
|
3110
|
-
// src/lib/auth.ts
|
|
3111
|
-
import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir2, unlink } from "fs/promises";
|
|
3112
|
-
import { join as join5 } from "path";
|
|
3113
|
-
import { homedir } from "os";
|
|
3114
|
-
var AUTH_DIR = join5(homedir(), ".stackable");
|
|
3115
|
-
var AUTH_FILE = join5(AUTH_DIR, "auth.json");
|
|
2972
|
+
var AUTH_DIR = join(homedir(), ".stackable");
|
|
2973
|
+
var AUTH_FILE = join(AUTH_DIR, "auth.json");
|
|
3116
2974
|
var readAuthState = async () => {
|
|
3117
2975
|
try {
|
|
3118
|
-
const content = await
|
|
2976
|
+
const content = await readFile(AUTH_FILE, "utf8");
|
|
3119
2977
|
return JSON.parse(content);
|
|
3120
2978
|
} catch {
|
|
3121
2979
|
return null;
|
|
3122
2980
|
}
|
|
3123
2981
|
};
|
|
3124
2982
|
var writeAuthState = async (state) => {
|
|
3125
|
-
await
|
|
3126
|
-
await
|
|
2983
|
+
await mkdir(AUTH_DIR, { recursive: true, mode: 448 });
|
|
2984
|
+
await writeFile(AUTH_FILE, JSON.stringify(state, null, 2), { mode: 384 });
|
|
3127
2985
|
};
|
|
3128
2986
|
var clearAuthState = async () => {
|
|
3129
2987
|
try {
|
|
@@ -3156,9 +3014,6 @@ var getToken = async () => {
|
|
|
3156
3014
|
}
|
|
3157
3015
|
return state.token;
|
|
3158
3016
|
};
|
|
3159
|
-
|
|
3160
|
-
// src/components/AuthLogin.tsx
|
|
3161
|
-
import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
3162
3017
|
var LOGIN_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
3163
3018
|
var callbackPage = (heading, sub, redirectUrl) => `<!DOCTYPE html>
|
|
3164
3019
|
<html><head><meta charset="utf-8"><title>Stackable CLI</title>
|
|
@@ -3168,13 +3023,13 @@ var callbackPage = (heading, sub, redirectUrl) => `<!DOCTYPE html>
|
|
|
3168
3023
|
${redirectUrl ? `<script>(function(){var s=3,el=document.getElementById('h');function t(){if(s<=0){location.href='${redirectUrl}';return}el.textContent='Redirecting in '+s+'s\u2026';s--;setTimeout(t,1000)}t()})()</script>` : ""}
|
|
3169
3024
|
</body></html>`;
|
|
3170
3025
|
var AuthLogin = ({ dashboardUrl }) => {
|
|
3171
|
-
const { exit } =
|
|
3172
|
-
const [state, setState] =
|
|
3173
|
-
const [loginUrl, setLoginUrl] =
|
|
3174
|
-
const [userIdLabel, setUserIdLabel] =
|
|
3175
|
-
const [orgIdLabel, setOrgIdLabel] =
|
|
3176
|
-
const [errorMessage, setErrorMessage] =
|
|
3177
|
-
|
|
3026
|
+
const { exit } = useApp();
|
|
3027
|
+
const [state, setState] = useState("waiting");
|
|
3028
|
+
const [loginUrl, setLoginUrl] = useState("");
|
|
3029
|
+
const [userIdLabel, setUserIdLabel] = useState("");
|
|
3030
|
+
const [orgIdLabel, setOrgIdLabel] = useState("");
|
|
3031
|
+
const [errorMessage, setErrorMessage] = useState("");
|
|
3032
|
+
useEffect(() => {
|
|
3178
3033
|
let server;
|
|
3179
3034
|
let timeout;
|
|
3180
3035
|
const run = async () => {
|
|
@@ -3249,116 +3104,103 @@ var AuthLogin = ({ dashboardUrl }) => {
|
|
|
3249
3104
|
server?.close();
|
|
3250
3105
|
};
|
|
3251
3106
|
}, []);
|
|
3252
|
-
return /* @__PURE__ */
|
|
3253
|
-
/* @__PURE__ */
|
|
3254
|
-
/* @__PURE__ */
|
|
3255
|
-
state === "waiting" && /* @__PURE__ */
|
|
3256
|
-
/* @__PURE__ */
|
|
3257
|
-
/* @__PURE__ */
|
|
3258
|
-
/* @__PURE__ */
|
|
3107
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
3108
|
+
/* @__PURE__ */ jsx(Banner, {}),
|
|
3109
|
+
/* @__PURE__ */ jsxs(StepShell, { title: "Authenticate with Stackable", children: [
|
|
3110
|
+
state === "waiting" && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
3111
|
+
/* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
3112
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: /* @__PURE__ */ jsx(Spinner5, { type: "dots" }) }),
|
|
3113
|
+
/* @__PURE__ */ jsx(Text, { children: "Waiting for browser authentication..." })
|
|
3259
3114
|
] }),
|
|
3260
|
-
loginUrl && /* @__PURE__ */
|
|
3115
|
+
loginUrl && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
3261
3116
|
" ",
|
|
3262
3117
|
loginUrl
|
|
3263
3118
|
] })
|
|
3264
3119
|
] }),
|
|
3265
|
-
state === "success" && /* @__PURE__ */
|
|
3266
|
-
/* @__PURE__ */
|
|
3267
|
-
/* @__PURE__ */
|
|
3268
|
-
/* @__PURE__ */
|
|
3269
|
-
/* @__PURE__ */
|
|
3120
|
+
state === "success" && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
3121
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
3122
|
+
/* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
3123
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "User:" }),
|
|
3124
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: userIdLabel })
|
|
3270
3125
|
] }),
|
|
3271
|
-
/* @__PURE__ */
|
|
3272
|
-
/* @__PURE__ */
|
|
3273
|
-
/* @__PURE__ */
|
|
3126
|
+
/* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
3127
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Org: " }),
|
|
3128
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: orgIdLabel })
|
|
3274
3129
|
] })
|
|
3275
3130
|
] }),
|
|
3276
|
-
/* @__PURE__ */
|
|
3277
|
-
/* @__PURE__ */
|
|
3278
|
-
/* @__PURE__ */
|
|
3131
|
+
/* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
3132
|
+
/* @__PURE__ */ jsx(Text, { color: "green", bold: true, children: "\u2714" }),
|
|
3133
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Authenticated" })
|
|
3279
3134
|
] })
|
|
3280
3135
|
] }),
|
|
3281
|
-
state === "error" && /* @__PURE__ */
|
|
3282
|
-
/* @__PURE__ */
|
|
3283
|
-
/* @__PURE__ */
|
|
3136
|
+
state === "error" && /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
3137
|
+
/* @__PURE__ */ jsx(Text, { color: "red", children: "\u2716" }),
|
|
3138
|
+
/* @__PURE__ */ jsx(Text, { children: errorMessage })
|
|
3284
3139
|
] })
|
|
3285
3140
|
] })
|
|
3286
3141
|
] });
|
|
3287
3142
|
};
|
|
3288
|
-
|
|
3289
|
-
// src/components/AuthLogout.tsx
|
|
3290
|
-
import { useEffect as useEffect10 } from "react";
|
|
3291
|
-
import { Box as Box22, Text as Text22, useApp as useApp4 } from "ink";
|
|
3292
|
-
import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
3293
3143
|
var AuthLogout = () => {
|
|
3294
|
-
const { exit } =
|
|
3295
|
-
|
|
3144
|
+
const { exit } = useApp();
|
|
3145
|
+
useEffect(() => {
|
|
3296
3146
|
exit();
|
|
3297
3147
|
}, [exit]);
|
|
3298
|
-
return /* @__PURE__ */
|
|
3299
|
-
/* @__PURE__ */
|
|
3300
|
-
/* @__PURE__ */
|
|
3301
|
-
/* @__PURE__ */
|
|
3302
|
-
/* @__PURE__ */
|
|
3148
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
3149
|
+
/* @__PURE__ */ jsx(Banner, {}),
|
|
3150
|
+
/* @__PURE__ */ jsx(StepShell, { title: "Authenticate with Stackable", children: /* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
3151
|
+
/* @__PURE__ */ jsx(Text, { color: "green", bold: true, children: "\u2714" }),
|
|
3152
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Logged out" })
|
|
3303
3153
|
] }) })
|
|
3304
3154
|
] });
|
|
3305
3155
|
};
|
|
3306
|
-
|
|
3307
|
-
// src/components/AuthStatus.tsx
|
|
3308
|
-
import { useEffect as useEffect11 } from "react";
|
|
3309
|
-
import { useApp as useApp5, Box as Box23, Text as Text23 } from "ink";
|
|
3310
|
-
import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
3311
3156
|
var AuthStatus = ({ state, userId, orgId, expiry }) => {
|
|
3312
|
-
const { exit } =
|
|
3313
|
-
|
|
3157
|
+
const { exit } = useApp();
|
|
3158
|
+
useEffect(() => {
|
|
3314
3159
|
exit();
|
|
3315
3160
|
}, [exit]);
|
|
3316
|
-
return /* @__PURE__ */
|
|
3317
|
-
/* @__PURE__ */
|
|
3318
|
-
/* @__PURE__ */
|
|
3319
|
-
state === "authenticated" && /* @__PURE__ */
|
|
3320
|
-
/* @__PURE__ */
|
|
3321
|
-
/* @__PURE__ */
|
|
3322
|
-
/* @__PURE__ */
|
|
3323
|
-
/* @__PURE__ */
|
|
3161
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
3162
|
+
/* @__PURE__ */ jsx(Banner, {}),
|
|
3163
|
+
/* @__PURE__ */ jsxs(StepShell, { title: "Authenticate with Stackable", children: [
|
|
3164
|
+
state === "authenticated" && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
3165
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
3166
|
+
/* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
3167
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "User:" }),
|
|
3168
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: userId })
|
|
3324
3169
|
] }),
|
|
3325
|
-
/* @__PURE__ */
|
|
3326
|
-
/* @__PURE__ */
|
|
3327
|
-
/* @__PURE__ */
|
|
3170
|
+
/* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
3171
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Org: " }),
|
|
3172
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: orgId })
|
|
3328
3173
|
] }),
|
|
3329
|
-
expiry && /* @__PURE__ */
|
|
3330
|
-
/* @__PURE__ */
|
|
3331
|
-
/* @__PURE__ */
|
|
3174
|
+
expiry && /* @__PURE__ */ jsxs(Box, { gap: 2, children: [
|
|
3175
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Exp: " }),
|
|
3176
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: expiry.toLocaleDateString() })
|
|
3332
3177
|
] })
|
|
3333
3178
|
] }),
|
|
3334
|
-
/* @__PURE__ */
|
|
3335
|
-
/* @__PURE__ */
|
|
3336
|
-
/* @__PURE__ */
|
|
3179
|
+
/* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
3180
|
+
/* @__PURE__ */ jsx(Text, { color: "green", bold: true, children: "\u2714" }),
|
|
3181
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Authenticated" })
|
|
3337
3182
|
] })
|
|
3338
3183
|
] }),
|
|
3339
|
-
state === "expired" && /* @__PURE__ */
|
|
3340
|
-
/* @__PURE__ */
|
|
3341
|
-
/* @__PURE__ */
|
|
3342
|
-
/* @__PURE__ */
|
|
3184
|
+
state === "expired" && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
3185
|
+
/* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
3186
|
+
/* @__PURE__ */ jsx(Text, { color: "red", children: "\u2716" }),
|
|
3187
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
3343
3188
|
"Session expired",
|
|
3344
3189
|
expiry ? ` (${expiry.toLocaleDateString()})` : ""
|
|
3345
3190
|
] })
|
|
3346
3191
|
] }),
|
|
3347
|
-
/* @__PURE__ */
|
|
3192
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Run `stackable-app-extension auth login` to re-authenticate." })
|
|
3348
3193
|
] }),
|
|
3349
|
-
state === "not-logged-in" && /* @__PURE__ */
|
|
3350
|
-
/* @__PURE__ */
|
|
3351
|
-
/* @__PURE__ */
|
|
3352
|
-
/* @__PURE__ */
|
|
3194
|
+
state === "not-logged-in" && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
3195
|
+
/* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
3196
|
+
/* @__PURE__ */ jsx(Text, { color: "red", children: "\u2716" }),
|
|
3197
|
+
/* @__PURE__ */ jsx(Text, { children: "Not logged in" })
|
|
3353
3198
|
] }),
|
|
3354
|
-
/* @__PURE__ */
|
|
3199
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Run `stackable-app-extension auth login`" })
|
|
3355
3200
|
] })
|
|
3356
3201
|
] })
|
|
3357
3202
|
] });
|
|
3358
3203
|
};
|
|
3359
|
-
|
|
3360
|
-
// src/lib/versionCheck.ts
|
|
3361
|
-
import https from "https";
|
|
3362
3204
|
var PACKAGE_NAME = "@stackable-labs/cli-app-extension";
|
|
3363
3205
|
var REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
|
|
3364
3206
|
var TIMEOUT_MS = 3e3;
|
|
@@ -3403,9 +3245,6 @@ var checkForUpdate = (currentVersion) => {
|
|
|
3403
3245
|
} catch {
|
|
3404
3246
|
}
|
|
3405
3247
|
};
|
|
3406
|
-
|
|
3407
|
-
// src/index.tsx
|
|
3408
|
-
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
3409
3248
|
var require2 = createRequire(import.meta.url);
|
|
3410
3249
|
var { version } = require2("../package.json");
|
|
3411
3250
|
checkForUpdate(version);
|
|
@@ -3418,7 +3257,7 @@ var ensureToken = async () => {
|
|
|
3418
3257
|
const message = err instanceof Error ? err.message : String(err);
|
|
3419
3258
|
const isExpired = message.toLowerCase().includes("expired");
|
|
3420
3259
|
render(
|
|
3421
|
-
/* @__PURE__ */
|
|
3260
|
+
/* @__PURE__ */ jsx(AuthStatus, { state: isExpired ? "expired" : "not-logged-in" })
|
|
3422
3261
|
);
|
|
3423
3262
|
return null;
|
|
3424
3263
|
}
|
|
@@ -3431,7 +3270,7 @@ program.command("create" /* CREATE */).description("Create a new Extension proje
|
|
|
3431
3270
|
}
|
|
3432
3271
|
const { token, userId, orgId } = auth2;
|
|
3433
3272
|
render(
|
|
3434
|
-
/* @__PURE__ */
|
|
3273
|
+
/* @__PURE__ */ jsx(
|
|
3435
3274
|
App,
|
|
3436
3275
|
{
|
|
3437
3276
|
command: "create" /* CREATE */,
|
|
@@ -3451,7 +3290,7 @@ program.command("scaffold" /* SCAFFOLD */).description("Scaffold a local project
|
|
|
3451
3290
|
}
|
|
3452
3291
|
const { token, userId, orgId } = auth2;
|
|
3453
3292
|
render(
|
|
3454
|
-
/* @__PURE__ */
|
|
3293
|
+
/* @__PURE__ */ jsx(
|
|
3455
3294
|
App,
|
|
3456
3295
|
{
|
|
3457
3296
|
command: "scaffold" /* SCAFFOLD */,
|
|
@@ -3471,7 +3310,7 @@ program.command("update" /* UPDATE */).description("Update an existing Extension
|
|
|
3471
3310
|
}
|
|
3472
3311
|
const { token, userId, orgId } = auth2;
|
|
3473
3312
|
render(
|
|
3474
|
-
/* @__PURE__ */
|
|
3313
|
+
/* @__PURE__ */ jsx(
|
|
3475
3314
|
App,
|
|
3476
3315
|
{
|
|
3477
3316
|
command: "update" /* UPDATE */,
|
|
@@ -3491,7 +3330,7 @@ program.command("dev" /* DEV */).description("Start dev servers with a public tu
|
|
|
3491
3330
|
}
|
|
3492
3331
|
const { token, userId, orgId } = auth2;
|
|
3493
3332
|
render(
|
|
3494
|
-
/* @__PURE__ */
|
|
3333
|
+
/* @__PURE__ */ jsx(
|
|
3495
3334
|
DevApp,
|
|
3496
3335
|
{
|
|
3497
3336
|
options,
|
|
@@ -3506,17 +3345,17 @@ program.command("dev" /* DEV */).description("Start dev servers with a public tu
|
|
|
3506
3345
|
var DASHBOARD_URL = process.env.ADMIN_DASHBOARD_URL ?? "https://admin.stackablelabs.io";
|
|
3507
3346
|
var auth = program.command("auth").description("Manage CLI authentication");
|
|
3508
3347
|
auth.command("login").description("Authenticate with Stackable via browser").action(async () => {
|
|
3509
|
-
render(/* @__PURE__ */
|
|
3348
|
+
render(/* @__PURE__ */ jsx(AuthLogin, { dashboardUrl: DASHBOARD_URL }));
|
|
3510
3349
|
});
|
|
3511
3350
|
auth.command("logout").description("Clear stored CLI credentials").action(async () => {
|
|
3512
3351
|
await clearAuthState();
|
|
3513
|
-
render(/* @__PURE__ */
|
|
3352
|
+
render(/* @__PURE__ */ jsx(AuthLogout, {}));
|
|
3514
3353
|
});
|
|
3515
3354
|
auth.command("status").description("Show current authentication status").action(async () => {
|
|
3516
3355
|
const state = await readAuthState();
|
|
3517
3356
|
if (!state) {
|
|
3518
3357
|
render(
|
|
3519
|
-
/* @__PURE__ */
|
|
3358
|
+
/* @__PURE__ */ jsx(AuthStatus, { state: "not-logged-in" })
|
|
3520
3359
|
);
|
|
3521
3360
|
return;
|
|
3522
3361
|
}
|
|
@@ -3524,11 +3363,11 @@ auth.command("status").description("Show current authentication status").action(
|
|
|
3524
3363
|
const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
|
|
3525
3364
|
const expiry = payload.exp ? new Date(payload.exp * 1e3) : null;
|
|
3526
3365
|
if (expiry && Date.now() >= expiry.getTime()) {
|
|
3527
|
-
render(/* @__PURE__ */
|
|
3366
|
+
render(/* @__PURE__ */ jsx(AuthStatus, { state: "expired", expiry }));
|
|
3528
3367
|
return;
|
|
3529
3368
|
}
|
|
3530
3369
|
render(
|
|
3531
|
-
/* @__PURE__ */
|
|
3370
|
+
/* @__PURE__ */ jsx(
|
|
3532
3371
|
AuthStatus,
|
|
3533
3372
|
{
|
|
3534
3373
|
state: "authenticated",
|
|
@@ -3541,6 +3380,6 @@ auth.command("status").description("Show current authentication status").action(
|
|
|
3541
3380
|
});
|
|
3542
3381
|
var ai = program.command("ai").description("AI editor configuration tools");
|
|
3543
3382
|
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) => {
|
|
3544
|
-
render(/* @__PURE__ */
|
|
3383
|
+
render(/* @__PURE__ */ jsx(AIScaffold, { version: options.version }));
|
|
3545
3384
|
});
|
|
3546
3385
|
program.parse(process.argv.filter((arg) => arg !== "--"));
|