Compare commits

...

33 Commits
8.0.0 ... 8.0.1

Author SHA1 Message Date
168e5e6e11 Version bump 2023-03-23 23:20:14 +00:00
ce71f19826 Merge pull request #2030 from dolanmiu/dependabot/npm_and_yarn/rimraf-4.4.1
build(deps-dev): bump rimraf from 4.4.0 to 4.4.1
2023-03-23 23:17:58 +00:00
4fd3f3a6b8 Merge pull request #2019 from dolanmiu/dependabot/npm_and_yarn/cspell-6.30.2
build(deps-dev): bump cspell from 6.30.0 to 6.30.2
2023-03-23 23:17:46 +00:00
39763d3869 Merge pull request #2023 from dolanmiu/dependabot/npm_and_yarn/typescript-eslint/parser-5.56.0
build(deps-dev): bump @typescript-eslint/parser from 5.55.0 to 5.56.0
2023-03-23 23:17:35 +00:00
36f90edc67 Merge pull request #2021 from dolanmiu/dependabot/npm_and_yarn/types/node-18.15.5
build(deps): bump @types/node from 18.15.3 to 18.15.5
2023-03-23 23:17:27 +00:00
b0cbd6f609 Merge pull request #2017 from dolanmiu/dependabot/npm_and_yarn/typedoc-0.23.28
build(deps-dev): bump typedoc from 0.23.27 to 0.23.28
2023-03-23 23:17:18 +00:00
d23d4a4557 Merge pull request #2020 from dolanmiu/dependabot/npm_and_yarn/prettier-2.8.6
build(deps-dev): bump prettier from 2.8.4 to 2.8.6
2023-03-23 23:16:58 +00:00
07c58ee43c Merge pull request #2022 from dolanmiu/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-5.56.0
build(deps-dev): bump @typescript-eslint/eslint-plugin from 5.55.0 to 5.56.0
2023-03-23 23:16:46 +00:00
1037e8f1b9 Merge pull request #2025 from dolanmiu/dependabot/npm_and_yarn/eslint-plugin-functional-5.0.7
build(deps-dev): bump eslint-plugin-functional from 5.0.6 to 5.0.7
2023-03-23 23:16:39 +00:00
f0ae8396f7 Merge pull request #2031 from dolanmiu/dependabot/npm_and_yarn/glob-9.3.2
build(deps-dev): bump glob from 9.3.0 to 9.3.2
2023-03-23 23:16:31 +00:00
1ae5995f9c Merge pull request #2033 from dolanmiu/feat/remove-redundant-keys
Remove unused type keys
2023-03-23 23:14:59 +00:00
751ad9d304 Remove unused type keys 2023-03-23 22:59:34 +00:00
0bd1514826 Merge pull request #2032 from dolanmiu/feat/fix-patcher-issue
#2028 Fix patcher offset indexes
2023-03-23 22:52:34 +00:00
16bfc78d8d #2028 Fix patcher offset indexes 2023-03-23 21:01:24 +00:00
528008406a Merge pull request #2016 from ewoutkleinsmann/master
Images in templates
2023-03-23 19:08:54 +00:00
9e3010ac6a Reduce coverage temporarily 2023-03-23 19:02:22 +00:00
7c1fa6f4bf build(deps-dev): bump glob from 9.3.0 to 9.3.2
Bumps [glob](https://github.com/isaacs/node-glob) from 9.3.0 to 9.3.2.
- [Release notes](https://github.com/isaacs/node-glob/releases)
- [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v9.3.0...v9.3.2)

---
updated-dependencies:
- dependency-name: glob
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-23 11:57:04 +00:00
f58d31cc3d build(deps-dev): bump rimraf from 4.4.0 to 4.4.1
Bumps [rimraf](https://github.com/isaacs/rimraf) from 4.4.0 to 4.4.1.
- [Release notes](https://github.com/isaacs/rimraf/releases)
- [Changelog](https://github.com/isaacs/rimraf/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/rimraf/compare/v4.4.0...v4.4.1)

---
updated-dependencies:
- dependency-name: rimraf
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-23 11:56:45 +00:00
286c742ece build(deps-dev): bump eslint-plugin-functional from 5.0.6 to 5.0.7
Bumps [eslint-plugin-functional](https://github.com/eslint-functional/eslint-plugin-functional) from 5.0.6 to 5.0.7.
- [Release notes](https://github.com/eslint-functional/eslint-plugin-functional/releases)
- [Changelog](https://github.com/eslint-functional/eslint-plugin-functional/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint-functional/eslint-plugin-functional/compare/v5.0.6...v5.0.7)

---
updated-dependencies:
- dependency-name: eslint-plugin-functional
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-21 11:58:57 +00:00
3edc51d5a0 build(deps-dev): bump @typescript-eslint/parser from 5.55.0 to 5.56.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.55.0 to 5.56.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.56.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-21 11:58:10 +00:00
05d4c9688e build(deps-dev): bump @typescript-eslint/eslint-plugin
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.55.0 to 5.56.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.56.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-21 11:57:39 +00:00
d4401d1597 build(deps): bump @types/node from 18.15.3 to 18.15.5
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 18.15.3 to 18.15.5.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-21 11:57:03 +00:00
90358e73f6 build(deps-dev): bump prettier from 2.8.4 to 2.8.6
Bumps [prettier](https://github.com/prettier/prettier) from 2.8.4 to 2.8.6.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/2.8.4...2.8.6)

---
updated-dependencies:
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-21 11:56:43 +00:00
a77ca02ea9 Set homepage to docx.js.org 2023-03-21 04:31:21 +00:00
7785f0df02 Add some tests to boost coverage 2023-03-21 04:30:20 +00:00
0e6ed6e5ea build(deps-dev): bump cspell from 6.30.0 to 6.30.2
Bumps [cspell](https://github.com/streetsidesoftware/cspell) from 6.30.0 to 6.30.2.
- [Release notes](https://github.com/streetsidesoftware/cspell/releases)
- [Changelog](https://github.com/streetsidesoftware/cspell/blob/main/CHANGELOG.md)
- [Commits](https://github.com/streetsidesoftware/cspell/compare/v6.30.0...v6.30.2)

---
updated-dependencies:
- dependency-name: cspell
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 11:57:45 +00:00
70e84c8d38 build(deps-dev): bump typedoc from 0.23.27 to 0.23.28
Bumps [typedoc](https://github.com/TypeStrong/TypeDoc) from 0.23.27 to 0.23.28.
- [Release notes](https://github.com/TypeStrong/TypeDoc/releases)
- [Changelog](https://github.com/TypeStrong/typedoc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/TypeStrong/TypeDoc/compare/v0.23.27...v0.23.28)

---
updated-dependencies:
- dependency-name: typedoc
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-20 11:56:49 +00:00
11c3886659 Merge branch 'dolanmiu:master' into master 2023-03-20 12:08:28 +01:00
6104e5bc35 Update shelljs definitions 2023-03-19 19:46:06 +00:00
c748b9a7fc Remove src and template from files 2023-03-19 19:42:40 +00:00
714dbc0179 Add horizontal rule to border example 2023-03-19 15:47:45 +00:00
7f16cfc359 Remove unessesary glob types and fix typedocs 2023-03-19 04:22:52 +00:00
71953cf45a Fixes patchDocument for files with binary content 2023-03-17 16:30:35 +01:00
14 changed files with 614 additions and 384 deletions

2
.nycrc
View File

@ -1,7 +1,7 @@
{
"check-coverage": true,
"statements": 99.87,
"branches": 98.29,
"branches": 98.21,
"functions": 100,
"lines": 99.86,
"include": [

View File

@ -25,6 +25,17 @@ const doc = new Document({
},
},
}),
new Paragraph({
text: "",
border: {
top: {
color: "auto",
space: 1,
style: BorderStyle.SINGLE,
size: 6,
},
},
}),
new Paragraph({
children: [
new TextRun({

View File

@ -0,0 +1,15 @@
// Patch a document with patches
// Import from 'docx' rather than '../build' if you install from npm
import * as fs from "fs";
import { patchDocument, PatchType, TextRun } from "../build";
patchDocument(fs.readFileSync("demo/assets/simple-template-2.docx"), {
patches: {
name: {
type: PatchType.PARAGRAPH,
children: [new TextRun("Max")],
},
},
}).then((doc) => {
fs.writeFileSync("My Document.docx", doc);
});

Binary file not shown.

722
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "docx",
"version": "8.0.0",
"version": "8.0.1",
"description": "Easily generate .docx files with JS/TS with a nice declarative API. Works for Node and on the Browser.",
"main": "build/index.js",
"scripts": {
@ -28,9 +28,7 @@
"lint"
],
"files": [
"src",
"build",
"template"
"build"
],
"repository": {
"type": "git",
@ -61,15 +59,14 @@
"bugs": {
"url": "https://github.com/dolanmiu/docx/issues"
},
"homepage": "https://github.com/dolanmiu/docx#readme",
"homepage": "https://docx.js.org",
"devDependencies": {
"@types/chai": "^4.2.15",
"@types/chai-as-promised": "^7.1.5",
"@types/glob": "^8.0.0",
"@types/mocha": "^10.0.0",
"@types/prompt": "^1.1.1",
"@types/request-promise": "^4.1.42",
"@types/shelljs": "^0.8.9",
"@types/shelljs": "^0.8.11",
"@types/sinon": "^10.0.0",
"@types/unzipper": "^0.10.4",
"@types/webpack": "^5.0.0",

View File

@ -8,7 +8,6 @@ export interface IBaseCharacterStyleOptions extends IStyleOptions {
export interface ICharacterStyleOptions extends IBaseCharacterStyleOptions {
readonly id: string;
readonly name?: string;
}
export class StyleForCharacter extends Style {

View File

@ -9,7 +9,6 @@ export interface IBaseParagraphStyleOptions extends IStyleOptions {
export interface IParagraphStyleOptions extends IBaseParagraphStyleOptions {
readonly id: string;
readonly name?: string;
}
export class StyleForParagraph extends Style {

View File

@ -206,8 +206,7 @@ const MOCK_XML = `
describe("from-docx", () => {
describe("patchDocument", () => {
describe("document.xml and [Content_Types].xml", () => {
before(() => {
sinon.createStubInstance(JSZip, {});
beforeEach(() => {
sinon.stub(JSZip, "loadAsync").callsFake(
() =>
new Promise<JSZip>((resolve) => {
@ -220,7 +219,7 @@ describe("from-docx", () => {
);
});
after(() => {
afterEach(() => {
(JSZip.loadAsync as unknown as sinon.SinonStub).restore();
});
@ -292,8 +291,7 @@ describe("from-docx", () => {
});
describe("document.xml and [Content_Types].xml with relationships", () => {
before(() => {
sinon.createStubInstance(JSZip, {});
beforeEach(() => {
sinon.stub(JSZip, "loadAsync").callsFake(
() =>
new Promise<JSZip>((resolve) => {
@ -307,7 +305,7 @@ describe("from-docx", () => {
);
});
after(() => {
afterEach(() => {
(JSZip.loadAsync as unknown as sinon.SinonStub).restore();
});
@ -322,6 +320,14 @@ describe("from-docx", () => {
data: Buffer.from(""),
transformation: { width: 100, height: 100 },
}),
new ExternalHyperlink({
children: [
new TextRun({
text: "Google Link",
}),
],
link: "https://www.google.co.uk",
}),
],
},
},
@ -331,8 +337,7 @@ describe("from-docx", () => {
});
describe("document.xml", () => {
before(() => {
sinon.createStubInstance(JSZip, {});
beforeEach(() => {
sinon.stub(JSZip, "loadAsync").callsFake(
() =>
new Promise<JSZip>((resolve) => {
@ -344,7 +349,45 @@ describe("from-docx", () => {
);
});
after(() => {
afterEach(() => {
(JSZip.loadAsync as unknown as sinon.SinonStub).restore();
});
it("should throw an error if the content types is not found", () =>
expect(
patchDocument(Buffer.from(""), {
patches: {
// eslint-disable-next-line @typescript-eslint/naming-convention
image_test: {
type: PatchType.PARAGRAPH,
children: [
new ImageRun({
data: Buffer.from(""),
transformation: { width: 100, height: 100 },
}),
],
},
},
}),
).to.eventually.be.rejected);
});
describe("Images", () => {
beforeEach(() => {
sinon.stub(JSZip, "loadAsync").callsFake(
() =>
new Promise<JSZip>((resolve) => {
const zip = new JSZip();
zip.file("word/document.xml", MOCK_XML);
zip.file("word/document.bmp", "");
resolve(zip);
}),
);
});
afterEach(() => {
(JSZip.loadAsync as unknown as sinon.SinonStub).restore();
});

View File

@ -68,7 +68,14 @@ export const patchDocument = async (data: InputDataType, options: PatchDocumentO
const hyperlinkRelationshipAdditions: IHyperlinkRelationshipAddition[] = [];
let hasMedia = false;
const binaryContentMap = new Map<string, Buffer>();
for (const [key, value] of Object.entries(zipContent.files)) {
if (!key.endsWith(".xml") && !key.endsWith(".rels")) {
binaryContentMap.set(key, await value.async("nodebuffer"));
continue;
}
const json = toJson(await value.async("text"));
if (key.startsWith("word/") && !key.endsWith(".xml.rels")) {
const context: IContext = {
@ -196,6 +203,10 @@ export const patchDocument = async (data: InputDataType, options: PatchDocumentO
zip.file(key, output);
}
for (const [key, value] of binaryContentMap) {
zip.file(key, value);
}
for (const { stream, fileName } of file.Media.Array) {
zip.file(`word/media/${fileName}`, stream);
}

View File

@ -71,6 +71,156 @@ describe("paragraph-token-replacer", () => {
});
});
it("should handle case where it cannot find any text to replace", () => {
const output = replaceTokenInParagraphElement({
paragraphElement: {
name: "w:p",
attributes: {
"w14:paraId": "2499FE9F",
"w14:textId": "27B4FBC2",
"w:rsidR": "00B51233",
"w:rsidRDefault": "007B52ED",
"w:rsidP": "007B52ED",
},
elements: [
{
type: "element",
name: "w:pPr",
elements: [{ type: "element", name: "w:pStyle", attributes: { "w:val": "Title" } }],
},
{
type: "element",
name: "w:r",
elements: [
{
type: "element",
name: "w:t",
attributes: { "xml:space": "preserve" },
elements: [{ type: "text", text: "Hello " }],
},
],
},
{
type: "element",
name: "w:r",
attributes: { "w:rsidR": "007F116B" },
elements: [
{
type: "element",
name: "w:t",
attributes: { "xml:space": "preserve" },
elements: [{ type: "text", text: "{{name}} " }],
},
],
},
{
type: "element",
name: "w:r",
elements: [{ type: "element", name: "w:t", elements: [{ type: "text", text: "World" }] }],
},
],
},
renderedParagraph: {
text: "Hello {{name}} World",
runs: [
{ text: "Hello ", parts: [{ text: "Hello ", index: 0, start: 0, end: 5 }], index: 1, start: 0, end: 5 },
{ text: "{{name}} ", parts: [{ text: "{{name}} ", index: 0, start: 6, end: 14 }], index: 2, start: 6, end: 14 },
{ text: "World", parts: [{ text: "World", index: 0, start: 15, end: 19 }], index: 3, start: 15, end: 19 },
],
index: 0,
path: [0, 1, 0, 0],
},
originalText: "{{name}}",
replacementText: "John",
});
expect(output).to.deep.equal({
attributes: {
"w14:paraId": "2499FE9F",
"w14:textId": "27B4FBC2",
"w:rsidP": "007B52ED",
"w:rsidR": "00B51233",
"w:rsidRDefault": "007B52ED",
},
elements: [
{
elements: [
{
attributes: {
"w:val": "Title",
},
name: "w:pStyle",
type: "element",
},
],
name: "w:pPr",
type: "element",
},
{
elements: [
{
attributes: {
"xml:space": "preserve",
},
elements: [
{
text: "Hello ",
type: "text",
},
],
name: "w:t",
type: "element",
},
],
name: "w:r",
type: "element",
},
{
attributes: {
"w:rsidR": "007F116B",
},
elements: [
{
attributes: {
"xml:space": "preserve",
},
elements: [
{
text: "John ",
type: "text",
},
],
name: "w:t",
type: "element",
},
],
name: "w:r",
type: "element",
},
{
elements: [
{
attributes: {
"xml:space": "preserve",
},
elements: [
{
text: "World",
type: "text",
},
],
name: "w:t",
type: "element",
},
],
name: "w:r",
type: "element",
},
],
name: "w:p",
});
});
// Try to fill rest of test coverage
// it("should replace token in paragraph", () => {
// const output = replaceTokenInParagraphElement({

View File

@ -30,9 +30,15 @@ export const replaceTokenInParagraphElement = ({
switch (replaceMode) {
case ReplaceMode.START:
if (startIndex >= start) {
const partToReplace = run.text.substring(Math.max(startIndex, start), Math.min(endIndex, end) + 1);
const offsetStartIndex = startIndex - start;
const offsetEndIndex = Math.min(endIndex, end) - start;
const partToReplace = run.text.substring(offsetStartIndex, offsetEndIndex + 1);
// We use a token to split the text if the replacement is within the same run
// If not, we just add text to the middle of the run later
if (partToReplace === "") {
continue;
}
const firstPart = text.replace(partToReplace, replacementText);
patchTextElement(paragraphElement.elements![run.index].elements![index], firstPart);
replaceMode = ReplaceMode.MIDDLE;

View File

@ -7,7 +7,7 @@ import { Text } from "@file/paragraph/run/run-components/text";
const formatter = new Formatter();
export const toJson = (xmlData: string): Element => {
const xmlObj = xml2js(xmlData, { compact: false }) as Element;
const xmlObj = xml2js(xmlData, { compact: false, captureSpacesBetweenElements: true }) as Element;
return xmlObj;
};

View File

@ -1,5 +1,8 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"allowSyntheticDefaultImports": true
},
"typedocOptions": {
"out": "docs/api",
"exclude": "test",