@contentful/experience-design-system-cli 2.35.1-dev-build-c4a4d1cd.0 → 2.35.1-dev-build-57c625cc.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/package.json +1 -1
- package/legacy/dist/src/index.js +306 -105
- package/legacy/dist/src/lib/push-debug-log.d.ts +23 -5
- package/legacy/package.json +1 -1
- package/package.json +2 -2
package/dist/package.json
CHANGED
package/legacy/dist/src/index.js
CHANGED
|
@@ -2011,8 +2011,8 @@ function deleteRawTokensForSession(db, sessionId2) {
|
|
|
2011
2011
|
}
|
|
2012
2012
|
function createRawTokenGroups(db, sessionId2, groups) {
|
|
2013
2013
|
const insertGroup = db.prepare(`INSERT INTO raw_token_groups (session_id, path, description) VALUES (?, ?, ?)`);
|
|
2014
|
-
for (const
|
|
2015
|
-
insertGroup.run(sessionId2,
|
|
2014
|
+
for (const group2 of groups) {
|
|
2015
|
+
insertGroup.run(sessionId2, group2.path, group2.$description ?? null);
|
|
2016
2016
|
}
|
|
2017
2017
|
}
|
|
2018
2018
|
function createRawTokens(db, sessionId2, tokens) {
|
|
@@ -6891,24 +6891,24 @@ function parseEdsiError(rawInput) {
|
|
|
6891
6891
|
}
|
|
6892
6892
|
}
|
|
6893
6893
|
const cleaned = stripLambdaLogPrefix(body);
|
|
6894
|
-
const
|
|
6895
|
-
const bindingFromJson = typeof
|
|
6894
|
+
const json2 = parseJsonBody(cleaned) ?? parseJsonBody(body);
|
|
6895
|
+
const bindingFromJson = typeof json2?.message === "string" ? parseBindingDiagnostics(json2.message) : null;
|
|
6896
6896
|
if (bindingFromJson) {
|
|
6897
6897
|
return {
|
|
6898
|
-
code: bindingFromJson.code ??
|
|
6898
|
+
code: bindingFromJson.code ?? json2?.code ?? null,
|
|
6899
6899
|
message: bindingFromJson.message ?? cleaned,
|
|
6900
6900
|
cycle: null,
|
|
6901
6901
|
raw: false,
|
|
6902
6902
|
...bindingFromJson.diagnostics ? { diagnostics: bindingFromJson.diagnostics } : {}
|
|
6903
6903
|
};
|
|
6904
6904
|
}
|
|
6905
|
-
if (
|
|
6905
|
+
if (json2 && (json2.code || json2.message || json2.cycle)) {
|
|
6906
6906
|
return {
|
|
6907
|
-
code:
|
|
6908
|
-
message:
|
|
6909
|
-
cycle:
|
|
6907
|
+
code: json2.code ?? null,
|
|
6908
|
+
message: json2.message ?? (cleaned || prefix),
|
|
6909
|
+
cycle: json2.cycle ?? null,
|
|
6910
6910
|
raw: false,
|
|
6911
|
-
...
|
|
6911
|
+
...json2.diagnostics ? { diagnostics: json2.diagnostics } : {}
|
|
6912
6912
|
};
|
|
6913
6913
|
}
|
|
6914
6914
|
const binding = parseBindingDiagnostics(cleaned);
|
|
@@ -8448,8 +8448,8 @@ async function resolveSession(sessionFlag, command) {
|
|
|
8448
8448
|
}
|
|
8449
8449
|
function rebuildDTCGTree(groups, tokens) {
|
|
8450
8450
|
const root = {};
|
|
8451
|
-
for (const
|
|
8452
|
-
const segments =
|
|
8451
|
+
for (const group2 of groups) {
|
|
8452
|
+
const segments = group2.path.split(".");
|
|
8453
8453
|
let node = root;
|
|
8454
8454
|
for (const seg of segments) {
|
|
8455
8455
|
if (typeof node[seg] !== "object" || node[seg] === null) {
|
|
@@ -8457,8 +8457,8 @@ function rebuildDTCGTree(groups, tokens) {
|
|
|
8457
8457
|
}
|
|
8458
8458
|
node = node[seg];
|
|
8459
8459
|
}
|
|
8460
|
-
if (
|
|
8461
|
-
node["$description"] =
|
|
8460
|
+
if (group2.$description) {
|
|
8461
|
+
node["$description"] = group2.$description;
|
|
8462
8462
|
}
|
|
8463
8463
|
}
|
|
8464
8464
|
for (const token of tokens) {
|
|
@@ -9204,18 +9204,27 @@ var init_run_teaser = __esm({
|
|
|
9204
9204
|
// packages/experience-design-system-cli-legacy/src/lib/push-debug-log.ts
|
|
9205
9205
|
import { existsSync as existsSync3, mkdirSync as mkdirSync3, readdirSync, writeFileSync } from "node:fs";
|
|
9206
9206
|
import { join as join10 } from "node:path";
|
|
9207
|
-
function scrub(
|
|
9208
|
-
if (/^cma_?token$/i.test(
|
|
9207
|
+
function scrub(key, value) {
|
|
9208
|
+
if (/^cma_?token$/i.test(key)) {
|
|
9209
9209
|
return typeof value === "string" && value ? `[present, ${value.length} chars]` : "[not set]";
|
|
9210
|
+
}
|
|
9210
9211
|
if (typeof value === "string" && SECRET_VALUE.test(value)) return "[redacted]";
|
|
9211
9212
|
return value;
|
|
9212
9213
|
}
|
|
9213
|
-
function
|
|
9214
|
-
|
|
9214
|
+
function json(value) {
|
|
9215
|
+
const text = JSON.stringify(value, scrub, 2) ?? "null";
|
|
9216
|
+
return text.length > MAX_BLOCK_CHARS ? `${text.slice(0, MAX_BLOCK_CHARS)}
|
|
9217
|
+
\u2026 truncated, ${text.length - MAX_BLOCK_CHARS} more characters` : text;
|
|
9218
|
+
}
|
|
9219
|
+
function pad(n, width = 2) {
|
|
9220
|
+
return String(n).padStart(width, "0");
|
|
9215
9221
|
}
|
|
9216
9222
|
function datePrefix(now) {
|
|
9217
9223
|
return `${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${now.getFullYear()}`;
|
|
9218
9224
|
}
|
|
9225
|
+
function clock(now) {
|
|
9226
|
+
return `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}.${pad(now.getMilliseconds(), 3)}`;
|
|
9227
|
+
}
|
|
9219
9228
|
function nextFilename(dir, now) {
|
|
9220
9229
|
const today = datePrefix(now);
|
|
9221
9230
|
const pattern = new RegExp(`^${today}-push-attempt-(\\d+)\\.md$`);
|
|
@@ -9226,59 +9235,176 @@ function nextFilename(dir, now) {
|
|
|
9226
9235
|
}, 0);
|
|
9227
9236
|
return `${today}-push-attempt-${max + 1}.md`;
|
|
9228
9237
|
}
|
|
9229
|
-
function
|
|
9230
|
-
|
|
9238
|
+
function entityName(entry) {
|
|
9239
|
+
if (typeof entry === "string") return entry;
|
|
9240
|
+
if (entry && typeof entry === "object") {
|
|
9241
|
+
const record = entry;
|
|
9242
|
+
for (const field of ["key", "name", "$name", "id"]) {
|
|
9243
|
+
if (typeof record[field] === "string") return record[field];
|
|
9244
|
+
}
|
|
9245
|
+
const current = record["current"];
|
|
9246
|
+
if (current && typeof current === "object" && typeof current["name"] === "string") {
|
|
9247
|
+
return current["name"];
|
|
9248
|
+
}
|
|
9249
|
+
}
|
|
9250
|
+
return "unknown";
|
|
9251
|
+
}
|
|
9252
|
+
function group(diff) {
|
|
9253
|
+
return {
|
|
9254
|
+
new: diff.new.map(entityName),
|
|
9255
|
+
changed: diff.changed.map((entry) => {
|
|
9256
|
+
const breaking = entry && typeof entry === "object" && entry.changeClassification?.classification === "breaking";
|
|
9257
|
+
return breaking ? `${entityName(entry)} (breaking)` : entityName(entry);
|
|
9258
|
+
}),
|
|
9259
|
+
unchanged: diff.unchanged,
|
|
9260
|
+
removed: diff.removed.map(entityName)
|
|
9261
|
+
};
|
|
9262
|
+
}
|
|
9263
|
+
function summarizePreview(preview) {
|
|
9264
|
+
return { components: group(preview.components), tokens: group(preview.tokens) };
|
|
9265
|
+
}
|
|
9266
|
+
function summarizeCdf(cdf) {
|
|
9267
|
+
return Object.entries(cdf).filter(([key]) => !key.startsWith("$") && key !== "allowDeletions").map(([key, value]) => {
|
|
9268
|
+
const entry = value ?? {};
|
|
9269
|
+
const properties = entry["$properties"];
|
|
9270
|
+
const slots = entry["$slots"];
|
|
9271
|
+
return {
|
|
9272
|
+
name: key,
|
|
9273
|
+
type: entry["$type"],
|
|
9274
|
+
properties: properties && typeof properties === "object" ? Object.keys(properties) : [],
|
|
9275
|
+
slots: slots && typeof slots === "object" ? Object.keys(slots) : []
|
|
9276
|
+
};
|
|
9277
|
+
});
|
|
9278
|
+
}
|
|
9279
|
+
function renderEvents(events) {
|
|
9280
|
+
if (events.length === 0) return "_Nothing recorded yet._";
|
|
9281
|
+
return events.map((event, index) => {
|
|
9282
|
+
const note = event.note ? ` \u2014 ${event.note}` : "";
|
|
9283
|
+
const request2 = event.requestId ? ` _(request ${event.requestId})_` : "";
|
|
9284
|
+
return `${index + 1}. \`${clock(event.at)}\` (+${event.sinceStartMs}ms) **${event.title}**${note}${request2}`;
|
|
9285
|
+
}).join("\n");
|
|
9286
|
+
}
|
|
9287
|
+
function renderDetails(events) {
|
|
9288
|
+
const withData = events.map((event, index) => ({ event, index })).filter(({ event }) => event.data && Object.keys(event.data).length > 0);
|
|
9289
|
+
if (withData.length === 0) return "";
|
|
9290
|
+
return withData.map(
|
|
9291
|
+
({ event, index }) => `<details>
|
|
9292
|
+
<summary>${index + 1}. ${event.title}</summary>
|
|
9293
|
+
|
|
9294
|
+
\`\`\`json
|
|
9295
|
+
${json(event.data)}
|
|
9296
|
+
\`\`\`
|
|
9297
|
+
|
|
9298
|
+
</details>`
|
|
9299
|
+
).join("\n\n");
|
|
9300
|
+
}
|
|
9301
|
+
function render2(runId, inputs, events, startedAt, result, durationMs) {
|
|
9302
|
+
const requestIds = [...new Set(events.map((event) => event.requestId).filter(Boolean))];
|
|
9303
|
+
const text = (field) => String(inputs[field] ?? "\u2014");
|
|
9304
|
+
const details = renderDetails(events);
|
|
9305
|
+
return `# Push to Contentful \u2014 debug log
|
|
9306
|
+
|
|
9307
|
+
## Summary
|
|
9308
|
+
|
|
9309
|
+
| | |
|
|
9310
|
+
|---|---|
|
|
9311
|
+
| **Result** | ${OUTCOME_LABEL[result.outcome]} |
|
|
9312
|
+
| **What happened** | ${result.summary} |
|
|
9313
|
+
| **Space / environment** | \`${text("space_id")}\` / \`${text("environment_id")}\` |
|
|
9314
|
+
| **Host** | ${text("host")} |
|
|
9315
|
+
| **Started** | ${startedAt.toISOString()} |
|
|
9316
|
+
| **Duration** | ${durationMs}ms |
|
|
9317
|
+
| **Request IDs** | ${requestIds.length > 0 ? requestIds.map((id) => `\`${id}\``).join(", ") : "\u2014"} |
|
|
9318
|
+
| **CLI / runtime** | ${cliVersion()} \xB7 ${process.platform} \xB7 Node ${process.version} |
|
|
9319
|
+
| **Run ID** | ${runId} |
|
|
9320
|
+
|
|
9321
|
+
## Timeline
|
|
9231
9322
|
|
|
9232
|
-
|
|
9233
|
-
- Flow: import
|
|
9234
|
-
- Step: 01 - push
|
|
9235
|
-
- Menu option: Push
|
|
9236
|
-
- Date: ${now.toISOString()}
|
|
9237
|
-
- CLI version: ${cliVersion()}
|
|
9238
|
-
- Platform: ${process.platform} / Node ${process.version}
|
|
9239
|
-
- Duration on screen: ${durationMs}ms
|
|
9240
|
-
- Status: ${status}
|
|
9241
|
-
- Exit method: completed
|
|
9323
|
+
${renderEvents(events)}
|
|
9242
9324
|
|
|
9243
9325
|
## Inputs
|
|
9326
|
+
|
|
9244
9327
|
\`\`\`json
|
|
9245
|
-
${
|
|
9328
|
+
${json(inputs)}
|
|
9246
9329
|
\`\`\`
|
|
9247
9330
|
|
|
9248
|
-
##
|
|
9331
|
+
## Result
|
|
9332
|
+
|
|
9249
9333
|
\`\`\`json
|
|
9250
|
-
${
|
|
9334
|
+
${json({ outcome: result.outcome, summary: result.summary, ...result.details ?? {} })}
|
|
9251
9335
|
\`\`\`
|
|
9252
|
-
|
|
9336
|
+
${details ? `
|
|
9337
|
+
## Details
|
|
9338
|
+
|
|
9339
|
+
${details}
|
|
9340
|
+
` : ""}`;
|
|
9253
9341
|
}
|
|
9254
9342
|
function startPushDebugRun(inputs) {
|
|
9255
9343
|
const sessionDir = process.env[DEBUG_SESSION_DIR_ENV];
|
|
9256
9344
|
if (!sessionDir) return NOOP_RUN;
|
|
9257
|
-
const startedAt = Date
|
|
9345
|
+
const startedAt = /* @__PURE__ */ new Date();
|
|
9346
|
+
const runId = `${startedAt.getFullYear()}${pad(startedAt.getMonth() + 1)}${pad(startedAt.getDate())}-${pad(startedAt.getHours())}${pad(startedAt.getMinutes())}${pad(startedAt.getSeconds())}`;
|
|
9347
|
+
const events = [];
|
|
9348
|
+
let result = {
|
|
9349
|
+
outcome: "in-progress",
|
|
9350
|
+
summary: "The push started but no final result was recorded."
|
|
9351
|
+
};
|
|
9258
9352
|
let finished = false;
|
|
9259
|
-
|
|
9260
|
-
|
|
9261
|
-
|
|
9262
|
-
|
|
9263
|
-
try {
|
|
9264
|
-
const now = /* @__PURE__ */ new Date();
|
|
9353
|
+
let path;
|
|
9354
|
+
const flush = () => {
|
|
9355
|
+
try {
|
|
9356
|
+
if (!path) {
|
|
9265
9357
|
const dir = join10(sessionDir, "import");
|
|
9266
9358
|
mkdirSync3(dir, { recursive: true });
|
|
9267
|
-
|
|
9268
|
-
const content = render2(runId, inputs, outputs, status, Date.now() - startedAt, now);
|
|
9269
|
-
writeFileSync(join10(dir, nextFilename(dir, now)), content, { mode: 384 });
|
|
9270
|
-
} catch {
|
|
9359
|
+
path = join10(dir, nextFilename(dir, startedAt));
|
|
9271
9360
|
}
|
|
9361
|
+
writeFileSync(path, render2(runId, inputs, events, startedAt, result, Date.now() - startedAt.getTime()), {
|
|
9362
|
+
mode: 384
|
|
9363
|
+
});
|
|
9364
|
+
} catch {
|
|
9365
|
+
}
|
|
9366
|
+
};
|
|
9367
|
+
flush();
|
|
9368
|
+
return {
|
|
9369
|
+
event(title, options = {}) {
|
|
9370
|
+
if (finished) return;
|
|
9371
|
+
const at = /* @__PURE__ */ new Date();
|
|
9372
|
+
events.push({ at, sinceStartMs: at.getTime() - startedAt.getTime(), title, ...options });
|
|
9373
|
+
flush();
|
|
9374
|
+
},
|
|
9375
|
+
finish(final) {
|
|
9376
|
+
if (finished) return;
|
|
9377
|
+
finished = true;
|
|
9378
|
+
result = final;
|
|
9379
|
+
const at = /* @__PURE__ */ new Date();
|
|
9380
|
+
events.push({
|
|
9381
|
+
at,
|
|
9382
|
+
sinceStartMs: at.getTime() - startedAt.getTime(),
|
|
9383
|
+
title: OUTCOME_LABEL[final.outcome].replace(/^\S+\s/, ""),
|
|
9384
|
+
note: final.summary
|
|
9385
|
+
});
|
|
9386
|
+
flush();
|
|
9272
9387
|
}
|
|
9273
9388
|
};
|
|
9274
9389
|
}
|
|
9275
|
-
var DEBUG_SESSION_DIR_ENV, NOOP_RUN, SECRET_VALUE;
|
|
9390
|
+
var DEBUG_SESSION_DIR_ENV, NOOP_RUN, OUTCOME_LABEL, MAX_BLOCK_CHARS, SECRET_VALUE;
|
|
9276
9391
|
var init_push_debug_log = __esm({
|
|
9277
9392
|
"packages/experience-design-system-cli-legacy/src/lib/push-debug-log.ts"() {
|
|
9278
9393
|
"use strict";
|
|
9279
9394
|
init_client();
|
|
9280
9395
|
DEBUG_SESSION_DIR_ENV = "EDS_DEBUG_SESSION_DIR";
|
|
9281
|
-
NOOP_RUN = { finish: () => void 0 };
|
|
9396
|
+
NOOP_RUN = { event: () => void 0, finish: () => void 0 };
|
|
9397
|
+
OUTCOME_LABEL = {
|
|
9398
|
+
"in-progress": "\u23F3 In progress (the process ended before the push finished)",
|
|
9399
|
+
pushed: "\u2705 Pushed",
|
|
9400
|
+
partial: "\u26A0\uFE0F Partly pushed (some items failed)",
|
|
9401
|
+
failed: "\u274C Push failed",
|
|
9402
|
+
"preview-failed": "\u274C Preview failed (nothing was sent to apply)",
|
|
9403
|
+
"nothing-to-push": "\u2139\uFE0F Nothing to push (the server says the space already matches)",
|
|
9404
|
+
skipped: "\u23ED\uFE0F Skipped",
|
|
9405
|
+
superseded: "\u21A9\uFE0F Superseded by a newer attempt"
|
|
9406
|
+
};
|
|
9407
|
+
MAX_BLOCK_CHARS = 1e5;
|
|
9282
9408
|
SECRET_VALUE = /CFPAT-[A-Za-z0-9_-]{20,}|^Bearer\s+\S+/;
|
|
9283
9409
|
}
|
|
9284
9410
|
});
|
|
@@ -20208,17 +20334,17 @@ function buildCycleUnits(slotCycles) {
|
|
|
20208
20334
|
const groups = /* @__PURE__ */ new Map();
|
|
20209
20335
|
for (const node of parent.keys()) {
|
|
20210
20336
|
const root = find(node);
|
|
20211
|
-
let
|
|
20212
|
-
if (!
|
|
20213
|
-
|
|
20214
|
-
groups.set(root,
|
|
20337
|
+
let group2 = groups.get(root);
|
|
20338
|
+
if (!group2) {
|
|
20339
|
+
group2 = /* @__PURE__ */ new Set();
|
|
20340
|
+
groups.set(root, group2);
|
|
20215
20341
|
}
|
|
20216
|
-
|
|
20342
|
+
group2.add(node);
|
|
20217
20343
|
}
|
|
20218
20344
|
const out = /* @__PURE__ */ new Map();
|
|
20219
|
-
for (const
|
|
20220
|
-
for (const node of
|
|
20221
|
-
out.set(node,
|
|
20345
|
+
for (const group2 of groups.values()) {
|
|
20346
|
+
for (const node of group2) {
|
|
20347
|
+
out.set(node, group2);
|
|
20222
20348
|
}
|
|
20223
20349
|
}
|
|
20224
20350
|
return out;
|
|
@@ -21712,10 +21838,10 @@ function swapValues(values, firstIndex, secondIndex) {
|
|
|
21712
21838
|
[next[firstIndex], next[secondIndex]] = [next[secondIndex], next[firstIndex]];
|
|
21713
21839
|
return next;
|
|
21714
21840
|
}
|
|
21715
|
-
function parseToState(
|
|
21841
|
+
function parseToState(json2) {
|
|
21716
21842
|
let parsed;
|
|
21717
21843
|
try {
|
|
21718
|
-
parsed = JSON.parse(
|
|
21844
|
+
parsed = JSON.parse(json2);
|
|
21719
21845
|
} catch (e) {
|
|
21720
21846
|
return {
|
|
21721
21847
|
state: { componentDescription: "", props: [], slots: [] },
|
|
@@ -22568,11 +22694,11 @@ function FieldEditor({
|
|
|
22568
22694
|
setEditorState(next);
|
|
22569
22695
|
onChange(serializeState(next, value));
|
|
22570
22696
|
};
|
|
22571
|
-
const canonicalize = React14.useCallback((
|
|
22697
|
+
const canonicalize = React14.useCallback((json2) => {
|
|
22572
22698
|
try {
|
|
22573
|
-
return JSON.stringify(JSON.parse(
|
|
22699
|
+
return JSON.stringify(JSON.parse(json2));
|
|
22574
22700
|
} catch {
|
|
22575
|
-
return `__unparseable__:${
|
|
22701
|
+
return `__unparseable__:${json2}`;
|
|
22576
22702
|
}
|
|
22577
22703
|
}, []);
|
|
22578
22704
|
const initialStateRef = React14.useRef(initialState);
|
|
@@ -23146,14 +23272,14 @@ function FieldEditor({
|
|
|
23146
23272
|
})();
|
|
23147
23273
|
const rows = [];
|
|
23148
23274
|
rows.push({ kind: "component-description" });
|
|
23149
|
-
for (const
|
|
23150
|
-
if (
|
|
23275
|
+
for (const group2 of propGroups.filter((candidate) => candidate.kind !== "hidden")) {
|
|
23276
|
+
if (group2.indexes.length === 0) continue;
|
|
23151
23277
|
rows.push({
|
|
23152
23278
|
kind: "header",
|
|
23153
|
-
label: `${
|
|
23154
|
-
section:
|
|
23279
|
+
label: `${group2.label} (${group2.indexes.length}) `,
|
|
23280
|
+
section: group2.kind
|
|
23155
23281
|
});
|
|
23156
|
-
|
|
23282
|
+
group2.indexes.forEach((idx) => rows.push({ kind: "prop", idx }));
|
|
23157
23283
|
}
|
|
23158
23284
|
if (slots.length > 0) {
|
|
23159
23285
|
rows.push({
|
|
@@ -23163,7 +23289,7 @@ function FieldEditor({
|
|
|
23163
23289
|
});
|
|
23164
23290
|
slots.forEach((_, i) => rows.push({ kind: "slot", idx: i }));
|
|
23165
23291
|
}
|
|
23166
|
-
const hiddenGroup = propGroups.find((
|
|
23292
|
+
const hiddenGroup = propGroups.find((group2) => group2.kind === "hidden");
|
|
23167
23293
|
if (hiddenGroup && hiddenGroup.indexes.length > 0) {
|
|
23168
23294
|
rows.push({
|
|
23169
23295
|
kind: "header",
|
|
@@ -27287,6 +27413,7 @@ function WizardApp({
|
|
|
27287
27413
|
tokensPath: ""
|
|
27288
27414
|
});
|
|
27289
27415
|
const allowEmptyDeleteAllRef = useRef10(false);
|
|
27416
|
+
const pushDebugRef = useRef10(null);
|
|
27290
27417
|
const generateChildRef = useRef10(null);
|
|
27291
27418
|
const generationCachePreflightRef = useRef10(null);
|
|
27292
27419
|
const selectionToReviewStartedAtRef = useRef10(null);
|
|
@@ -28341,12 +28468,30 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28341
28468
|
void runSaveAndPush();
|
|
28342
28469
|
};
|
|
28343
28470
|
const runPreview = async (extractSessionId, tokensPath, spaceId, environmentId, cmaToken, host2) => {
|
|
28471
|
+
const resolvedHost = resolveWizardHost(host2);
|
|
28472
|
+
pushDebugRef.current?.finish({
|
|
28473
|
+
outcome: "superseded",
|
|
28474
|
+
summary: "A new push attempt started before this one finished."
|
|
28475
|
+
});
|
|
28476
|
+
const pushDebug = startPushDebugRun({
|
|
28477
|
+
space_id: spaceId,
|
|
28478
|
+
environment_id: environmentId,
|
|
28479
|
+
host: resolvedHost,
|
|
28480
|
+
cma_token: cmaToken,
|
|
28481
|
+
extract_session_id: extractSessionId,
|
|
28482
|
+
tokens_file: tokensPath || null,
|
|
28483
|
+
delete_everything_not_listed: allowEmptyDeleteAllRef.current
|
|
28484
|
+
});
|
|
28485
|
+
pushDebugRef.current = pushDebug;
|
|
28344
28486
|
if (shouldBypassPreview(state)) {
|
|
28487
|
+
pushDebug.finish({
|
|
28488
|
+
outcome: "skipped",
|
|
28489
|
+
summary: "Credentials were skipped, so nothing is previewed or pushed. Files were saved only."
|
|
28490
|
+
});
|
|
28345
28491
|
update(buildSkippedPreviewTransition());
|
|
28346
28492
|
return;
|
|
28347
28493
|
}
|
|
28348
28494
|
update({ step: "previewing" });
|
|
28349
|
-
const resolvedHost = resolveWizardHost(host2);
|
|
28350
28495
|
try {
|
|
28351
28496
|
const client2 = new ImportApiClient({
|
|
28352
28497
|
cmaToken,
|
|
@@ -28354,6 +28499,7 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28354
28499
|
environmentId,
|
|
28355
28500
|
host: resolvedHost
|
|
28356
28501
|
});
|
|
28502
|
+
pushDebug.event("Preview started", { note: `POST ${resolvedHost}/\u2026/design_systems/imports/preview` });
|
|
28357
28503
|
let components = [];
|
|
28358
28504
|
if (extractSessionId) {
|
|
28359
28505
|
const db = openPipelineDb();
|
|
@@ -28369,7 +28515,16 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28369
28515
|
tokens = await readTokensFromPath("tokens", tokensPath);
|
|
28370
28516
|
}
|
|
28371
28517
|
let cdf = buildCDF3(components, toCDFTokens(tokens), { deleteAll: allowEmptyDeleteAllRef.current });
|
|
28518
|
+
pushDebug.event("Built the CDF to send", {
|
|
28519
|
+
note: `${summarizeCdf(cdf).length} entries`,
|
|
28520
|
+
data: { entries: summarizeCdf(cdf), tokens_loaded: tokens.length }
|
|
28521
|
+
});
|
|
28372
28522
|
let preview = await client2.previewImport(cdf);
|
|
28523
|
+
pushDebug.event("Server previewed the CDF", {
|
|
28524
|
+
note: "what the server would create, change, leave alone or remove",
|
|
28525
|
+
data: summarizePreview(preview),
|
|
28526
|
+
requestId: client2.getLastRequestId()
|
|
28527
|
+
});
|
|
28373
28528
|
if (extractSessionId) {
|
|
28374
28529
|
let needsRepreview = false;
|
|
28375
28530
|
const db = openPipelineDb();
|
|
@@ -28389,15 +28544,27 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28389
28544
|
if (seededDefaults > 0) needsRepreview = true;
|
|
28390
28545
|
}
|
|
28391
28546
|
if (needsRepreview) {
|
|
28547
|
+
pushDebug.event("Re-previewing", {
|
|
28548
|
+
note: "the server listed components as removed or changed that exist locally, so defaults were filled in"
|
|
28549
|
+
});
|
|
28392
28550
|
components = loadCDFComponents(db, extractSessionId);
|
|
28393
28551
|
cdf = buildCDF3(components, toCDFTokens(tokens), { deleteAll: allowEmptyDeleteAllRef.current });
|
|
28394
28552
|
preview = await client2.previewImport(cdf);
|
|
28553
|
+
pushDebug.event("Server previewed the updated CDF", {
|
|
28554
|
+
data: summarizePreview(preview),
|
|
28555
|
+
requestId: client2.getLastRequestId()
|
|
28556
|
+
});
|
|
28395
28557
|
}
|
|
28396
28558
|
} finally {
|
|
28397
28559
|
db.close();
|
|
28398
28560
|
}
|
|
28399
28561
|
}
|
|
28400
28562
|
if (isEmptyPreview(preview)) {
|
|
28563
|
+
pushDebug.finish({
|
|
28564
|
+
outcome: "nothing-to-push",
|
|
28565
|
+
summary: "The server says every component and token in the CDF already matches what is in this space, so no apply request was sent. If the space looks empty, check that this is the space and environment you are viewing.",
|
|
28566
|
+
details: { preview: summarizePreview(preview), request_id: client2.getLastRequestId() }
|
|
28567
|
+
});
|
|
28401
28568
|
update({
|
|
28402
28569
|
step: "done",
|
|
28403
28570
|
serverPreview: preview,
|
|
@@ -28409,6 +28576,9 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28409
28576
|
});
|
|
28410
28577
|
return;
|
|
28411
28578
|
}
|
|
28579
|
+
pushDebug.event("Waiting for confirmation", {
|
|
28580
|
+
note: "the preview shows changes, so the wizard asks before pushing"
|
|
28581
|
+
});
|
|
28412
28582
|
update({
|
|
28413
28583
|
step: "preview-gate",
|
|
28414
28584
|
serverPreview: preview,
|
|
@@ -28417,6 +28587,11 @@ Make sure this path contains TypeScript/React/Vue component files (.tsx, .ts, .v
|
|
|
28417
28587
|
...clearedValidationErrorState()
|
|
28418
28588
|
});
|
|
28419
28589
|
} catch (e) {
|
|
28590
|
+
pushDebug.finish({
|
|
28591
|
+
outcome: "preview-failed",
|
|
28592
|
+
summary: e instanceof ApiError ? `The preview request was rejected with HTTP ${e.status}.` : `The preview failed before the server answered: ${e instanceof Error ? e.message : String(e)}`,
|
|
28593
|
+
details: e instanceof ApiError ? { status: e.status, body: (e.body ?? "").slice(0, 4e3) } : { error: e instanceof Error ? e.message : String(e) }
|
|
28594
|
+
});
|
|
28420
28595
|
if (e instanceof ApiError) {
|
|
28421
28596
|
if (e.status === 401 || e.status === 403) {
|
|
28422
28597
|
let bodyMsg = "";
|
|
@@ -28479,7 +28654,18 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28479
28654
|
}
|
|
28480
28655
|
};
|
|
28481
28656
|
const runPush = async (cdf, spaceId, environmentId, cmaToken, host2, acknowledgeBreakingChanges, preview) => {
|
|
28657
|
+
const pushDebug = pushDebugRef.current ?? startPushDebugRun({
|
|
28658
|
+
space_id: spaceId,
|
|
28659
|
+
environment_id: environmentId,
|
|
28660
|
+
host: resolveWizardHost(host2),
|
|
28661
|
+
cma_token: cmaToken
|
|
28662
|
+
});
|
|
28663
|
+
pushDebugRef.current = pushDebug;
|
|
28482
28664
|
if (shouldRefusePush(state)) {
|
|
28665
|
+
pushDebug.finish({
|
|
28666
|
+
outcome: "skipped",
|
|
28667
|
+
summary: "Credentials were skipped, so the push was refused. Files were saved only."
|
|
28668
|
+
});
|
|
28483
28669
|
update(buildSkippedPushTransition());
|
|
28484
28670
|
return;
|
|
28485
28671
|
}
|
|
@@ -28487,6 +28673,11 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28487
28673
|
const hasComponentChanges = preview.components.new.length > 0 || preview.components.changed.length > 0 || preview.components.removed.length > 0;
|
|
28488
28674
|
const hasTokenChanges = preview.tokens.new.length > 0 || preview.tokens.changed.length > 0 || preview.tokens.removed.length > 0;
|
|
28489
28675
|
if (!hasComponentChanges && !hasTokenChanges) {
|
|
28676
|
+
pushDebug.finish({
|
|
28677
|
+
outcome: "nothing-to-push",
|
|
28678
|
+
summary: "The preview had no new, changed or removed items, so no apply request was sent.",
|
|
28679
|
+
details: { preview: summarizePreview(preview) }
|
|
28680
|
+
});
|
|
28490
28681
|
update({
|
|
28491
28682
|
step: "done",
|
|
28492
28683
|
pushResult: {
|
|
@@ -28499,6 +28690,11 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28499
28690
|
}
|
|
28500
28691
|
const cycles = detectSlotCycles(extractComponents(cdf));
|
|
28501
28692
|
if (cycles.length > 0) {
|
|
28693
|
+
pushDebug.finish({
|
|
28694
|
+
outcome: "failed",
|
|
28695
|
+
summary: "The push was blocked locally because components slot each other in a cycle.",
|
|
28696
|
+
details: { cycles: formatSlotCycleReport(cycles) }
|
|
28697
|
+
});
|
|
28502
28698
|
update({
|
|
28503
28699
|
step: "error",
|
|
28504
28700
|
errorStep: "apply",
|
|
@@ -28509,6 +28705,11 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28509
28705
|
}
|
|
28510
28706
|
const unresolvedSlotReferences = validateSlotReferences2(extractComponents(cdf));
|
|
28511
28707
|
if (unresolvedSlotReferences.length > 0) {
|
|
28708
|
+
pushDebug.finish({
|
|
28709
|
+
outcome: "failed",
|
|
28710
|
+
summary: "The push was blocked locally because a slot refers to a component that is not in the CDF.",
|
|
28711
|
+
details: { unresolved: formatUnresolvedSlotReferences(unresolvedSlotReferences) }
|
|
28712
|
+
});
|
|
28512
28713
|
update({
|
|
28513
28714
|
step: "error",
|
|
28514
28715
|
errorStep: "apply",
|
|
@@ -28518,27 +28719,13 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28518
28719
|
return;
|
|
28519
28720
|
}
|
|
28520
28721
|
update({ step: "pushing", pushProgress: null, errorAllowBreakingChangeAcknowledgment: false });
|
|
28521
|
-
|
|
28522
|
-
|
|
28523
|
-
|
|
28524
|
-
|
|
28525
|
-
|
|
28526
|
-
|
|
28527
|
-
|
|
28528
|
-
cdf_keys: cdfEntries.map(([key]) => key),
|
|
28529
|
-
cdf_entry_count: cdfEntries.length,
|
|
28530
|
-
preview: preview ? {
|
|
28531
|
-
components: {
|
|
28532
|
-
new: preview.components.new.length,
|
|
28533
|
-
changed: preview.components.changed.length,
|
|
28534
|
-
removed: preview.components.removed.length
|
|
28535
|
-
},
|
|
28536
|
-
tokens: {
|
|
28537
|
-
new: preview.tokens.new.length,
|
|
28538
|
-
changed: preview.tokens.changed.length,
|
|
28539
|
-
removed: preview.tokens.removed.length
|
|
28540
|
-
}
|
|
28541
|
-
} : null
|
|
28722
|
+
pushDebug.event("Apply started", {
|
|
28723
|
+
note: `POST ${resolveWizardHost(host2)}/\u2026/design_systems/imports/apply`,
|
|
28724
|
+
data: {
|
|
28725
|
+
acknowledge_breaking_changes: acknowledgeBreakingChanges,
|
|
28726
|
+
sending: summarizeCdf(cdf),
|
|
28727
|
+
expected: preview ? summarizePreview(preview) : null
|
|
28728
|
+
}
|
|
28542
28729
|
});
|
|
28543
28730
|
try {
|
|
28544
28731
|
const resolvedHost = resolveWizardHost(host2);
|
|
@@ -28549,6 +28736,11 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28549
28736
|
host: resolvedHost
|
|
28550
28737
|
});
|
|
28551
28738
|
let operation = await client2.applyImport(cdf, { acknowledgeBreakingChanges });
|
|
28739
|
+
pushDebug.event("Server accepted the apply request", {
|
|
28740
|
+
note: `operation ${operation.sys.id} is ${operation.sys.status}`,
|
|
28741
|
+
data: { operation_id: operation.sys.id, status: operation.sys.status, summary: operation.summary },
|
|
28742
|
+
requestId: client2.getLastRequestId()
|
|
28743
|
+
});
|
|
28552
28744
|
try {
|
|
28553
28745
|
logStep({
|
|
28554
28746
|
applyResponse: {
|
|
@@ -28565,9 +28757,15 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28565
28757
|
pushProgress: { kind: "queued", operationId: operation.sys.id }
|
|
28566
28758
|
});
|
|
28567
28759
|
let pollCount = 0;
|
|
28760
|
+
let lastPolledStatus = "";
|
|
28568
28761
|
operation = await client2.pollOperation(operation.sys.id, {
|
|
28569
28762
|
onProgress: (op) => {
|
|
28570
28763
|
pollCount++;
|
|
28764
|
+
const polled = `${op.sys.status} ${op.summary ? `${op.summary.total - op.summary.pending}/${op.summary.total}` : ""}`;
|
|
28765
|
+
if (polled !== lastPolledStatus) {
|
|
28766
|
+
lastPolledStatus = polled;
|
|
28767
|
+
pushDebug.event("Operation status changed", { note: polled.trim(), requestId: client2.getLastRequestId() });
|
|
28768
|
+
}
|
|
28571
28769
|
const s = op.summary;
|
|
28572
28770
|
if (s) {
|
|
28573
28771
|
const done = s.total - s.pending;
|
|
@@ -28672,27 +28870,29 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28672
28870
|
);
|
|
28673
28871
|
}
|
|
28674
28872
|
}
|
|
28675
|
-
|
|
28676
|
-
|
|
28873
|
+
const failedItems = items.filter((item) => item.status === "failed");
|
|
28874
|
+
const pushedCount = items.filter((item) => item.status === "succeeded").length;
|
|
28875
|
+
pushDebug.finish({
|
|
28876
|
+
outcome: pushSucceeded ? "pushed" : pushedCount > 0 ? "partial" : "failed",
|
|
28877
|
+
summary: pushSucceeded ? items.length > 0 ? `The server reports ${pushedCount} of ${items.length} items applied.` : `The operation finished as ${operation.sys.status}, but the server returned no per-item results, so the counts come from the preview.` : `The operation finished as ${operation.sys.status}; ${failedItems.length} item(s) failed.`,
|
|
28878
|
+
details: {
|
|
28677
28879
|
operation_id: operation.sys.id,
|
|
28678
28880
|
operation_status: operation.sys.status,
|
|
28679
|
-
|
|
28680
|
-
item_count: items.length,
|
|
28881
|
+
server_summary: operation.summary,
|
|
28681
28882
|
items: items.map((item) => ({
|
|
28682
|
-
|
|
28883
|
+
type: item.entityType,
|
|
28683
28884
|
id: item.id,
|
|
28684
28885
|
action: item.action,
|
|
28685
28886
|
status: item.status,
|
|
28686
28887
|
...item.error ? { error: formatEdsiError(item.error) } : {}
|
|
28687
28888
|
})),
|
|
28688
|
-
|
|
28889
|
+
shown_to_user: {
|
|
28689
28890
|
component_types: pushResult.componentTypes,
|
|
28690
28891
|
design_tokens: pushResult.designTokens
|
|
28691
28892
|
},
|
|
28692
|
-
|
|
28693
|
-
}
|
|
28694
|
-
|
|
28695
|
-
);
|
|
28893
|
+
request_id: client2.getLastRequestId()
|
|
28894
|
+
}
|
|
28895
|
+
});
|
|
28696
28896
|
update({ step: "done", pushResult });
|
|
28697
28897
|
} catch (e) {
|
|
28698
28898
|
let msg;
|
|
@@ -28703,13 +28903,14 @@ If using a custom host configuration, make sure the space exists on that host.`
|
|
|
28703
28903
|
} else {
|
|
28704
28904
|
msg = "Push failed";
|
|
28705
28905
|
}
|
|
28706
|
-
pushDebug.finish(
|
|
28707
|
-
|
|
28708
|
-
|
|
28709
|
-
|
|
28710
|
-
|
|
28711
|
-
|
|
28712
|
-
|
|
28906
|
+
pushDebug.finish({
|
|
28907
|
+
outcome: "failed",
|
|
28908
|
+
summary: e instanceof ApiError ? `The apply request failed with HTTP ${e.status}.` : `The apply request failed before the server answered: ${msg}`,
|
|
28909
|
+
details: {
|
|
28910
|
+
message: msg,
|
|
28911
|
+
...e instanceof ApiError ? { status: e.status, body: (e.body ?? "").slice(0, 4e3) } : {}
|
|
28912
|
+
}
|
|
28913
|
+
});
|
|
28713
28914
|
update({
|
|
28714
28915
|
step: "error",
|
|
28715
28916
|
errorStep: "apply",
|
|
@@ -1,11 +1,29 @@
|
|
|
1
|
+
import type { ServerPreviewResponse } from '@contentful/experience-design-system-types';
|
|
1
2
|
export declare const DEBUG_SESSION_DIR_ENV = "EDS_DEBUG_SESSION_DIR";
|
|
2
|
-
export type
|
|
3
|
+
export type PushOutcome = 'in-progress' | 'pushed' | 'partial' | 'failed' | 'preview-failed' | 'nothing-to-push' | 'skipped' | 'superseded';
|
|
4
|
+
export interface PushDebugResult {
|
|
5
|
+
outcome: PushOutcome;
|
|
6
|
+
/** One plain-English sentence that says what happened and why. */
|
|
7
|
+
summary: string;
|
|
8
|
+
details?: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
export interface PushDebugEventOptions {
|
|
11
|
+
note?: string;
|
|
12
|
+
data?: Record<string, unknown>;
|
|
13
|
+
requestId?: string;
|
|
14
|
+
}
|
|
3
15
|
export interface PushDebugRun {
|
|
4
|
-
|
|
16
|
+
event(title: string, options?: PushDebugEventOptions): void;
|
|
17
|
+
finish(result: PushDebugResult): void;
|
|
5
18
|
}
|
|
19
|
+
/** The server's preview, reduced to the names in each group so it is easy to read. */
|
|
20
|
+
export declare function summarizePreview(preview: ServerPreviewResponse): Record<string, unknown>;
|
|
21
|
+
/** The entries of a CDF that will be sent: name, type and the properties and slots each has. */
|
|
22
|
+
export declare function summarizeCdf(cdf: Record<string, unknown>): Array<Record<string, unknown>>;
|
|
6
23
|
/**
|
|
7
|
-
* Records the
|
|
8
|
-
*
|
|
9
|
-
*
|
|
24
|
+
* Records the push step (preview, confirmation and apply) in the v2 debug session folder.
|
|
25
|
+
* The file is rewritten after every event, so a push that dies partway still leaves a log.
|
|
26
|
+
* It does nothing unless the v2 CLI set EDS_DEBUG_SESSION_DIR, which it only does when
|
|
27
|
+
* Debug Mode is on. Logging never throws.
|
|
10
28
|
*/
|
|
11
29
|
export declare function startPushDebugRun(inputs: Record<string, unknown>): PushDebugRun;
|
package/legacy/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experience-design-system-cli",
|
|
3
|
-
"version": "2.35.1-dev-build-
|
|
3
|
+
"version": "2.35.1-dev-build-57c625cc.0",
|
|
4
4
|
"description": "Contentful Experiences design system import CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"svelte": "^5.56.4",
|
|
42
42
|
"ts-morph": "^27.0.2",
|
|
43
43
|
"typescript": "^5.9.3",
|
|
44
|
-
"@contentful/experience-design-system-types": "2.35.1-dev-build-
|
|
44
|
+
"@contentful/experience-design-system-types": "2.35.1-dev-build-57c625cc.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@tsconfig/node24": "^24.0.4",
|