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