Feat: subfile overrides (#2941)
* Adds overrides parameter to Packer methods and compiler * Adds tests for overrides parameter * Update Packer usage examples
This commit is contained in:
committed by
GitHub
parent
eb2174e566
commit
05fcf6edd4
@ -112,6 +112,41 @@ describe("Compiler", () => {
|
||||
},
|
||||
);
|
||||
|
||||
it(
|
||||
"should pack subfile overrides",
|
||||
async () => {
|
||||
const file = new File({
|
||||
sections: [],
|
||||
comments: {
|
||||
children: [],
|
||||
},
|
||||
});
|
||||
const subfileData1 = "comments";
|
||||
const subfileData2 = "commentsExtended";
|
||||
const overrides = [
|
||||
{ path: "word/comments.xml", data: subfileData1 },
|
||||
{ path: "word/commentsExtended.xml", data: subfileData2 },
|
||||
];
|
||||
const zipFile = compiler.compile(file, "", overrides);
|
||||
const fileNames = Object.keys(zipFile.files).map((f) => zipFile.files[f].name);
|
||||
|
||||
expect(fileNames).is.an.instanceof(Array);
|
||||
expect(fileNames).has.length(20);
|
||||
|
||||
expect(fileNames).to.include("word/comments.xml");
|
||||
expect(fileNames).to.include("word/commentsExtended.xml");
|
||||
|
||||
const commentsText = await zipFile.file("word/comments.xml")?.async("text");
|
||||
const commentsExtendedText = await zipFile.file("word/commentsExtended.xml")?.async("text");
|
||||
|
||||
expect(commentsText).toBe(subfileData1);
|
||||
expect(commentsExtendedText).toBe(subfileData2);
|
||||
},
|
||||
{
|
||||
timeout: 99999999,
|
||||
},
|
||||
);
|
||||
|
||||
it("should call the format method X times equalling X files to be formatted", () => {
|
||||
// This test is required because before, there was a case where Document was formatted twice, which was inefficient
|
||||
// This also caused issues such as running prepForXml multiple times as format() was ran multiple times.
|
||||
|
@ -9,7 +9,7 @@ import { ImageReplacer } from "./image-replacer";
|
||||
import { NumberingReplacer } from "./numbering-replacer";
|
||||
import { PrettifyType } from "./packer";
|
||||
|
||||
type IXmlifyedFile = {
|
||||
export type IXmlifyedFile = {
|
||||
readonly data: string;
|
||||
readonly path: string;
|
||||
};
|
||||
@ -47,7 +47,11 @@ export class Compiler {
|
||||
this.numberingReplacer = new NumberingReplacer();
|
||||
}
|
||||
|
||||
public compile(file: File, prettifyXml?: (typeof PrettifyType)[keyof typeof PrettifyType]): JSZip {
|
||||
public compile(
|
||||
file: File,
|
||||
prettifyXml?: (typeof PrettifyType)[keyof typeof PrettifyType],
|
||||
overrides: readonly IXmlifyedFile[] = [],
|
||||
): JSZip {
|
||||
const zip = new JSZip();
|
||||
const xmlifiedFileMapping = this.xmlifyFile(file, prettifyXml);
|
||||
const map = new Map<string, IXmlifyedFile | readonly IXmlifyedFile[]>(Object.entries(xmlifiedFileMapping));
|
||||
@ -62,6 +66,10 @@ export class Compiler {
|
||||
}
|
||||
}
|
||||
|
||||
for (const subFile of overrides) {
|
||||
zip.file(subFile.path, subFile.data);
|
||||
}
|
||||
|
||||
for (const data of file.Media.Array) {
|
||||
if (data.type !== "svg") {
|
||||
zip.file(`word/media/${data.fileName}`, data.data);
|
||||
|
@ -46,7 +46,7 @@ describe("Packer", () => {
|
||||
|
||||
await Packer.toString(file, true);
|
||||
|
||||
expect(spy).toBeCalledWith(expect.anything(), PrettifyType.WITH_2_BLANKS);
|
||||
expect(spy).toBeCalledWith(expect.anything(), PrettifyType.WITH_2_BLANKS, expect.anything());
|
||||
});
|
||||
|
||||
it("should use a prettify value", async () => {
|
||||
@ -55,7 +55,7 @@ describe("Packer", () => {
|
||||
|
||||
await Packer.toString(file, PrettifyType.WITH_4_BLANKS);
|
||||
|
||||
expect(spy).toBeCalledWith(expect.anything(), PrettifyType.WITH_4_BLANKS);
|
||||
expect(spy).toBeCalledWith(expect.anything(), PrettifyType.WITH_4_BLANKS, expect.anything());
|
||||
});
|
||||
|
||||
it("should use an undefined prettify value", async () => {
|
||||
@ -64,7 +64,32 @@ describe("Packer", () => {
|
||||
|
||||
await Packer.toString(file, false);
|
||||
|
||||
expect(spy).toBeCalledWith(expect.anything(), undefined);
|
||||
expect(spy).toBeCalledWith(expect.anything(), undefined, expect.anything());
|
||||
});
|
||||
});
|
||||
|
||||
describe("overrides", () => {
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("should use an overrides value", async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const spy = vi.spyOn((Packer as any).compiler, "compile");
|
||||
const overrides = [{ path: "word/comments.xml", data: "comments" }];
|
||||
|
||||
await Packer.toString(file, true, overrides);
|
||||
|
||||
expect(spy).toBeCalledWith(expect.anything(), expect.anything(), overrides);
|
||||
});
|
||||
|
||||
it("should use a default overrides value", async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const spy = vi.spyOn((Packer as any).compiler, "compile");
|
||||
|
||||
await Packer.toString(file);
|
||||
|
||||
expect(spy).toBeCalledWith(expect.anything(), undefined, []);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -2,7 +2,7 @@ import { Stream } from "stream";
|
||||
|
||||
import { File } from "@file/file";
|
||||
|
||||
import { Compiler } from "./next-compiler";
|
||||
import { Compiler, IXmlifyedFile } from "./next-compiler";
|
||||
|
||||
/**
|
||||
* Use blanks to prettify
|
||||
@ -21,8 +21,12 @@ const convertPrettifyType = (
|
||||
prettify === true ? PrettifyType.WITH_2_BLANKS : prettify === false ? undefined : prettify;
|
||||
|
||||
export class Packer {
|
||||
public static async toString(file: File, prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType]): Promise<string> {
|
||||
const zip = this.compiler.compile(file, convertPrettifyType(prettify));
|
||||
public static async toString(
|
||||
file: File,
|
||||
prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType],
|
||||
overrides: readonly IXmlifyedFile[] = [],
|
||||
): Promise<string> {
|
||||
const zip = this.compiler.compile(file, convertPrettifyType(prettify), overrides);
|
||||
const zipData = await zip.generateAsync({
|
||||
type: "string",
|
||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
@ -32,8 +36,12 @@ export class Packer {
|
||||
return zipData;
|
||||
}
|
||||
|
||||
public static async toBuffer(file: File, prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType]): Promise<Buffer> {
|
||||
const zip = this.compiler.compile(file, convertPrettifyType(prettify));
|
||||
public static async toBuffer(
|
||||
file: File,
|
||||
prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType],
|
||||
overrides: readonly IXmlifyedFile[] = [],
|
||||
): Promise<Buffer> {
|
||||
const zip = this.compiler.compile(file, convertPrettifyType(prettify), overrides);
|
||||
const zipData = await zip.generateAsync({
|
||||
type: "nodebuffer",
|
||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
@ -43,8 +51,12 @@ export class Packer {
|
||||
return zipData;
|
||||
}
|
||||
|
||||
public static async toBase64String(file: File, prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType]): Promise<string> {
|
||||
const zip = this.compiler.compile(file, convertPrettifyType(prettify));
|
||||
public static async toBase64String(
|
||||
file: File,
|
||||
prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType],
|
||||
overrides: readonly IXmlifyedFile[] = [],
|
||||
): Promise<string> {
|
||||
const zip = this.compiler.compile(file, convertPrettifyType(prettify), overrides);
|
||||
const zipData = await zip.generateAsync({
|
||||
type: "base64",
|
||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
@ -54,8 +66,12 @@ export class Packer {
|
||||
return zipData;
|
||||
}
|
||||
|
||||
public static async toBlob(file: File, prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType]): Promise<Blob> {
|
||||
const zip = this.compiler.compile(file, convertPrettifyType(prettify));
|
||||
public static async toBlob(
|
||||
file: File,
|
||||
prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType],
|
||||
overrides: readonly IXmlifyedFile[] = [],
|
||||
): Promise<Blob> {
|
||||
const zip = this.compiler.compile(file, convertPrettifyType(prettify), overrides);
|
||||
const zipData = await zip.generateAsync({
|
||||
type: "blob",
|
||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
@ -65,9 +81,13 @@ export class Packer {
|
||||
return zipData;
|
||||
}
|
||||
|
||||
public static toStream(file: File, prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType]): Stream {
|
||||
public static toStream(
|
||||
file: File,
|
||||
prettify?: boolean | (typeof PrettifyType)[keyof typeof PrettifyType],
|
||||
overrides: readonly IXmlifyedFile[] = [],
|
||||
): Stream {
|
||||
const stream = new Stream();
|
||||
const zip = this.compiler.compile(file, convertPrettifyType(prettify));
|
||||
const zip = this.compiler.compile(file, convertPrettifyType(prettify), overrides);
|
||||
|
||||
zip.generateAsync({
|
||||
type: "nodebuffer",
|
||||
|
Reference in New Issue
Block a user