@contentful/experience-design-system-cli 2.36.2-dev-build-4bcc1e36.0 → 2.36.2-dev-build-a6f80ae6.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/app.js +375 -716
- package/dist/index.js +391 -851
- package/dist/package.json +1 -2
- package/dist/src/tui/import/spawn-v1-import.d.ts +0 -1
- package/dist/src/tui/settings/contentful-configuration/config-store.d.ts +0 -2
- package/dist/src/tui/settings/utils/v1-store.d.ts +2 -3
- package/legacy/dist/src/analyze/select/tui/theme.d.ts +0 -3
- package/legacy/dist/src/import/tui/steps/DoneStep.d.ts +1 -1
- package/legacy/dist/src/import/tui/steps/RunningStep.d.ts +1 -9
- package/legacy/dist/src/index.js +7618 -8648
- package/legacy/dist/src/runs/store.d.ts +2 -2
- package/legacy/dist/src/tui/use-timed-spinner.d.ts +2 -1
- package/legacy/package.json +1 -2
- package/package.json +2 -3
- package/dist/src/config/migrate.d.ts +0 -1
- package/dist/src/tui/control-hints.d.ts +0 -7
- package/dist/src/tui/import/steps/01-welcome/controls.d.ts +0 -8
- package/dist/src/tui/import/steps/01-welcome/logic.d.ts +0 -8
- package/dist/src/tui/import/steps/01-welcome/screen.d.ts +0 -8
- package/dist/src/tui/import/steps/02-token-input/controls.d.ts +0 -11
- package/dist/src/tui/import/steps/02-token-input/logic.d.ts +0 -9
- package/dist/src/tui/import/steps/02-token-input/screen.d.ts +0 -9
- package/dist/src/tui/import/steps/02-token-input/validate-path.d.ts +0 -12
- package/dist/src/tui/import/steps/index.d.ts +0 -2
package/dist/app.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// packages/experience-design-system-cli/app.tsx
|
|
2
|
-
import {
|
|
2
|
+
import { useState as useState8 } from "react";
|
|
3
3
|
|
|
4
4
|
// packages/experience-design-system-cli/src/tui/home/home.tsx
|
|
5
5
|
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
6
|
-
import { Box, Text
|
|
6
|
+
import { Box, Text, useApp, useInput } from "ink";
|
|
7
7
|
|
|
8
8
|
// packages/experience-design-system-cli/src/tui/home/home.theme.ts
|
|
9
9
|
var BRAND = {
|
|
@@ -117,15 +117,8 @@ function useTerminalWidth() {
|
|
|
117
117
|
return columns;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
// packages/experience-design-system-cli/src/tui/control-hints.tsx
|
|
121
|
-
import { Text } from "ink";
|
|
122
|
-
import { jsx } from "react/jsx-runtime";
|
|
123
|
-
function ControlHints({ hints }) {
|
|
124
|
-
return /* @__PURE__ */ jsx(Text, { color: PALETTE.muted, children: hints.map((hint) => `${hint.keys} ${hint.label}`).join(" \xB7 ") });
|
|
125
|
-
}
|
|
126
|
-
|
|
127
120
|
// packages/experience-design-system-cli/src/tui/home/home.tsx
|
|
128
|
-
import { jsx
|
|
121
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
129
122
|
var VERSION = readPackageVersion();
|
|
130
123
|
var HEADING = "Contentful Experiences";
|
|
131
124
|
var SUBTITLE = "Let's import your design system into Contentful";
|
|
@@ -178,27 +171,27 @@ function HomeScreen({ onNavigate }) {
|
|
|
178
171
|
});
|
|
179
172
|
if (tooNarrow) {
|
|
180
173
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
|
|
181
|
-
/* @__PURE__ */
|
|
182
|
-
/* @__PURE__ */
|
|
174
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: PALETTE.warning, children: "Terminal too small" }),
|
|
175
|
+
/* @__PURE__ */ jsx(Text, { color: PALETTE.muted, children: "Press q to quit, make your terminal full screen, then run experiences import again." })
|
|
183
176
|
] });
|
|
184
177
|
}
|
|
185
178
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
|
|
186
179
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", alignItems: "center", children: [
|
|
187
|
-
/* @__PURE__ */
|
|
188
|
-
/* @__PURE__ */
|
|
189
|
-
/* @__PURE__ */
|
|
190
|
-
/* @__PURE__ */ jsxs(
|
|
180
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: PALETTE.heading, children: HEADING }),
|
|
181
|
+
/* @__PURE__ */ jsx(Text, { children: brandBar(HEADING.length).map((segment, i) => /* @__PURE__ */ jsx(Text, { color: segment.color, children: segment.text }, i)) }),
|
|
182
|
+
/* @__PURE__ */ jsx(Text, { color: PALETTE.muted, children: SUBTITLE }),
|
|
183
|
+
/* @__PURE__ */ jsxs(Text, { color: PALETTE.muted, children: [
|
|
191
184
|
"v",
|
|
192
185
|
VERSION
|
|
193
186
|
] })
|
|
194
187
|
] }),
|
|
195
|
-
/* @__PURE__ */
|
|
188
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, justifyContent: "center", children: /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: START_ITEMS.map((item, i) => {
|
|
196
189
|
const focused = i === focusIdx;
|
|
197
190
|
const isUpgradeItem = item.screen === "upgrade";
|
|
198
191
|
const display = isUpgradeItem ? upgradeItemDisplay(upgradeCheck) : { label: item.label };
|
|
199
192
|
const dimmed = isUpgradeItem && upgradeDisabled;
|
|
200
193
|
return /* @__PURE__ */ jsxs(
|
|
201
|
-
|
|
194
|
+
Text,
|
|
202
195
|
{
|
|
203
196
|
bold: focused && !dimmed,
|
|
204
197
|
dimColor: dimmed,
|
|
@@ -211,22 +204,13 @@ function HomeScreen({ onNavigate }) {
|
|
|
211
204
|
item.label
|
|
212
205
|
);
|
|
213
206
|
}) }) }),
|
|
214
|
-
/* @__PURE__ */
|
|
215
|
-
ControlHints,
|
|
216
|
-
{
|
|
217
|
-
hints: [
|
|
218
|
-
{ keys: "\u2191/\u2193", label: "move" },
|
|
219
|
-
{ keys: "\u23CE", label: "select" },
|
|
220
|
-
{ keys: "q", label: "quit" }
|
|
221
|
-
]
|
|
222
|
-
}
|
|
223
|
-
) })
|
|
207
|
+
/* @__PURE__ */ jsx(Box, { marginTop: 1, justifyContent: "center", children: /* @__PURE__ */ jsx(Text, { color: PALETTE.muted, children: "\u2191/\u2193 move \xB7 \u23CE select \xB7 q quit" }) })
|
|
224
208
|
] });
|
|
225
209
|
}
|
|
226
210
|
|
|
227
211
|
// packages/experience-design-system-cli/src/tui/import/PageContainer.tsx
|
|
228
|
-
import { Box as Box2, Text as
|
|
229
|
-
import { jsx as
|
|
212
|
+
import { Box as Box2, Text as Text2, useInput as useInput2 } from "ink";
|
|
213
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
230
214
|
function ImportScreen({ exitCode, onDone }) {
|
|
231
215
|
useInput2((input, key) => {
|
|
232
216
|
if (key.return || key.escape || input === "q") {
|
|
@@ -235,210 +219,14 @@ function ImportScreen({ exitCode, onDone }) {
|
|
|
235
219
|
});
|
|
236
220
|
const isSuccess = exitCode === 0;
|
|
237
221
|
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
|
|
238
|
-
/* @__PURE__ */
|
|
239
|
-
/* @__PURE__ */
|
|
240
|
-
isSuccess ? /* @__PURE__ */
|
|
222
|
+
/* @__PURE__ */ jsx2(Text2, { bold: true, children: "Import" }),
|
|
223
|
+
/* @__PURE__ */ jsx2(Text2, { children: " " }),
|
|
224
|
+
isSuccess ? /* @__PURE__ */ jsx2(Text2, { color: PALETTE.success, children: "\u2713 Import complete" }) : /* @__PURE__ */ jsxs2(Text2, { color: PALETTE.error, children: [
|
|
241
225
|
"\u2717 Import failed: process exited with code ",
|
|
242
226
|
exitCode ?? "unknown"
|
|
243
227
|
] }),
|
|
244
|
-
/* @__PURE__ */
|
|
245
|
-
/* @__PURE__ */
|
|
246
|
-
] });
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// packages/experience-design-system-cli/src/tui/import/steps/01-welcome/screen.tsx
|
|
250
|
-
import { useState as useState3 } from "react";
|
|
251
|
-
import { Box as Box3, Text as Text4 } from "ink";
|
|
252
|
-
import TextInput from "ink-text-input";
|
|
253
|
-
|
|
254
|
-
// packages/experience-design-system-cli/src/tui/import/steps/01-welcome/controls.ts
|
|
255
|
-
import { useInput as useInput3 } from "ink";
|
|
256
|
-
|
|
257
|
-
// packages/experience-design-system-cli/src/tui/import/steps/01-welcome/logic.ts
|
|
258
|
-
function shouldQuit(value, input, key) {
|
|
259
|
-
if (key.escape) return true;
|
|
260
|
-
return value === "" && input === "q" && !key.ctrl && !key.meta;
|
|
261
|
-
}
|
|
262
|
-
function toProjectPath(value) {
|
|
263
|
-
const projectPath = value.trim();
|
|
264
|
-
return projectPath === "" ? null : projectPath;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// packages/experience-design-system-cli/src/tui/import/steps/01-welcome/controls.ts
|
|
268
|
-
var WELCOME_CONTROLS = [
|
|
269
|
-
{ keys: "Enter", label: "Continue" },
|
|
270
|
-
{ keys: "Esc/q", label: "Back to menu" }
|
|
271
|
-
];
|
|
272
|
-
function useWelcomeControls(projectPath, onQuit) {
|
|
273
|
-
useInput3((input, key) => {
|
|
274
|
-
if (shouldQuit(projectPath, input, key)) onQuit();
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// packages/experience-design-system-cli/src/tui/import/steps/01-welcome/screen.tsx
|
|
279
|
-
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
280
|
-
var RULE = "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500";
|
|
281
|
-
var OVERVIEW = [
|
|
282
|
-
{ label: "Step 1", description: "Extract components from your codebase" },
|
|
283
|
-
{ label: "Step 2", description: "Review what was extracted" },
|
|
284
|
-
{ label: "Step 3", description: "Generate CDF definitions with Claude" },
|
|
285
|
-
{ label: "Step 4", description: "Review generated definitions" },
|
|
286
|
-
{ label: "Step 5", description: "Push to Contentful" }
|
|
287
|
-
];
|
|
288
|
-
function WelcomeScreen({ onContinue, onQuit, initialPath = "" }) {
|
|
289
|
-
const [projectPath, setProjectPath] = useState3(initialPath);
|
|
290
|
-
useWelcomeControls(projectPath, onQuit);
|
|
291
|
-
const submit = (value) => {
|
|
292
|
-
const path = toProjectPath(value);
|
|
293
|
-
if (path) onContinue(path);
|
|
294
|
-
};
|
|
295
|
-
return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", gap: 1, paddingX: 2, paddingY: 1, children: [
|
|
296
|
-
/* @__PURE__ */ jsx4(Text4, { bold: true, color: PALETTE.success, children: "\u{1F44B} Hey! Let's import your design system into Contentful." }),
|
|
297
|
-
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "I'll walk you through 5 steps to get your components into Contentful ExO." }),
|
|
298
|
-
/* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", marginTop: 1, children: [
|
|
299
|
-
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: RULE }),
|
|
300
|
-
OVERVIEW.map((item) => /* @__PURE__ */ jsxs3(Box3, { gap: 1, children: [
|
|
301
|
-
/* @__PURE__ */ jsx4(Text4, { bold: true, children: item.label }),
|
|
302
|
-
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: item.description })
|
|
303
|
-
] }, item.label)),
|
|
304
|
-
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: RULE })
|
|
305
|
-
] }),
|
|
306
|
-
/* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", marginTop: 1, children: [
|
|
307
|
-
/* @__PURE__ */ jsx4(Text4, { children: "Where is your component library?" }),
|
|
308
|
-
/* @__PURE__ */ jsxs3(Box3, { gap: 1, children: [
|
|
309
|
-
/* @__PURE__ */ jsx4(Text4, { color: PALETTE.accent, children: "?" }),
|
|
310
|
-
/* @__PURE__ */ jsx4(Text4, { children: "Project path:" }),
|
|
311
|
-
/* @__PURE__ */ jsx4(TextInput, { value: projectPath, onChange: setProjectPath, onSubmit: submit })
|
|
312
|
-
] })
|
|
313
|
-
] }),
|
|
314
|
-
/* @__PURE__ */ jsx4(Box3, { marginTop: 1, gap: 3, children: WELCOME_CONTROLS.map((control) => /* @__PURE__ */ jsxs3(Text4, { dimColor: true, children: [
|
|
315
|
-
"[",
|
|
316
|
-
control.keys,
|
|
317
|
-
"] ",
|
|
318
|
-
control.label
|
|
319
|
-
] }, control.keys)) })
|
|
320
|
-
] });
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// packages/experience-design-system-cli/src/tui/import/steps/02-token-input/screen.tsx
|
|
324
|
-
import { useState as useState4 } from "react";
|
|
325
|
-
import { Box as Box4, Text as Text5 } from "ink";
|
|
326
|
-
import TextInput2 from "ink-text-input";
|
|
327
|
-
|
|
328
|
-
// packages/experience-design-system-cli/src/tui/import/steps/02-token-input/controls.ts
|
|
329
|
-
import { useInput as useInput4 } from "ink";
|
|
330
|
-
|
|
331
|
-
// packages/experience-design-system-cli/src/tui/import/steps/02-token-input/logic.ts
|
|
332
|
-
function isPlainKeyOnEmptyField(value, input, key, expected) {
|
|
333
|
-
return value === "" && input === expected && !key.ctrl && !key.meta;
|
|
334
|
-
}
|
|
335
|
-
function shouldGoBack(value, input, key) {
|
|
336
|
-
return key.escape || isPlainKeyOnEmptyField(value, input, key, "q");
|
|
337
|
-
}
|
|
338
|
-
function shouldSkip(value, input, key) {
|
|
339
|
-
return isPlainKeyOnEmptyField(value, input, key, "s");
|
|
340
|
-
}
|
|
341
|
-
function toTokenPath(value) {
|
|
342
|
-
const tokenPath = value.trim();
|
|
343
|
-
return tokenPath === "" ? null : tokenPath;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
// packages/experience-design-system-cli/src/tui/import/steps/02-token-input/controls.ts
|
|
347
|
-
var TOKEN_INPUT_CONTROLS = [
|
|
348
|
-
{ keys: "Enter", label: "Continue (skips if empty)" },
|
|
349
|
-
{ keys: "s", label: "Skip" },
|
|
350
|
-
{ keys: "Esc/q", label: "Back" }
|
|
351
|
-
];
|
|
352
|
-
function useTokenInputControls(tokenPath, onSkip, onBack) {
|
|
353
|
-
useInput4((input, key) => {
|
|
354
|
-
if (shouldGoBack(tokenPath, input, key)) onBack();
|
|
355
|
-
else if (shouldSkip(tokenPath, input, key)) onSkip();
|
|
356
|
-
});
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
// packages/experience-design-system-cli/src/tui/import/steps/02-token-input/validate-path.ts
|
|
360
|
-
import { statSync } from "node:fs";
|
|
361
|
-
import { homedir } from "node:os";
|
|
362
|
-
import { resolve } from "node:path";
|
|
363
|
-
function stripQuotes(value) {
|
|
364
|
-
const quoted = value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'");
|
|
365
|
-
return value.length >= 2 && quoted ? value.slice(1, -1) : value;
|
|
366
|
-
}
|
|
367
|
-
function expandHome(value) {
|
|
368
|
-
return value === "~" || value.startsWith("~/") || value.startsWith("~\\") ? homedir() + value.slice(1) : value;
|
|
369
|
-
}
|
|
370
|
-
function validateTokenPath(rawPath) {
|
|
371
|
-
const path = resolve(expandHome(stripQuotes(rawPath.trim())));
|
|
372
|
-
let stats;
|
|
373
|
-
try {
|
|
374
|
-
stats = statSync(path);
|
|
375
|
-
} catch {
|
|
376
|
-
return { ok: false, error: `Path not found: ${path}`, resolvedPath: path };
|
|
377
|
-
}
|
|
378
|
-
if (stats.isDirectory()) {
|
|
379
|
-
return {
|
|
380
|
-
ok: false,
|
|
381
|
-
error: "That's a directory \u2014 provide a path to a token file (e.g. tokens.json), not a folder.",
|
|
382
|
-
resolvedPath: path
|
|
383
|
-
};
|
|
384
|
-
}
|
|
385
|
-
if (!stats.isFile()) {
|
|
386
|
-
return { ok: false, error: `Not a regular file: ${path}`, resolvedPath: path };
|
|
387
|
-
}
|
|
388
|
-
return { ok: true, path };
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// packages/experience-design-system-cli/src/tui/import/steps/02-token-input/screen.tsx
|
|
392
|
-
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
393
|
-
function TokenInputScreen({
|
|
394
|
-
onConfirm,
|
|
395
|
-
onSkip,
|
|
396
|
-
onBack,
|
|
397
|
-
initialPath = ""
|
|
398
|
-
}) {
|
|
399
|
-
const [tokenPath, setTokenPath] = useState4(initialPath);
|
|
400
|
-
const [failure, setFailure] = useState4(null);
|
|
401
|
-
useTokenInputControls(tokenPath, onSkip, onBack);
|
|
402
|
-
const change = (value) => {
|
|
403
|
-
setTokenPath(value);
|
|
404
|
-
setFailure(null);
|
|
405
|
-
};
|
|
406
|
-
const submit = (value) => {
|
|
407
|
-
const rawPath = toTokenPath(value);
|
|
408
|
-
if (!rawPath) {
|
|
409
|
-
onSkip();
|
|
410
|
-
return;
|
|
411
|
-
}
|
|
412
|
-
const check = validateTokenPath(rawPath);
|
|
413
|
-
if (check.ok) onConfirm(check.path);
|
|
414
|
-
else setFailure({ error: check.error, resolvedPath: check.resolvedPath });
|
|
415
|
-
};
|
|
416
|
-
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", gap: 1, paddingX: 2, paddingY: 1, children: [
|
|
417
|
-
/* @__PURE__ */ jsx5(Text5, { bold: true, children: "Design tokens" }),
|
|
418
|
-
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "Point me to your raw token file (e.g. ~/design-tokens/tokens.json). You can use ~, relative, or absolute paths. Claude will map it to DTCG format." }),
|
|
419
|
-
/* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
420
|
-
/* @__PURE__ */ jsxs4(Box4, { gap: 1, children: [
|
|
421
|
-
/* @__PURE__ */ jsx5(Text5, { color: PALETTE.accent, children: "?" }),
|
|
422
|
-
/* @__PURE__ */ jsx5(Text5, { children: "Token path:" }),
|
|
423
|
-
/* @__PURE__ */ jsx5(TextInput2, { value: tokenPath, onChange: change, onSubmit: submit })
|
|
424
|
-
] }),
|
|
425
|
-
failure && /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
|
|
426
|
-
/* @__PURE__ */ jsxs4(Text5, { color: PALETTE.error, children: [
|
|
427
|
-
"\u2717 ",
|
|
428
|
-
failure.error
|
|
429
|
-
] }),
|
|
430
|
-
/* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
|
|
431
|
-
" Resolved to: ",
|
|
432
|
-
failure.resolvedPath
|
|
433
|
-
] })
|
|
434
|
-
] })
|
|
435
|
-
] }),
|
|
436
|
-
/* @__PURE__ */ jsx5(Box4, { marginTop: 1, gap: 3, children: TOKEN_INPUT_CONTROLS.map((control) => /* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
|
|
437
|
-
"[",
|
|
438
|
-
control.keys,
|
|
439
|
-
"] ",
|
|
440
|
-
control.label
|
|
441
|
-
] }, control.keys)) })
|
|
228
|
+
/* @__PURE__ */ jsx2(Text2, { children: " " }),
|
|
229
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "[Enter] Back to Start" })
|
|
442
230
|
] });
|
|
443
231
|
}
|
|
444
232
|
|
|
@@ -469,9 +257,6 @@ function buildArgs(options) {
|
|
|
469
257
|
if (options.project) {
|
|
470
258
|
args.push("--project", options.project);
|
|
471
259
|
}
|
|
472
|
-
if (options.tokens) {
|
|
473
|
-
args.push("--tokens", options.tokens);
|
|
474
|
-
}
|
|
475
260
|
return args;
|
|
476
261
|
}
|
|
477
262
|
async function spawnV1Import(options = {}) {
|
|
@@ -495,7 +280,7 @@ function getTerminalHandle() {
|
|
|
495
280
|
return process.stdin._handle;
|
|
496
281
|
}
|
|
497
282
|
async function stopReadingTerminal() {
|
|
498
|
-
await new Promise((
|
|
283
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
499
284
|
const handle = getTerminalHandle();
|
|
500
285
|
if (!handle?.readStop) return;
|
|
501
286
|
handle.reading = false;
|
|
@@ -509,243 +294,43 @@ function startReadingTerminal() {
|
|
|
509
294
|
}
|
|
510
295
|
|
|
511
296
|
// packages/experience-design-system-cli/src/tui/help/PageContainer.tsx
|
|
512
|
-
import {
|
|
513
|
-
import {
|
|
514
|
-
|
|
515
|
-
// packages/experience-design-system-cli/src/tui/debug-store.ts
|
|
516
|
-
import { mkdir as mkdir2, writeFile as writeFile2 } from "node:fs/promises";
|
|
517
|
-
import { existsSync as existsSync3, readdirSync } from "node:fs";
|
|
518
|
-
import { join as join5 } from "node:path";
|
|
519
|
-
|
|
520
|
-
// packages/experience-design-system-types/dist/src/config/index.js
|
|
521
|
-
import { randomBytes } from "node:crypto";
|
|
522
|
-
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
523
|
-
import { homedir as homedir2 } from "node:os";
|
|
524
|
-
import { dirname as dirname2, join as join4 } from "node:path";
|
|
525
|
-
function configRoot() {
|
|
526
|
-
return process.env["EDS_HOME"] || join4(homedir2(), ".contentful", "experience-design-system-cli");
|
|
527
|
-
}
|
|
528
|
-
var configFilePath = () => join4(configRoot(), "config.json");
|
|
529
|
-
var debugSessionsDir = () => join4(configRoot(), "debug", "sessions");
|
|
530
|
-
async function readSettings() {
|
|
531
|
-
try {
|
|
532
|
-
return JSON.parse(await readFile(configFilePath(), "utf8"));
|
|
533
|
-
} catch {
|
|
534
|
-
return {};
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
async function writeSettings(settings) {
|
|
538
|
-
const path = configFilePath();
|
|
539
|
-
await mkdir(dirname2(path), { recursive: true });
|
|
540
|
-
const tmp = `${path}.${process.pid}.${randomBytes(4).toString("hex")}.tmp`;
|
|
541
|
-
await writeFile(tmp, `${JSON.stringify(settings, null, 2)}
|
|
542
|
-
`, { mode: 384 });
|
|
543
|
-
await rename(tmp, path);
|
|
544
|
-
}
|
|
545
|
-
async function updateSettings(patch) {
|
|
546
|
-
await writeSettings({ ...await readSettings(), ...patch });
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
// packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts
|
|
550
|
-
var DEFAULT_DEBUG_MODE_SETTING = {
|
|
551
|
-
enabled: true
|
|
552
|
-
};
|
|
553
|
-
async function readDebugModeSetting() {
|
|
554
|
-
const { debugMode } = await readSettings();
|
|
555
|
-
return { ...DEFAULT_DEBUG_MODE_SETTING, ...debugMode };
|
|
556
|
-
}
|
|
557
|
-
async function writeDebugModeSetting(setting) {
|
|
558
|
-
await updateSettings({ debugMode: setting });
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
// packages/experience-design-system-cli/src/tui/debug-store.ts
|
|
562
|
-
var pendingRun;
|
|
563
|
-
function generateRunId() {
|
|
564
|
-
const now = /* @__PURE__ */ new Date();
|
|
565
|
-
const pad = (n) => String(n).padStart(2, "0");
|
|
566
|
-
return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
|
|
567
|
-
}
|
|
568
|
-
function datePrefix(now = /* @__PURE__ */ new Date()) {
|
|
569
|
-
const pad = (n) => String(n).padStart(2, "0");
|
|
570
|
-
return `${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${now.getFullYear()}`;
|
|
571
|
-
}
|
|
572
|
-
function slugify(value) {
|
|
573
|
-
return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
574
|
-
}
|
|
575
|
-
function generateSessionId() {
|
|
576
|
-
const today = datePrefix();
|
|
577
|
-
const root = debugSessionsDir();
|
|
578
|
-
const existing = existsSync3(root) ? readdirSync(root) : [];
|
|
579
|
-
const seqPattern = new RegExp(`^${today}-session-(\\d+)$`);
|
|
580
|
-
const maxSeq = existing.reduce((max, entry) => {
|
|
581
|
-
const match = seqPattern.exec(entry);
|
|
582
|
-
return match ? Math.max(max, Number(match[1])) : max;
|
|
583
|
-
}, 0);
|
|
584
|
-
return `${today}-session-${maxSeq + 1}`;
|
|
585
|
-
}
|
|
586
|
-
var SESSION_ID = generateSessionId();
|
|
587
|
-
function sessionDebugDir() {
|
|
588
|
-
return join5(debugSessionsDir(), SESSION_ID);
|
|
589
|
-
}
|
|
590
|
-
void isDebugModeEnabled().then((enabled) => {
|
|
591
|
-
if (!enabled) return void 0;
|
|
592
|
-
return mkdir2(sessionDebugDir(), { recursive: true });
|
|
593
|
-
});
|
|
594
|
-
async function isDebugModeEnabled() {
|
|
595
|
-
try {
|
|
596
|
-
return (await readDebugModeSetting()).enabled;
|
|
597
|
-
} catch {
|
|
598
|
-
return true;
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
function redact(value) {
|
|
602
|
-
const clone = { ...value };
|
|
603
|
-
if ("cma_token" in clone) {
|
|
604
|
-
const raw = clone.cma_token;
|
|
605
|
-
clone.cma_token = typeof raw === "string" && raw.length > 0 ? `[present, ${raw.length} chars]` : "[not set]";
|
|
606
|
-
}
|
|
607
|
-
return clone;
|
|
608
|
-
}
|
|
609
|
-
function startDebugRun({
|
|
610
|
-
flow,
|
|
611
|
-
step,
|
|
612
|
-
menuOption,
|
|
613
|
-
inputs
|
|
614
|
-
}) {
|
|
615
|
-
const runId = generateRunId();
|
|
616
|
-
const startedAt = Date.now();
|
|
617
|
-
const redactedInputs = redact(inputs);
|
|
618
|
-
isDebugModeEnabled().then((enabled) => {
|
|
619
|
-
if (!enabled) return;
|
|
620
|
-
pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
|
|
621
|
-
});
|
|
622
|
-
}
|
|
623
|
-
async function finishDebugRun({
|
|
624
|
-
outputs,
|
|
625
|
-
status,
|
|
626
|
-
exitMethod
|
|
627
|
-
}) {
|
|
628
|
-
const run = pendingRun;
|
|
629
|
-
if (!run) return;
|
|
630
|
-
pendingRun = void 0;
|
|
631
|
-
const durationMs = Date.now() - run.startedAt;
|
|
632
|
-
const content = renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs });
|
|
633
|
-
const flowSegments = run.flow.split("/");
|
|
634
|
-
const dir = join5(sessionDebugDir(), ...flowSegments);
|
|
635
|
-
await mkdir2(dir, { recursive: true });
|
|
636
|
-
const filename = nextAttemptFilename(dir, run.menuOption);
|
|
637
|
-
await writeFile2(join5(dir, filename), content, { mode: 384 });
|
|
638
|
-
}
|
|
639
|
-
function nextAttemptFilename(dir, menuOption) {
|
|
640
|
-
const today = datePrefix();
|
|
641
|
-
const optionSlug = slugify(menuOption);
|
|
642
|
-
const existing = existsSync3(dir) ? readdirSync(dir) : [];
|
|
643
|
-
const attemptPattern = new RegExp(`^${today}-${optionSlug}-attempt-(\\d+)\\.md$`);
|
|
644
|
-
const maxAttempt = existing.reduce((max, entry) => {
|
|
645
|
-
const match = attemptPattern.exec(entry);
|
|
646
|
-
return match ? Math.max(max, Number(match[1])) : max;
|
|
647
|
-
}, 0);
|
|
648
|
-
return `${today}-${optionSlug}-attempt-${maxAttempt + 1}.md`;
|
|
649
|
-
}
|
|
650
|
-
function renderMarkdown(run, finish) {
|
|
651
|
-
const stepMatch = /^(\d+)-(.+)$/.exec(run.step);
|
|
652
|
-
const stepLabel = stepMatch ? `${stepMatch[1]} - ${stepMatch[2]}` : run.step;
|
|
653
|
-
const flowSlug = run.flow.split("/").join("-");
|
|
654
|
-
return `# Debug Log
|
|
655
|
-
|
|
656
|
-
- Run ID: ${run.runId}
|
|
657
|
-
- Flow: ${flowSlug}
|
|
658
|
-
- Step: ${stepLabel}
|
|
659
|
-
- Menu option: ${run.menuOption}
|
|
660
|
-
- Date: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
661
|
-
- CLI version: ${readPackageVersion()}
|
|
662
|
-
- Platform: ${process.platform} / Node ${process.version}
|
|
663
|
-
- Duration on screen: ${finish.durationMs}ms
|
|
664
|
-
- Status: ${finish.status}
|
|
665
|
-
- Exit method: ${finish.exitMethod}
|
|
666
|
-
|
|
667
|
-
## Inputs
|
|
668
|
-
\`\`\`json
|
|
669
|
-
${JSON.stringify(run.inputs, null, 2)}
|
|
670
|
-
\`\`\`
|
|
671
|
-
|
|
672
|
-
## Outputs
|
|
673
|
-
\`\`\`json
|
|
674
|
-
${JSON.stringify(finish.outputs, null, 2)}
|
|
675
|
-
\`\`\`
|
|
676
|
-
`;
|
|
677
|
-
}
|
|
678
|
-
function handleCrash() {
|
|
679
|
-
return finishDebugRun({ outputs: {}, status: "error", exitMethod: "crashed" });
|
|
680
|
-
}
|
|
681
|
-
process.once("uncaughtException", (err) => {
|
|
682
|
-
void handleCrash().finally(() => {
|
|
683
|
-
throw err;
|
|
684
|
-
});
|
|
685
|
-
});
|
|
686
|
-
process.once("unhandledRejection", (reason) => {
|
|
687
|
-
void handleCrash().finally(() => {
|
|
688
|
-
throw reason;
|
|
689
|
-
});
|
|
690
|
-
});
|
|
691
|
-
process.once("SIGINT", () => {
|
|
692
|
-
void handleCrash().finally(() => {
|
|
693
|
-
process.exit(130);
|
|
694
|
-
});
|
|
695
|
-
});
|
|
696
|
-
|
|
697
|
-
// packages/experience-design-system-cli/src/tui/help/PageContainer.tsx
|
|
698
|
-
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
297
|
+
import { Box as Box3, Text as Text3, useInput as useInput3 } from "ink";
|
|
298
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
699
299
|
function HelpScreen({ onDone }) {
|
|
700
|
-
|
|
701
|
-
startDebugRun({ flow: "help", step: "01-help", menuOption: "Help", inputs: {} });
|
|
702
|
-
}, []);
|
|
703
|
-
const leave = (exitMethod) => {
|
|
704
|
-
void finishDebugRun({ outputs: {}, status: "success", exitMethod });
|
|
705
|
-
onDone();
|
|
706
|
-
};
|
|
707
|
-
useInput5((input, key) => {
|
|
300
|
+
useInput3((input, key) => {
|
|
708
301
|
if (key.return) {
|
|
709
|
-
|
|
302
|
+
onDone();
|
|
710
303
|
return;
|
|
711
304
|
}
|
|
712
305
|
if (key.escape || input === "q") {
|
|
713
|
-
|
|
306
|
+
onDone();
|
|
714
307
|
return;
|
|
715
308
|
}
|
|
716
309
|
});
|
|
717
|
-
return /* @__PURE__ */
|
|
718
|
-
/* @__PURE__ */
|
|
719
|
-
/* @__PURE__ */
|
|
720
|
-
/* @__PURE__ */
|
|
721
|
-
/* @__PURE__ */
|
|
722
|
-
/* @__PURE__ */
|
|
723
|
-
ControlHints,
|
|
724
|
-
{
|
|
725
|
-
hints: [
|
|
726
|
-
{ keys: "\u23CE", label: "done" },
|
|
727
|
-
{ keys: "Esc/q", label: "back to start" }
|
|
728
|
-
]
|
|
729
|
-
}
|
|
730
|
-
)
|
|
310
|
+
return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
|
|
311
|
+
/* @__PURE__ */ jsx3(Text3, { bold: true, children: "Help" }),
|
|
312
|
+
/* @__PURE__ */ jsx3(Text3, { children: " " }),
|
|
313
|
+
/* @__PURE__ */ jsx3(Text3, { children: "This is a placeholder screen for v2 help content." }),
|
|
314
|
+
/* @__PURE__ */ jsx3(Text3, { children: " " }),
|
|
315
|
+
/* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "[Enter] Complete [Esc/q] Exit \u2014 both return to Start" })
|
|
731
316
|
] });
|
|
732
317
|
}
|
|
733
318
|
|
|
734
319
|
// packages/experience-design-system-cli/src/tui/settings/PageContainer.tsx
|
|
735
|
-
import { useState as
|
|
736
|
-
import { Box as
|
|
737
|
-
import { jsx as
|
|
320
|
+
import { useState as useState3 } from "react";
|
|
321
|
+
import { Box as Box4, Text as Text4, useInput as useInput4 } from "ink";
|
|
322
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
738
323
|
function SettingsScreen({
|
|
739
324
|
onNavigate,
|
|
740
325
|
onBack
|
|
741
326
|
}) {
|
|
742
|
-
const [focusIdx, setFocusIdx] =
|
|
327
|
+
const [focusIdx, setFocusIdx] = useState3(0);
|
|
743
328
|
const items = [
|
|
744
329
|
{ label: "Configuration", screen: "settings-configuration" },
|
|
745
330
|
{ label: "Opt-in Analytics", screen: "settings-opt-in-analytics" },
|
|
746
331
|
{ label: "Debug Mode", screen: "settings-debug-mode" }
|
|
747
332
|
];
|
|
748
|
-
|
|
333
|
+
useInput4((input, key) => {
|
|
749
334
|
if (key.upArrow) {
|
|
750
335
|
setFocusIdx((i) => (i - 1 + items.length) % items.length);
|
|
751
336
|
return;
|
|
@@ -765,35 +350,40 @@ function SettingsScreen({
|
|
|
765
350
|
onBack();
|
|
766
351
|
}
|
|
767
352
|
});
|
|
768
|
-
return /* @__PURE__ */
|
|
769
|
-
/* @__PURE__ */
|
|
770
|
-
/* @__PURE__ */
|
|
771
|
-
items.map((item, i) => /* @__PURE__ */
|
|
353
|
+
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
|
|
354
|
+
/* @__PURE__ */ jsx4(Text4, { bold: true, children: "Settings" }),
|
|
355
|
+
/* @__PURE__ */ jsx4(Text4, { children: " " }),
|
|
356
|
+
items.map((item, i) => /* @__PURE__ */ jsxs4(Text4, { color: i === focusIdx ? "cyan" : void 0, children: [
|
|
772
357
|
i === focusIdx ? "> " : " ",
|
|
773
358
|
item.label
|
|
774
359
|
] }, item.label)),
|
|
775
|
-
/* @__PURE__ */
|
|
776
|
-
/* @__PURE__ */
|
|
777
|
-
ControlHints,
|
|
778
|
-
{
|
|
779
|
-
hints: [
|
|
780
|
-
{ keys: "\u2191/\u2193", label: "move" },
|
|
781
|
-
{ keys: "\u23CE", label: "select" },
|
|
782
|
-
{ keys: "Esc/q", label: "back" }
|
|
783
|
-
]
|
|
784
|
-
}
|
|
785
|
-
)
|
|
360
|
+
/* @__PURE__ */ jsx4(Text4, { children: " " }),
|
|
361
|
+
/* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "[\u2191/\u2193] Navigate [Enter] Select [Esc/q] Back to Start" })
|
|
786
362
|
] });
|
|
787
363
|
}
|
|
788
364
|
|
|
789
365
|
// packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
|
|
790
|
-
import { useEffect as
|
|
791
|
-
import { Box as
|
|
792
|
-
import TextInput3 from "ink-text-input";
|
|
366
|
+
import { useEffect as useEffect3, useState as useState4 } from "react";
|
|
367
|
+
import { Box as Box5, Text as Text5, useInput as useInput5 } from "ink";
|
|
793
368
|
|
|
794
369
|
// packages/experience-design-system-cli/src/tui/settings/utils/v1-store.ts
|
|
795
|
-
|
|
796
|
-
|
|
370
|
+
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
371
|
+
import { join as join4 } from "node:path";
|
|
372
|
+
import { homedir } from "node:os";
|
|
373
|
+
var V1_STORE_PATH = join4(homedir(), ".config", "experiences", "credentials.json");
|
|
374
|
+
async function readV1Store() {
|
|
375
|
+
try {
|
|
376
|
+
const raw = await readFile(V1_STORE_PATH, "utf8");
|
|
377
|
+
return JSON.parse(raw);
|
|
378
|
+
} catch {
|
|
379
|
+
return {};
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
async function writeV1Store(data) {
|
|
383
|
+
await mkdir(join4(homedir(), ".config", "experiences"), { recursive: true });
|
|
384
|
+
await writeFile(V1_STORE_PATH, `${JSON.stringify(data, null, 2)}
|
|
385
|
+
`, { mode: 384 });
|
|
386
|
+
}
|
|
797
387
|
|
|
798
388
|
// packages/experience-design-system-cli/src/tui/settings/contentful-configuration/config-store.ts
|
|
799
389
|
async function readCredentials() {
|
|
@@ -802,9 +392,7 @@ async function readCredentials() {
|
|
|
802
392
|
spaceId: store.spaceId || "",
|
|
803
393
|
environmentId: store.environmentId || "",
|
|
804
394
|
cmaToken: store.cmaToken || "",
|
|
805
|
-
host: store.host || ""
|
|
806
|
-
defaultComponentDir: store.defaultComponentDir || "",
|
|
807
|
-
defaultTokenFile: store.defaultTokenFile || ""
|
|
395
|
+
host: store.host || ""
|
|
808
396
|
};
|
|
809
397
|
}
|
|
810
398
|
async function writeCredentials(config) {
|
|
@@ -820,51 +408,23 @@ async function writeCredentials(config) {
|
|
|
820
408
|
}
|
|
821
409
|
|
|
822
410
|
// packages/experience-design-system-cli/src/tui/settings/contentful-configuration/ContentfulConfigScreen.tsx
|
|
823
|
-
import { Fragment, jsx as
|
|
824
|
-
var FIELD_ORDER = [
|
|
825
|
-
"spaceId",
|
|
826
|
-
"environmentId",
|
|
827
|
-
"cmaToken",
|
|
828
|
-
"host",
|
|
829
|
-
"defaultComponentDir",
|
|
830
|
-
"defaultTokenFile"
|
|
831
|
-
];
|
|
832
|
-
function debugFields(config) {
|
|
833
|
-
return {
|
|
834
|
-
space_id: config?.spaceId ?? "",
|
|
835
|
-
environment_id: config?.environmentId ?? "",
|
|
836
|
-
cma_token: config?.cmaToken ?? "",
|
|
837
|
-
host: config?.host ?? "",
|
|
838
|
-
default_component_dir: config?.defaultComponentDir ?? "",
|
|
839
|
-
default_token_file: config?.defaultTokenFile ?? ""
|
|
840
|
-
};
|
|
841
|
-
}
|
|
411
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
412
|
+
var FIELD_ORDER = ["spaceId", "environmentId", "cmaToken", "host"];
|
|
842
413
|
var FIELD_LABELS = {
|
|
843
414
|
spaceId: "Space ID",
|
|
844
415
|
environmentId: "Environment ID",
|
|
845
416
|
cmaToken: "CMA Token",
|
|
846
|
-
host: "API Host (optional)"
|
|
847
|
-
defaultComponentDir: "Default component directory (optional)",
|
|
848
|
-
defaultTokenFile: "Default token file (optional)"
|
|
417
|
+
host: "API Host (optional)"
|
|
849
418
|
};
|
|
850
419
|
function ConfigurationScreen({ onDone }) {
|
|
851
|
-
const [stage, setStage] =
|
|
852
|
-
const [config, setConfig] =
|
|
853
|
-
const [activeField, setActiveField] =
|
|
854
|
-
const [
|
|
855
|
-
|
|
856
|
-
const [editing, setEditing] = useState6(false);
|
|
857
|
-
const [valueBeforeEdit, setValueBeforeEdit] = useState6("");
|
|
858
|
-
useEffect4(() => {
|
|
420
|
+
const [stage, setStage] = useState4("loading");
|
|
421
|
+
const [config, setConfig] = useState4(null);
|
|
422
|
+
const [activeField, setActiveField] = useState4("spaceId");
|
|
423
|
+
const [message, setMessage] = useState4(null);
|
|
424
|
+
useEffect3(() => {
|
|
859
425
|
readCredentials().then((cfg) => {
|
|
860
426
|
setConfig(cfg);
|
|
861
427
|
setStage("form");
|
|
862
|
-
startDebugRun({
|
|
863
|
-
flow: "settings/contentful-configuration",
|
|
864
|
-
step: "01-configuration",
|
|
865
|
-
menuOption: "Configuration",
|
|
866
|
-
inputs: debugFields(cfg)
|
|
867
|
-
});
|
|
868
428
|
});
|
|
869
429
|
}, []);
|
|
870
430
|
function fieldValue(field) {
|
|
@@ -874,46 +434,29 @@ function ConfigurationScreen({ onDone }) {
|
|
|
874
434
|
function setFieldValue(field, value) {
|
|
875
435
|
if (!config) return;
|
|
876
436
|
setConfig({ ...config, [field]: value });
|
|
877
|
-
setNotice(null);
|
|
878
437
|
}
|
|
879
438
|
function handleSave() {
|
|
880
439
|
if (!config) return;
|
|
881
440
|
setStage("saving");
|
|
882
|
-
|
|
441
|
+
setMessage(null);
|
|
883
442
|
writeCredentials(config).then(() => {
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
setStage("form");
|
|
443
|
+
setStage("saved");
|
|
444
|
+
setMessage("Configuration saved");
|
|
887
445
|
}).catch((err) => {
|
|
888
|
-
|
|
446
|
+
setMessage(err instanceof Error ? err.message : "Failed to save");
|
|
889
447
|
setStage("form");
|
|
890
448
|
});
|
|
891
449
|
}
|
|
892
|
-
|
|
893
|
-
void finishDebugRun(
|
|
894
|
-
lastSaved ? { outputs: debugFields(lastSaved), status: "success", exitMethod: "saved" } : { outputs: {}, status: "success", exitMethod: "discarded" }
|
|
895
|
-
);
|
|
896
|
-
onDone();
|
|
897
|
-
}
|
|
898
|
-
useInput7((input, key) => {
|
|
450
|
+
useInput5((input, key) => {
|
|
899
451
|
if (stage === "loading" || stage === "saving") return;
|
|
900
|
-
if (
|
|
901
|
-
if (key.escape) {
|
|
902
|
-
|
|
903
|
-
setEditing(false);
|
|
452
|
+
if (stage === "saved") {
|
|
453
|
+
if (key.return || key.escape || input === "q") {
|
|
454
|
+
onDone();
|
|
904
455
|
}
|
|
905
456
|
return;
|
|
906
457
|
}
|
|
907
458
|
if (key.escape || input === "q") {
|
|
908
|
-
|
|
909
|
-
return;
|
|
910
|
-
}
|
|
911
|
-
if (input === "s") {
|
|
912
|
-
handleSave();
|
|
913
|
-
return;
|
|
914
|
-
}
|
|
915
|
-
if (input === "c") {
|
|
916
|
-
setFieldValue(activeField, "");
|
|
459
|
+
onDone();
|
|
917
460
|
return;
|
|
918
461
|
}
|
|
919
462
|
if (key.tab || key.downArrow) {
|
|
@@ -927,73 +470,75 @@ function ConfigurationScreen({ onDone }) {
|
|
|
927
470
|
return;
|
|
928
471
|
}
|
|
929
472
|
if (key.return) {
|
|
930
|
-
|
|
931
|
-
|
|
473
|
+
const idx = FIELD_ORDER.indexOf(activeField);
|
|
474
|
+
if (idx < FIELD_ORDER.length - 1) {
|
|
475
|
+
setActiveField(FIELD_ORDER[idx + 1]);
|
|
476
|
+
} else {
|
|
477
|
+
handleSave();
|
|
478
|
+
}
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
if (key.backspace || key.delete) {
|
|
482
|
+
const current = fieldValue(activeField);
|
|
483
|
+
setFieldValue(activeField, current.slice(0, -1));
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
if (input && !key.ctrl && !key.meta) {
|
|
487
|
+
setFieldValue(activeField, fieldValue(activeField) + input);
|
|
932
488
|
}
|
|
933
489
|
});
|
|
934
490
|
if (stage === "loading") {
|
|
935
|
-
return /* @__PURE__ */
|
|
936
|
-
/* @__PURE__ */
|
|
937
|
-
/* @__PURE__ */
|
|
938
|
-
/* @__PURE__ */
|
|
491
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
|
|
492
|
+
/* @__PURE__ */ jsx5(Text5, { bold: true, children: "Configuration" }),
|
|
493
|
+
/* @__PURE__ */ jsx5(Text5, { children: " " }),
|
|
494
|
+
/* @__PURE__ */ jsx5(Text5, { color: PALETTE.accent, children: "Loading..." })
|
|
939
495
|
] });
|
|
940
496
|
}
|
|
941
|
-
|
|
942
|
-
/* @__PURE__ */
|
|
943
|
-
|
|
944
|
-
|
|
497
|
+
if (stage === "saved") {
|
|
498
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
|
|
499
|
+
/* @__PURE__ */ jsx5(Text5, { bold: true, children: "Configuration" }),
|
|
500
|
+
/* @__PURE__ */ jsx5(Text5, { children: " " }),
|
|
501
|
+
/* @__PURE__ */ jsxs5(Text5, { color: PALETTE.success, children: [
|
|
502
|
+
"\u2713 ",
|
|
503
|
+
message
|
|
504
|
+
] }),
|
|
505
|
+
/* @__PURE__ */ jsx5(Text5, { children: " " }),
|
|
506
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "[Enter] Back to Settings" })
|
|
507
|
+
] });
|
|
508
|
+
}
|
|
509
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
|
|
510
|
+
/* @__PURE__ */ jsx5(Text5, { bold: true, children: "Configuration" }),
|
|
511
|
+
/* @__PURE__ */ jsx5(Text5, { children: " " }),
|
|
512
|
+
/* @__PURE__ */ jsx5(Text5, { children: "Contentful API Credentials" }),
|
|
513
|
+
/* @__PURE__ */ jsx5(Text5, { children: " " }),
|
|
514
|
+
/* @__PURE__ */ jsx5(Box5, { flexDirection: "column", children: FIELD_ORDER.map((field) => {
|
|
945
515
|
const isActive = activeField === field;
|
|
946
516
|
const value = fieldValue(field);
|
|
947
517
|
const display = field === "cmaToken" ? "\u2022".repeat(value.length) : value;
|
|
948
|
-
return /* @__PURE__ */
|
|
949
|
-
/* @__PURE__ */
|
|
950
|
-
/* @__PURE__ */
|
|
518
|
+
return /* @__PURE__ */ jsxs5(Box5, { gap: 1, children: [
|
|
519
|
+
/* @__PURE__ */ jsx5(Text5, { color: isActive ? PALETTE.accent : void 0, children: isActive ? "\u276F" : " " }),
|
|
520
|
+
/* @__PURE__ */ jsxs5(Text5, { bold: isActive, children: [
|
|
951
521
|
FIELD_LABELS[field],
|
|
952
522
|
":"
|
|
953
523
|
] }),
|
|
954
|
-
|
|
955
|
-
TextInput3,
|
|
956
|
-
{
|
|
957
|
-
value,
|
|
958
|
-
onChange: (next) => setFieldValue(field, next),
|
|
959
|
-
onSubmit: () => setEditing(false),
|
|
960
|
-
mask: field === "cmaToken" ? "\u2022" : void 0
|
|
961
|
-
}
|
|
962
|
-
) : /* @__PURE__ */ jsx8(Text8, { children: display || /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: "(empty)" }) })
|
|
524
|
+
/* @__PURE__ */ jsx5(Text5, { children: display || /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "(empty)" }) })
|
|
963
525
|
] }, field);
|
|
964
526
|
}) }),
|
|
965
|
-
|
|
966
|
-
/* @__PURE__ */
|
|
967
|
-
/* @__PURE__ */
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
notice.text
|
|
527
|
+
message && /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
528
|
+
/* @__PURE__ */ jsx5(Text5, { children: " " }),
|
|
529
|
+
/* @__PURE__ */ jsxs5(Text5, { color: PALETTE.error, children: [
|
|
530
|
+
"\u2717 ",
|
|
531
|
+
message
|
|
971
532
|
] })
|
|
972
533
|
] }),
|
|
973
|
-
/* @__PURE__ */
|
|
974
|
-
/* @__PURE__ */
|
|
975
|
-
ControlHints,
|
|
976
|
-
{
|
|
977
|
-
hints: editing ? [
|
|
978
|
-
{ keys: "type", label: "edit" },
|
|
979
|
-
{ keys: "\u2190/\u2192", label: "move cursor" },
|
|
980
|
-
{ keys: "\u23CE", label: "done" },
|
|
981
|
-
{ keys: "Esc", label: "cancel edit" }
|
|
982
|
-
] : [
|
|
983
|
-
{ keys: "\u2191/\u2193", label: "move" },
|
|
984
|
-
{ keys: "\u23CE", label: "edit" },
|
|
985
|
-
{ keys: "c", label: "clear" },
|
|
986
|
-
{ keys: "s", label: "save" },
|
|
987
|
-
{ keys: "Esc/q", label: "quit without saving" }
|
|
988
|
-
]
|
|
989
|
-
}
|
|
990
|
-
)
|
|
534
|
+
/* @__PURE__ */ jsx5(Text5, { children: " " }),
|
|
535
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "[\u2191/\u2193] Switch field \xB7 [Enter] Save/Next \xB7 [Esc/q] Back" })
|
|
991
536
|
] });
|
|
992
537
|
}
|
|
993
538
|
|
|
994
539
|
// packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
|
|
995
|
-
import { useEffect as
|
|
996
|
-
import { Box as
|
|
540
|
+
import { useEffect as useEffect4, useState as useState5 } from "react";
|
|
541
|
+
import { Box as Box6, Text as Text6, useInput as useInput6 } from "ink";
|
|
997
542
|
|
|
998
543
|
// packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/analytics-store.ts
|
|
999
544
|
async function readAnalyticsSetting() {
|
|
@@ -1011,23 +556,17 @@ async function writeAnalyticsSetting(setting) {
|
|
|
1011
556
|
}
|
|
1012
557
|
|
|
1013
558
|
// packages/experience-design-system-cli/src/tui/settings/opt-in-analytics/screen.tsx
|
|
1014
|
-
import { Fragment as Fragment2, jsx as
|
|
559
|
+
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1015
560
|
function OptInAnalyticsScreen({ onDone }) {
|
|
1016
|
-
const [loading, setLoading] =
|
|
1017
|
-
const [enabled, setEnabled] =
|
|
1018
|
-
|
|
561
|
+
const [loading, setLoading] = useState5(true);
|
|
562
|
+
const [enabled, setEnabled] = useState5(true);
|
|
563
|
+
useEffect4(() => {
|
|
1019
564
|
readAnalyticsSetting().then((setting) => {
|
|
1020
565
|
setEnabled(setting.enabled);
|
|
1021
566
|
setLoading(false);
|
|
1022
|
-
startDebugRun({
|
|
1023
|
-
flow: "settings/opt-in-analytics",
|
|
1024
|
-
step: "01-opt-in-analytics",
|
|
1025
|
-
menuOption: "Opt-in Analytics",
|
|
1026
|
-
inputs: { enabled: setting.enabled }
|
|
1027
|
-
});
|
|
1028
567
|
});
|
|
1029
568
|
}, []);
|
|
1030
|
-
|
|
569
|
+
useInput6((input, key) => {
|
|
1031
570
|
if (loading) return;
|
|
1032
571
|
if (key.return || input === " ") {
|
|
1033
572
|
setEnabled((current) => {
|
|
@@ -1038,44 +577,208 @@ function OptInAnalyticsScreen({ onDone }) {
|
|
|
1038
577
|
return;
|
|
1039
578
|
}
|
|
1040
579
|
if (key.escape || input === "q") {
|
|
1041
|
-
void finishDebugRun({ outputs: { enabled }, status: "success", exitMethod: "saved" });
|
|
1042
580
|
onDone();
|
|
1043
581
|
}
|
|
1044
582
|
});
|
|
1045
|
-
return /* @__PURE__ */
|
|
1046
|
-
/* @__PURE__ */
|
|
1047
|
-
/* @__PURE__ */
|
|
1048
|
-
loading ? /* @__PURE__ */
|
|
1049
|
-
/* @__PURE__ */
|
|
583
|
+
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
|
|
584
|
+
/* @__PURE__ */ jsx6(Text6, { bold: true, children: "Settings \u203A Opt-in Analytics" }),
|
|
585
|
+
/* @__PURE__ */ jsx6(Text6, { children: " " }),
|
|
586
|
+
loading ? /* @__PURE__ */ jsx6(Text6, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
587
|
+
/* @__PURE__ */ jsxs6(Text6, { children: [
|
|
1050
588
|
"Share anonymous usage data:",
|
|
1051
589
|
" ",
|
|
1052
|
-
/* @__PURE__ */
|
|
590
|
+
/* @__PURE__ */ jsx6(Text6, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
|
|
1053
591
|
] }),
|
|
1054
|
-
/* @__PURE__ */
|
|
1055
|
-
/* @__PURE__ */
|
|
1056
|
-
/* @__PURE__ */
|
|
592
|
+
/* @__PURE__ */ jsx6(Text6, { children: " " }),
|
|
593
|
+
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "Shares which CLI commands are used and where imports succeed or fail." }),
|
|
594
|
+
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "Never includes source code, file paths, credentials, or authored content." })
|
|
1057
595
|
] }),
|
|
1058
|
-
/* @__PURE__ */
|
|
1059
|
-
/* @__PURE__ */
|
|
1060
|
-
ControlHints,
|
|
1061
|
-
{
|
|
1062
|
-
hints: [
|
|
1063
|
-
{ keys: "\u23CE/Space", label: "toggle" },
|
|
1064
|
-
{ keys: "Esc/q", label: "back" }
|
|
1065
|
-
]
|
|
1066
|
-
}
|
|
1067
|
-
)
|
|
596
|
+
/* @__PURE__ */ jsx6(Text6, { children: " " }),
|
|
597
|
+
/* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "[Enter/Space] Toggle [Esc/q] Back to Settings" })
|
|
1068
598
|
] });
|
|
1069
599
|
}
|
|
1070
600
|
|
|
1071
601
|
// packages/experience-design-system-cli/src/tui/upgrade/PageContainer.tsx
|
|
1072
|
-
import { useEffect as
|
|
1073
|
-
import { Box as
|
|
1074
|
-
|
|
602
|
+
import { useEffect as useEffect5, useState as useState6 } from "react";
|
|
603
|
+
import { Box as Box7, Text as Text7, useInput as useInput7 } from "ink";
|
|
604
|
+
|
|
605
|
+
// packages/experience-design-system-cli/src/tui/debug-store.ts
|
|
606
|
+
import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
|
|
607
|
+
import { existsSync as existsSync3, readdirSync } from "node:fs";
|
|
608
|
+
import { join as join6 } from "node:path";
|
|
609
|
+
|
|
610
|
+
// packages/experience-design-system-cli/src/tui/settings/debug-mode/debug-mode-store.ts
|
|
611
|
+
import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
612
|
+
import { dirname as dirname2, join as join5 } from "node:path";
|
|
613
|
+
var PACKAGE_NAME3 = "@contentful/experience-design-system-cli";
|
|
614
|
+
var DEFAULT_DEBUG_MODE_SETTING = {
|
|
615
|
+
enabled: true
|
|
616
|
+
};
|
|
617
|
+
function debugModeSettingPath() {
|
|
618
|
+
return join5(findPackageRoot(import.meta.url, PACKAGE_NAME3), ".contentful", "config", "debug_mode.json");
|
|
619
|
+
}
|
|
620
|
+
async function readDebugModeSetting() {
|
|
621
|
+
try {
|
|
622
|
+
const raw = await readFile2(debugModeSettingPath(), "utf8");
|
|
623
|
+
const parsed = JSON.parse(raw);
|
|
624
|
+
return { ...DEFAULT_DEBUG_MODE_SETTING, ...parsed };
|
|
625
|
+
} catch {
|
|
626
|
+
return { ...DEFAULT_DEBUG_MODE_SETTING };
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
async function writeDebugModeSetting(setting) {
|
|
630
|
+
const path = debugModeSettingPath();
|
|
631
|
+
await mkdir2(dirname2(path), { recursive: true });
|
|
632
|
+
await writeFile2(path, `${JSON.stringify(setting, null, 2)}
|
|
633
|
+
`, { mode: 384 });
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
// packages/experience-design-system-cli/src/tui/debug-store.ts
|
|
637
|
+
var PACKAGE_NAME4 = "@contentful/experience-design-system-cli";
|
|
638
|
+
var pendingRun;
|
|
639
|
+
function generateRunId() {
|
|
640
|
+
const now = /* @__PURE__ */ new Date();
|
|
641
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
642
|
+
return `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
|
|
643
|
+
}
|
|
644
|
+
function sessionsRootDir() {
|
|
645
|
+
return join6(findPackageRoot(import.meta.url, PACKAGE_NAME4), ".contentful", "debug", "sessions");
|
|
646
|
+
}
|
|
647
|
+
function datePrefix(now = /* @__PURE__ */ new Date()) {
|
|
648
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
649
|
+
return `${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${now.getFullYear()}`;
|
|
650
|
+
}
|
|
651
|
+
function slugify(value) {
|
|
652
|
+
return value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
653
|
+
}
|
|
654
|
+
function generateSessionId() {
|
|
655
|
+
const today = datePrefix();
|
|
656
|
+
const root = sessionsRootDir();
|
|
657
|
+
const existing = existsSync3(root) ? readdirSync(root) : [];
|
|
658
|
+
const seqPattern = new RegExp(`^${today}-session-(\\d+)$`);
|
|
659
|
+
const maxSeq = existing.reduce((max, entry) => {
|
|
660
|
+
const match = seqPattern.exec(entry);
|
|
661
|
+
return match ? Math.max(max, Number(match[1])) : max;
|
|
662
|
+
}, 0);
|
|
663
|
+
return `${today}-session-${maxSeq + 1}`;
|
|
664
|
+
}
|
|
665
|
+
var SESSION_ID = generateSessionId();
|
|
666
|
+
function sessionDebugDir() {
|
|
667
|
+
return join6(sessionsRootDir(), SESSION_ID);
|
|
668
|
+
}
|
|
669
|
+
void isDebugModeEnabled().then((enabled) => {
|
|
670
|
+
if (!enabled) return void 0;
|
|
671
|
+
return mkdir3(sessionDebugDir(), { recursive: true });
|
|
672
|
+
});
|
|
673
|
+
async function isDebugModeEnabled() {
|
|
674
|
+
try {
|
|
675
|
+
return (await readDebugModeSetting()).enabled;
|
|
676
|
+
} catch {
|
|
677
|
+
return true;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
function redact(value) {
|
|
681
|
+
const clone = { ...value };
|
|
682
|
+
if ("cma_token" in clone) {
|
|
683
|
+
const raw = clone.cma_token;
|
|
684
|
+
clone.cma_token = typeof raw === "string" && raw.length > 0 ? `[present, ${raw.length} chars]` : "[not set]";
|
|
685
|
+
}
|
|
686
|
+
return clone;
|
|
687
|
+
}
|
|
688
|
+
function startDebugRun({
|
|
689
|
+
flow,
|
|
690
|
+
step,
|
|
691
|
+
menuOption,
|
|
692
|
+
inputs
|
|
693
|
+
}) {
|
|
694
|
+
const runId = generateRunId();
|
|
695
|
+
const startedAt = Date.now();
|
|
696
|
+
const redactedInputs = redact(inputs);
|
|
697
|
+
isDebugModeEnabled().then((enabled) => {
|
|
698
|
+
if (!enabled) return;
|
|
699
|
+
pendingRun = { flow, step, runId, menuOption, inputs: redactedInputs, startedAt };
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
async function finishDebugRun({
|
|
703
|
+
outputs,
|
|
704
|
+
status,
|
|
705
|
+
exitMethod
|
|
706
|
+
}) {
|
|
707
|
+
const run = pendingRun;
|
|
708
|
+
if (!run) return;
|
|
709
|
+
pendingRun = void 0;
|
|
710
|
+
const durationMs = Date.now() - run.startedAt;
|
|
711
|
+
const content = renderMarkdown(run, { outputs: redact(outputs), status, exitMethod, durationMs });
|
|
712
|
+
const flowSegments = run.flow.split("/");
|
|
713
|
+
const dir = join6(sessionDebugDir(), ...flowSegments);
|
|
714
|
+
await mkdir3(dir, { recursive: true });
|
|
715
|
+
const filename = nextAttemptFilename(dir, run.menuOption);
|
|
716
|
+
await writeFile3(join6(dir, filename), content, { mode: 384 });
|
|
717
|
+
}
|
|
718
|
+
function nextAttemptFilename(dir, menuOption) {
|
|
719
|
+
const today = datePrefix();
|
|
720
|
+
const optionSlug = slugify(menuOption);
|
|
721
|
+
const existing = existsSync3(dir) ? readdirSync(dir) : [];
|
|
722
|
+
const attemptPattern = new RegExp(`^${today}-${optionSlug}-attempt-(\\d+)\\.md$`);
|
|
723
|
+
const maxAttempt = existing.reduce((max, entry) => {
|
|
724
|
+
const match = attemptPattern.exec(entry);
|
|
725
|
+
return match ? Math.max(max, Number(match[1])) : max;
|
|
726
|
+
}, 0);
|
|
727
|
+
return `${today}-${optionSlug}-attempt-${maxAttempt + 1}.md`;
|
|
728
|
+
}
|
|
729
|
+
function renderMarkdown(run, finish) {
|
|
730
|
+
const stepMatch = /^(\d+)-(.+)$/.exec(run.step);
|
|
731
|
+
const stepLabel = stepMatch ? `${stepMatch[1]} - ${stepMatch[2]}` : run.step;
|
|
732
|
+
const flowSlug = run.flow.split("/").join("-");
|
|
733
|
+
return `# Debug Log
|
|
734
|
+
|
|
735
|
+
- Run ID: ${run.runId}
|
|
736
|
+
- Flow: ${flowSlug}
|
|
737
|
+
- Step: ${stepLabel}
|
|
738
|
+
- Menu option: ${run.menuOption}
|
|
739
|
+
- Date: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
740
|
+
- CLI version: ${readPackageVersion()}
|
|
741
|
+
- Platform: ${process.platform} / Node ${process.version}
|
|
742
|
+
- Duration on screen: ${finish.durationMs}ms
|
|
743
|
+
- Status: ${finish.status}
|
|
744
|
+
- Exit method: ${finish.exitMethod}
|
|
745
|
+
|
|
746
|
+
## Inputs
|
|
747
|
+
\`\`\`json
|
|
748
|
+
${JSON.stringify(run.inputs, null, 2)}
|
|
749
|
+
\`\`\`
|
|
750
|
+
|
|
751
|
+
## Outputs
|
|
752
|
+
\`\`\`json
|
|
753
|
+
${JSON.stringify(finish.outputs, null, 2)}
|
|
754
|
+
\`\`\`
|
|
755
|
+
`;
|
|
756
|
+
}
|
|
757
|
+
function handleCrash() {
|
|
758
|
+
return finishDebugRun({ outputs: {}, status: "error", exitMethod: "crashed" });
|
|
759
|
+
}
|
|
760
|
+
process.once("uncaughtException", (err) => {
|
|
761
|
+
void handleCrash().finally(() => {
|
|
762
|
+
throw err;
|
|
763
|
+
});
|
|
764
|
+
});
|
|
765
|
+
process.once("unhandledRejection", (reason) => {
|
|
766
|
+
void handleCrash().finally(() => {
|
|
767
|
+
throw reason;
|
|
768
|
+
});
|
|
769
|
+
});
|
|
770
|
+
process.once("SIGINT", () => {
|
|
771
|
+
void handleCrash().finally(() => {
|
|
772
|
+
process.exit(130);
|
|
773
|
+
});
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
// packages/experience-design-system-cli/src/tui/upgrade/PageContainer.tsx
|
|
777
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1075
778
|
var UPGRADE_COMMANDS = ["git pull", "pnpm install", "pnpm build"];
|
|
1076
779
|
function UpgradeScreen({ onDone }) {
|
|
1077
|
-
const [upgradeCheck, setUpgradeCheck] =
|
|
1078
|
-
|
|
780
|
+
const [upgradeCheck, setUpgradeCheck] = useState6();
|
|
781
|
+
useEffect5(() => {
|
|
1079
782
|
startDebugRun({
|
|
1080
783
|
flow: "upgrade",
|
|
1081
784
|
step: "01-upgrade",
|
|
@@ -1084,7 +787,7 @@ function UpgradeScreen({ onDone }) {
|
|
|
1084
787
|
});
|
|
1085
788
|
checkForUpgrade().then(setUpgradeCheck).catch(() => setUpgradeCheck({ status: "error" }));
|
|
1086
789
|
}, []);
|
|
1087
|
-
|
|
790
|
+
useInput7((_input, key) => {
|
|
1088
791
|
if (key.return) {
|
|
1089
792
|
void finishDebugRun({
|
|
1090
793
|
outputs: upgradeCheck ?? {},
|
|
@@ -1095,12 +798,12 @@ function UpgradeScreen({ onDone }) {
|
|
|
1095
798
|
return;
|
|
1096
799
|
}
|
|
1097
800
|
});
|
|
1098
|
-
return /* @__PURE__ */
|
|
1099
|
-
/* @__PURE__ */
|
|
1100
|
-
/* @__PURE__ */
|
|
801
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
|
|
802
|
+
/* @__PURE__ */ jsx7(Text7, { bold: true, children: "Upgrade" }),
|
|
803
|
+
/* @__PURE__ */ jsx7(Text7, { children: " " }),
|
|
1101
804
|
renderBody(upgradeCheck),
|
|
1102
|
-
/* @__PURE__ */
|
|
1103
|
-
/* @__PURE__ */
|
|
805
|
+
/* @__PURE__ */ jsx7(Text7, { children: " " }),
|
|
806
|
+
/* @__PURE__ */ jsxs7(Text7, { bold: true, color: PALETTE.accent, children: [
|
|
1104
807
|
FOCUS_MARKER,
|
|
1105
808
|
" Go Back"
|
|
1106
809
|
] })
|
|
@@ -1108,57 +811,51 @@ function UpgradeScreen({ onDone }) {
|
|
|
1108
811
|
}
|
|
1109
812
|
function renderBody(upgradeCheck) {
|
|
1110
813
|
if (!upgradeCheck) {
|
|
1111
|
-
return /* @__PURE__ */
|
|
814
|
+
return /* @__PURE__ */ jsx7(Text7, { color: PALETTE.muted, children: "Checking for updates\u2026" });
|
|
1112
815
|
}
|
|
1113
816
|
if (upgradeCheck.status === "error") {
|
|
1114
|
-
return /* @__PURE__ */
|
|
817
|
+
return /* @__PURE__ */ jsx7(Text7, { color: PALETTE.warning, children: "Couldn't check for updates \u2014 check your network connection and try again." });
|
|
1115
818
|
}
|
|
1116
819
|
if (upgradeCheck.status === "up-to-date") {
|
|
1117
|
-
return /* @__PURE__ */
|
|
820
|
+
return /* @__PURE__ */ jsxs7(Text7, { color: PALETTE.success, children: [
|
|
1118
821
|
"You're already on the latest version (v",
|
|
1119
822
|
upgradeCheck.current,
|
|
1120
823
|
")."
|
|
1121
824
|
] });
|
|
1122
825
|
}
|
|
1123
|
-
return /* @__PURE__ */
|
|
1124
|
-
/* @__PURE__ */
|
|
1125
|
-
/* @__PURE__ */
|
|
826
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
827
|
+
/* @__PURE__ */ jsxs7(Text7, { color: PALETTE.muted, children: [
|
|
828
|
+
/* @__PURE__ */ jsxs7(Text7, { bold: true, color: PALETTE.success, children: [
|
|
1126
829
|
"v",
|
|
1127
830
|
upgradeCheck.latest
|
|
1128
831
|
] }),
|
|
1129
832
|
" ",
|
|
1130
833
|
"is available (you're on ",
|
|
1131
|
-
/* @__PURE__ */
|
|
834
|
+
/* @__PURE__ */ jsxs7(Text7, { bold: true, children: [
|
|
1132
835
|
"v",
|
|
1133
836
|
upgradeCheck.current
|
|
1134
837
|
] }),
|
|
1135
838
|
"). Exit this program, cd into the root of your local clone of contentful/experience-design-system-sdk-public, then run:"
|
|
1136
839
|
] }),
|
|
1137
|
-
/* @__PURE__ */
|
|
1138
|
-
/* @__PURE__ */
|
|
840
|
+
/* @__PURE__ */ jsx7(Text7, { children: " " }),
|
|
841
|
+
/* @__PURE__ */ jsx7(Box7, { flexDirection: "column", borderStyle: "round", borderColor: PALETTE.border, paddingX: 1, children: UPGRADE_COMMANDS.map((cmd) => /* @__PURE__ */ jsx7(Text7, { bold: true, children: cmd }, cmd)) })
|
|
1139
842
|
] });
|
|
1140
843
|
}
|
|
1141
844
|
|
|
1142
845
|
// packages/experience-design-system-cli/src/tui/settings/debug-mode/screen.tsx
|
|
1143
|
-
import { useEffect as
|
|
1144
|
-
import { Box as
|
|
1145
|
-
import { jsx as
|
|
846
|
+
import { useEffect as useEffect6, useState as useState7 } from "react";
|
|
847
|
+
import { Box as Box8, Text as Text8, useInput as useInput8 } from "ink";
|
|
848
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1146
849
|
function DebugModeScreen({ onDone }) {
|
|
1147
|
-
const [loading, setLoading] =
|
|
1148
|
-
const [enabled, setEnabled] =
|
|
1149
|
-
|
|
850
|
+
const [loading, setLoading] = useState7(true);
|
|
851
|
+
const [enabled, setEnabled] = useState7(true);
|
|
852
|
+
useEffect6(() => {
|
|
1150
853
|
readDebugModeSetting().then((setting) => {
|
|
1151
854
|
setEnabled(setting.enabled);
|
|
1152
855
|
setLoading(false);
|
|
1153
|
-
startDebugRun({
|
|
1154
|
-
flow: "settings/debug-mode",
|
|
1155
|
-
step: "01-debug-mode",
|
|
1156
|
-
menuOption: "Debug Mode",
|
|
1157
|
-
inputs: { enabled: setting.enabled }
|
|
1158
|
-
});
|
|
1159
856
|
});
|
|
1160
857
|
}, []);
|
|
1161
|
-
|
|
858
|
+
useInput8((input, key) => {
|
|
1162
859
|
if (loading) return;
|
|
1163
860
|
if (key.return || input === " ") {
|
|
1164
861
|
setEnabled((current) => {
|
|
@@ -1169,100 +866,64 @@ function DebugModeScreen({ onDone }) {
|
|
|
1169
866
|
return;
|
|
1170
867
|
}
|
|
1171
868
|
if (key.escape || input === "q") {
|
|
1172
|
-
void finishDebugRun({ outputs: { enabled }, status: "success", exitMethod: "saved" });
|
|
1173
869
|
onDone();
|
|
1174
870
|
}
|
|
1175
871
|
});
|
|
1176
|
-
return /* @__PURE__ */
|
|
1177
|
-
/* @__PURE__ */
|
|
1178
|
-
/* @__PURE__ */
|
|
1179
|
-
loading ? /* @__PURE__ */
|
|
872
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", paddingX: 2, paddingY: 1, children: [
|
|
873
|
+
/* @__PURE__ */ jsx8(Text8, { bold: true, children: "Settings \u203A Debug Mode" }),
|
|
874
|
+
/* @__PURE__ */ jsx8(Text8, { children: " " }),
|
|
875
|
+
loading ? /* @__PURE__ */ jsx8(Text8, { color: PALETTE.muted, children: "Loading\u2026" }) : /* @__PURE__ */ jsxs8(Text8, { children: [
|
|
1180
876
|
"Debug logging:",
|
|
1181
877
|
" ",
|
|
1182
|
-
/* @__PURE__ */
|
|
878
|
+
/* @__PURE__ */ jsx8(Text8, { bold: true, color: enabled ? PALETTE.success : PALETTE.muted, children: enabled ? "On" : "Off" })
|
|
1183
879
|
] }),
|
|
1184
|
-
/* @__PURE__ */
|
|
1185
|
-
/* @__PURE__ */
|
|
1186
|
-
ControlHints,
|
|
1187
|
-
{
|
|
1188
|
-
hints: [
|
|
1189
|
-
{ keys: "\u23CE/Space", label: "toggle" },
|
|
1190
|
-
{ keys: "Esc/q", label: "back" }
|
|
1191
|
-
]
|
|
1192
|
-
}
|
|
1193
|
-
)
|
|
880
|
+
/* @__PURE__ */ jsx8(Text8, { children: " " }),
|
|
881
|
+
/* @__PURE__ */ jsx8(Text8, { dimColor: true, children: "[Enter/Space] Toggle [Esc/q] Back to Settings" })
|
|
1194
882
|
] });
|
|
1195
883
|
}
|
|
1196
884
|
|
|
1197
885
|
// packages/experience-design-system-cli/app.tsx
|
|
1198
|
-
import {
|
|
886
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
1199
887
|
function App({ onLaunchImport, importExitCode }) {
|
|
1200
888
|
const returnedFromImport = importExitCode !== void 0;
|
|
1201
|
-
const [screen, setScreen] =
|
|
1202
|
-
const [showImportResult, setShowImportResult] = useState10(returnedFromImport);
|
|
1203
|
-
const [projectPath, setProjectPath] = useState10();
|
|
1204
|
-
const [importDefaults, setImportDefaults] = useState10();
|
|
1205
|
-
useEffect8(() => {
|
|
1206
|
-
if (screen !== "import") {
|
|
1207
|
-
setImportDefaults(void 0);
|
|
1208
|
-
return;
|
|
1209
|
-
}
|
|
1210
|
-
void readCredentials().then(
|
|
1211
|
-
(saved) => setImportDefaults({ componentDir: saved.defaultComponentDir ?? "", tokenFile: saved.defaultTokenFile ?? "" })
|
|
1212
|
-
);
|
|
1213
|
-
}, [screen]);
|
|
889
|
+
const [screen, setScreen] = useState8(returnedFromImport ? "import" : "start");
|
|
1214
890
|
const goToStart = () => setScreen("start");
|
|
1215
891
|
const goToSettings = () => setScreen("settings");
|
|
1216
|
-
const
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
setProjectPath(void 0);
|
|
1223
|
-
goToStart();
|
|
892
|
+
const navigateFromHome = (next) => {
|
|
893
|
+
if (next === "import" && onLaunchImport) {
|
|
894
|
+
onLaunchImport();
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
setScreen(next);
|
|
1224
898
|
};
|
|
1225
899
|
switch (screen) {
|
|
1226
900
|
case "import":
|
|
1227
|
-
|
|
1228
|
-
if (importDefaults === void 0) return /* @__PURE__ */ jsx12(Fragment3, {});
|
|
1229
|
-
if (projectPath === void 0) {
|
|
1230
|
-
return /* @__PURE__ */ jsx12(WelcomeScreen, { onContinue: setProjectPath, onQuit: leaveImport, initialPath: importDefaults.componentDir });
|
|
1231
|
-
}
|
|
1232
|
-
return /* @__PURE__ */ jsx12(
|
|
1233
|
-
TokenInputScreen,
|
|
1234
|
-
{
|
|
1235
|
-
initialPath: importDefaults.tokenFile,
|
|
1236
|
-
onConfirm: (tokens) => onLaunchImport?.({ project: projectPath, tokens }),
|
|
1237
|
-
onSkip: () => onLaunchImport?.({ project: projectPath }),
|
|
1238
|
-
onBack: () => setProjectPath(void 0)
|
|
1239
|
-
}
|
|
1240
|
-
);
|
|
901
|
+
return /* @__PURE__ */ jsx9(ImportScreen, { exitCode: importExitCode, onDone: goToStart });
|
|
1241
902
|
case "help":
|
|
1242
|
-
return /* @__PURE__ */
|
|
903
|
+
return /* @__PURE__ */ jsx9(HelpScreen, { onDone: goToStart });
|
|
1243
904
|
case "upgrade":
|
|
1244
|
-
return /* @__PURE__ */
|
|
905
|
+
return /* @__PURE__ */ jsx9(UpgradeScreen, { onDone: goToStart });
|
|
1245
906
|
case "settings":
|
|
1246
|
-
return /* @__PURE__ */
|
|
907
|
+
return /* @__PURE__ */ jsx9(SettingsScreen, { onNavigate: setScreen, onBack: goToStart });
|
|
1247
908
|
case "settings-configuration":
|
|
1248
|
-
return /* @__PURE__ */
|
|
909
|
+
return /* @__PURE__ */ jsx9(ConfigurationScreen, { onDone: goToSettings });
|
|
1249
910
|
case "settings-opt-in-analytics":
|
|
1250
|
-
return /* @__PURE__ */
|
|
911
|
+
return /* @__PURE__ */ jsx9(OptInAnalyticsScreen, { onDone: goToSettings });
|
|
1251
912
|
case "settings-debug-mode":
|
|
1252
|
-
return /* @__PURE__ */
|
|
913
|
+
return /* @__PURE__ */ jsx9(DebugModeScreen, { onDone: goToSettings });
|
|
1253
914
|
case "start":
|
|
1254
|
-
return /* @__PURE__ */
|
|
915
|
+
return /* @__PURE__ */ jsx9(HomeScreen, { onNavigate: navigateFromHome });
|
|
1255
916
|
}
|
|
1256
917
|
}
|
|
1257
918
|
async function renderUntilImportRequestedOrExit(renderApp, importExitCode) {
|
|
1258
|
-
let
|
|
919
|
+
let importRequested = false;
|
|
1259
920
|
const instance = renderApp(
|
|
1260
|
-
/* @__PURE__ */
|
|
921
|
+
/* @__PURE__ */ jsx9(
|
|
1261
922
|
App,
|
|
1262
923
|
{
|
|
1263
924
|
importExitCode,
|
|
1264
|
-
onLaunchImport: (
|
|
1265
|
-
|
|
925
|
+
onLaunchImport: () => {
|
|
926
|
+
importRequested = true;
|
|
1266
927
|
instance.unmount();
|
|
1267
928
|
}
|
|
1268
929
|
}
|
|
@@ -1270,15 +931,13 @@ async function renderUntilImportRequestedOrExit(renderApp, importExitCode) {
|
|
|
1270
931
|
);
|
|
1271
932
|
await instance.waitUntilExit();
|
|
1272
933
|
await stopReadingTerminal();
|
|
1273
|
-
return
|
|
934
|
+
return importRequested;
|
|
1274
935
|
}
|
|
1275
936
|
async function runApp(renderApp) {
|
|
1276
937
|
let importExitCode;
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
importExitCode = (await spawnV1Import(requestedImport)).exitCode;
|
|
938
|
+
while (await renderUntilImportRequestedOrExit(renderApp, importExitCode)) {
|
|
939
|
+
importExitCode = (await spawnV1Import({})).exitCode;
|
|
1280
940
|
startReadingTerminal();
|
|
1281
|
-
requestedImport = await renderUntilImportRequestedOrExit(renderApp, importExitCode);
|
|
1282
941
|
}
|
|
1283
942
|
}
|
|
1284
943
|
export {
|