fix(cli): retain nested facts in Markdown tables
This commit is contained in:
1 parent
a4e9b61e9f
commit
3f5d879414
3 files changed
+63
-5
No files matched your search
+3
-1
@@ -796,7 +796,9 @@ operation status.
|
||||
|
||||
`--format md` escapes backslashes and pipes in table headers and cells, and
|
||||
renders cell line breaks as `<br>`. These are presentation changes; retained
|
||||
Evidence and JSON output keep the original values. Table widths are measured
|
||||
Evidence and JSON output keep the original values. Nested objects and arrays
|
||||
use JSON inside their owning Markdown cells, retaining the field names and
|
||||
values instead of replacing them with an object label. Table widths are measured
|
||||
iteratively, so an admitted row page is not limited by the JavaScript function
|
||||
argument count.
|
||||
|
||||
|
||||
@@ -77,10 +77,18 @@ const renderTable = (
|
||||
return lines.join("\n");
|
||||
};
|
||||
|
||||
/** Keep nested JSON facts inside their owning table cell. */
|
||||
const markdownCell = (value: unknown): string =>
|
||||
value !== null && typeof value === "object"
|
||||
? JSON.stringify(value)
|
||||
: value === undefined
|
||||
? ""
|
||||
: String(value);
|
||||
|
||||
const formatKeyValueTable = (value: Record<string, unknown>): string =>
|
||||
renderTable(
|
||||
["Key", "Value"],
|
||||
Object.entries(value).map(([key, child]) => [key, String(child)]),
|
||||
Object.entries(value).map(([key, child]) => [key, markdownCell(child)]),
|
||||
);
|
||||
|
||||
const formatObjectTable = (
|
||||
@@ -96,7 +104,7 @@ const formatObjectTable = (
|
||||
}
|
||||
return renderTable(
|
||||
headers,
|
||||
items.map((item) => headers.map((key) => String(item[key] ?? ""))),
|
||||
items.map((item) => headers.map((key) => markdownCell(item[key]))),
|
||||
);
|
||||
};
|
||||
|
||||
@@ -114,7 +122,7 @@ const formatMarkdown = (
|
||||
const table = formatObjectTable(value);
|
||||
return path.length === 0 ? table : `## ${path.join(".")}\n\n${table}`;
|
||||
}
|
||||
return formatMarkdown(String(value), path);
|
||||
return formatMarkdown(markdownCell(value), path);
|
||||
}
|
||||
|
||||
const object = value as Record<string, unknown>;
|
||||
@@ -144,7 +152,7 @@ const formatMarkdown = (
|
||||
? `${heading}${formatKeyValueTable(nested)}`
|
||||
: formatMarkdown(nested, childPath);
|
||||
}
|
||||
return `${heading}${String(child)}`;
|
||||
return `${heading}${markdownCell(child)}`;
|
||||
})
|
||||
.join("\n\n");
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
import { join } from "node:path";
|
||||
import { expect, it } from "vitest";
|
||||
|
||||
import { renderCliDocument } from "../../../src/cliOutput.js";
|
||||
import { writeOrderedZip } from "../../fixtures/artifactEntryOrder.js";
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
import { workspaceCliTest } from "../../support/cli/workspaceCliFixture.js";
|
||||
|
||||
it("retains nested facts in standalone Markdown table cells and mixed arrays", () => {
|
||||
const value = [
|
||||
{
|
||||
details: { path: "alpha.txt" },
|
||||
entries: [{ path: "sub/beta.txt" }],
|
||||
mixed: ["selected", { nested: "caller|value" }],
|
||||
},
|
||||
];
|
||||
const markdown = renderCliDocument(value, "md", false);
|
||||
expect(markdown).toContain('{"path":"alpha.txt"}');
|
||||
expect(markdown).toContain('[{"path":"sub/beta.txt"}]');
|
||||
expect(markdown).toContain("caller\\|value");
|
||||
expect(markdown).not.toContain("[object Object]");
|
||||
expect(
|
||||
renderCliDocument({ mixed: [1, { path: "retained" }] }, "md", false),
|
||||
).toContain('{"path":"retained"}');
|
||||
expect(JSON.parse(renderCliDocument(value, "json", false))).toEqual(value);
|
||||
});
|
||||
|
||||
workspaceCliTest(
|
||||
"preserves archive inventory facts through public Markdown and JSON output",
|
||||
async ({ cli }) => {
|
||||
const root = await createTestTempDirectory("rea-markdown-archive-facts-");
|
||||
const archive = join(root, "fixture.zip");
|
||||
await writeOrderedZip(archive, ["alpha.txt", "sub/beta.txt"]);
|
||||
const markdown = await cli.run({
|
||||
arguments: ["inspect-artifact", archive, "--format", "md"],
|
||||
});
|
||||
const json = await cli.run({
|
||||
arguments: ["inspect-artifact", archive, "--json"],
|
||||
});
|
||||
expect(markdown.exitCode).toBe(0);
|
||||
expect(json.exitCode).toBe(0);
|
||||
for (const entry of ["alpha.txt", "sub/beta.txt"]) {
|
||||
expect(markdown.stdout).toContain(entry);
|
||||
expect(json.stdout).toContain(entry);
|
||||
}
|
||||
expect(markdown.stdout).not.toContain("[object Object]");
|
||||
},
|
||||
);
|
||||
Reference in new issue
Block a user