mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-08-23 14:52:18 +10:00
feat: add semantic CSS stylesheets (#3274)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor Agent
parent
4ac19f81b3
commit
d2ffbf9618
@@ -1,9 +1,28 @@
|
||||
// @vitest-environment happy-dom
|
||||
|
||||
import type { ResumeData } from "@reactive-resume/schema/resume/data";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { defaultResumeData } from "@reactive-resume/schema/resume/default";
|
||||
import { buildDocx } from "./index";
|
||||
|
||||
const createRendererUnsafeResumeData = (): ResumeData => {
|
||||
const data = structuredClone(defaultResumeData);
|
||||
data.customSections = [
|
||||
{
|
||||
id: "custom-experience",
|
||||
type: "experience",
|
||||
title: "Experience",
|
||||
icon: "",
|
||||
columns: 1,
|
||||
hidden: false,
|
||||
keepTogether: false,
|
||||
startOnNewPage: false,
|
||||
items: [{ id: "summary-shaped-item", hidden: false, content: "<p>Missing company</p>" }],
|
||||
} as never,
|
||||
];
|
||||
return data;
|
||||
};
|
||||
|
||||
describe("buildDocx", () => {
|
||||
it("returns a Blob for the default resume", async () => {
|
||||
const blob = await buildDocx(defaultResumeData);
|
||||
@@ -27,4 +46,42 @@ describe("buildDocx", () => {
|
||||
expect(promise).toBeInstanceOf(Promise);
|
||||
await expect(promise).rejects.toThrow();
|
||||
});
|
||||
|
||||
it("rejects renderer-unsafe data before DOCX builder dispatch", async () => {
|
||||
const error = await buildDocx(createRendererUnsafeResumeData()).catch((caught: unknown) => caught);
|
||||
|
||||
expect(error).toHaveProperty("issues.0.path", ["customSections", 0, "items", 0, "company"]);
|
||||
});
|
||||
|
||||
it("normalizes valid legacy data before DOCX building", async () => {
|
||||
const data = {
|
||||
...structuredClone(defaultResumeData),
|
||||
customSections: [
|
||||
{
|
||||
id: "custom-experience",
|
||||
type: "experience",
|
||||
title: "Experience",
|
||||
icon: "",
|
||||
columns: 1,
|
||||
hidden: false,
|
||||
keepTogether: false,
|
||||
startOnNewPage: false,
|
||||
items: [
|
||||
{
|
||||
id: "experience-item",
|
||||
hidden: false,
|
||||
company: "Analytical Engines",
|
||||
position: "Programmer",
|
||||
location: "London",
|
||||
period: "1842–1843",
|
||||
description: "<p>Wrote the first algorithm.</p>",
|
||||
content: "<p>Compatible overlap</p>",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
} as unknown as ResumeData;
|
||||
|
||||
await expect(buildDocx(data)).resolves.toBeInstanceOf(Blob);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { ResumeData } from "@reactive-resume/schema/resume/data";
|
||||
import type { SectionTitleResolver } from "./builder";
|
||||
import { Packer } from "docx";
|
||||
import { parseResumeData } from "@reactive-resume/schema/resume/data";
|
||||
import { buildDocument } from "./builder";
|
||||
|
||||
/**
|
||||
@@ -9,6 +10,6 @@ import { buildDocument } from "./builder";
|
||||
*/
|
||||
// biome-ignore lint/suspicious/useAwait: keep synchronous renderer errors on the public Promise rejection path.
|
||||
export async function buildDocx(data: ResumeData, resolveTitle?: SectionTitleResolver): Promise<Blob> {
|
||||
const doc = buildDocument(data, resolveTitle);
|
||||
const doc = buildDocument(parseResumeData(data), resolveTitle);
|
||||
return Packer.toBlob(doc);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user