diff --git a/.npmignore b/.npmignore index 5e2cb9d175..fe3322c8fd 100644 --- a/.npmignore +++ b/.npmignore @@ -40,4 +40,7 @@ build-tests .vscode # docs -docs \ No newline at end of file +docs + +# src +src diff --git a/.nycrc b/.nycrc index 19699770ea..64dc581dc7 100644 --- a/.nycrc +++ b/.nycrc @@ -1,7 +1,7 @@ { "check-coverage": true, "statements": 99.87, - "branches": 98.2, + "branches": 98.29, "functions": 100, "lines": 99.86, "include": [ diff --git a/README.md b/README.md index c5ce2ad461..4dcc91b325 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@

- Easily generate .docx files with JS/TS. Works for Node and on the Browser. + Easily generate and modify .docx files with JS/TS. Works for Node and on the Browser.

--- diff --git a/demo/26-paragraph-borders.ts b/demo/26-paragraph-borders.ts index 6b81954456..ec32943e4c 100644 --- a/demo/26-paragraph-borders.ts +++ b/demo/26-paragraph-borders.ts @@ -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({ diff --git a/demo/73-comments.ts b/demo/73-comments.ts index fffe22df93..3c1da71454 100644 --- a/demo/73-comments.ts +++ b/demo/73-comments.ts @@ -5,7 +5,34 @@ import { Document, Packer, Paragraph, TextRun, CommentRangeStart, CommentRangeEn const doc = new Document({ comments: { - children: [{ id: 0, author: "Ray Chen", date: new Date(), text: "comment text content" }], + children: [ + { + id: 0, + author: "Ray Chen", + date: new Date(), + children: [ + new Paragraph({ + children: [ + new TextRun({ + text: "some initial text content", + }), + ], + }), + new Paragraph({ + children: [ + new TextRun({ + text: "comment text content", + }), + new TextRun({ text: "", break: 1 }), + new TextRun({ + text: "More text here", + bold: true, + }), + ], + }), + ], + }, + ], }, sections: [ { diff --git a/docs/_coverpage.md b/docs/_coverpage.md index ae27b1a3fb..b8a546f3a4 100644 --- a/docs/_coverpage.md +++ b/docs/_coverpage.md @@ -1,10 +1,10 @@ drawing -> Easily generate .docx files with JS/TS. Works for Node and on the Browser. :100: +> Easily generate and modify .docx files with JS/TS. Works for Node and on the Browser. :100: - Simple, declarative API -- 60+ usage examples -- Battle tested, mature, 99%+ coverage +- 80+ usage examples +- Battle tested, mature, 99.9%+ coverage [GitHub](https://github.com/dolanmiu/docx) [Get Started](#Welcome) diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 8805f6a417..048b62397c 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -1,6 +1,8 @@ - [Getting Started](/) -- [Examples](https://github.com/dolanmiu/docx/tree/master/demo) +- Examples + + - [Demos](https://github.com/dolanmiu/docx/tree/master/demo) - API @@ -36,6 +38,10 @@ - [Packers](usage/packers.md) +- Modifying Existing Documents + + - [Patcher](usage/patcher.md) + - Utility - [Convenience functions](usage/convenience-functions.md) diff --git a/docs/usage/patcher.md b/docs/usage/patcher.md new file mode 100644 index 0000000000..6f76b1d180 --- /dev/null +++ b/docs/usage/patcher.md @@ -0,0 +1,94 @@ +# Patcher + +The patcher allows you to modify existing documents, and add new content to them. + +!> The Patcher requires an understanding of [Paragraphs](usage/paragraph.md). + +--- + +## Usage + +```ts +import * as fs from "fs"; +import { patchDocument } from "docx"; + +patchDocument(fs.readFileSync("My Document.docx"), { + patches: { + // Patches here + }, +}); +``` + +## Patches + +The patcher takes in a `patches` object, which is a map of `string` to `Patch`: + +```ts +interface Patch { + type: PatchType; + children: FileChild[] | ParagraphChild[]; +} +``` + +| Property | Type | Notes | Possible Values | +| -------- | --------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| type | `PatchType` | Required | `DOCUMENT`, `PARAGRAPH` | +| children | `FileChild[] or ParagraphChild[]` | Required | The contents to replace with. A `FileChild` is a `Paragraph` or `Table`, whereas a `ParagraphChild` is typical `Paragraph` children. | + +### How to patch existing document + +1. Open your existing word document in your favorite Word Processor +2. Write tags in the document where you want to patch in a mustache style notation. For example, `{{my_patch}}` and `{{my_second_patch}}`. +3. Run the patcher with the patches as a key value pair. + +## Example + +### Word Document + +![Word Document screenshot](https://i.imgur.com/ybkvw6Z.png) + +### Patcher + +?> Notice how there is no handlebar notation in the key. + +The patch can be as simple as a string, or as complex as a table. Images, hyperlinks, and other complex elements within the `docx` library are also supported. + +```ts +patchDocument(fs.readFileSync("My Document.docx"), { + patches: { + my_patch: { + type: PatchType.PARAGRAPH, + children: [new TextRun("Sir. "), new TextRun("John Doe"), new TextRun("(The Conqueror)")], + }, + my_second_patch: { + type: PatchType.DOCUMENT, + children: [ + new Paragraph("Lorem ipsum paragraph"), + new Paragraph("Another paragraph"), + new Paragraph({ + children: [ + new TextRun("This is a "), + new ExternalHyperlink({ + children: [ + new TextRun({ + text: "Google Link", + }), + ], + link: "https://www.google.co.uk", + }), + new ImageRun({ data: fs.readFileSync("./demo/images/dog.png"), transformation: { width: 100, height: 100 } }), + ], + }), + ], + }, + }, +}); +``` + +--- + +## Demo + +_Source: https://github.com/dolanmiu/docx/blob/master/demo/85-template-document.ts_ + +[Example](https://raw.githubusercontent.com/dolanmiu/docx/master/demo/85-template-document.ts ":include :type=code typescript") diff --git a/package-lock.json b/package-lock.json index a99ccc78b6..bfc755c49f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "docx", - "version": "7.8.2", + "version": "8.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "docx", - "version": "7.8.2", + "version": "8.0.0", "license": "MIT", "dependencies": { "@types/node": "^18.0.0", @@ -18,11 +18,10 @@ "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", @@ -40,7 +39,7 @@ "eslint-plugin-no-null": "^1.0.2", "eslint-plugin-prefer-arrow": "^1.2.3", "eslint-plugin-unicorn": "^46.0.0", - "glob": "^8.0.1", + "glob": "^9.3.0", "jszip": "^3.1.5", "mocha": "^10.0.0", "nyc": "^15.1.0", @@ -60,7 +59,7 @@ "tsconfig-paths": "^4.0.0", "tsconfig-paths-webpack-plugin": "^4.0.0", "typedoc": "^0.23.2", - "typescript": "4.9.5", + "typescript": "5.0.2", "unzipper": "^0.10.11", "webpack": "^5.28.0", "webpack-cli": "^5.0.0" @@ -802,14 +801,14 @@ } }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.36.1", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.36.1.tgz", - "integrity": "sha512-922xqFsTpHs6D0BUiG4toiyPOMc8/jafnWKxz1KWgS4XzKPy2qXf1Pe6UFuNSCQqt6tOuhAWXBNuuyUhJmw9Vg==", + "version": "0.37.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.37.0.tgz", + "integrity": "sha512-hjK0wnsPCYLlF+HHB4R/RbUjOWeLW2SlarB67+Do5WsKILOkmIZvvPJFbtWSmbypxcjpoECLAMzoao0D4Bg5ZQ==", "dev": true, "dependencies": { "comment-parser": "1.3.1", "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "~3.1.0" + "jsdoc-type-pratt-parser": "~4.0.0" }, "engines": { "node": "^14 || ^16 || ^17 || ^18 || ^19" @@ -4584,16 +4583,16 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "40.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-40.0.1.tgz", - "integrity": "sha512-KkiRInury7YrjjV5aCHDxwsPy6XFt5p2b2CnpDMITnWs8patNPf5kj24+VXIWw45kP6z/B0GOKfrYczB56OjQQ==", + "version": "40.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-40.1.0.tgz", + "integrity": "sha512-ANvrhiu62VlSorARM0hup60VQsS3hNyp0Ca7cnJDj8tpJzM7tNhBVqMVYXSuLzEmqrpwx6aAh+NAN2DdAGG5fQ==", "dev": true, "dependencies": { - "@es-joy/jsdoccomment": "~0.36.1", + "@es-joy/jsdoccomment": "~0.37.0", "comment-parser": "1.3.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", - "esquery": "^1.4.0", + "esquery": "^1.5.0", "semver": "^7.3.8", "spdx-expression-parse": "^3.0.1" }, @@ -5061,9 +5060,9 @@ } }, "node_modules/esquery": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz", - "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -5768,19 +5767,18 @@ } }, "node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.0.tgz", + "integrity": "sha512-EAZejC7JvnQINayvB/7BJbpZpNOJ8Lrw2OZNEvQxe0vaLn1SuwMcfV7/MNaX8L/T0wmptBFI4YMtDvSBxYDc7w==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" + "minimatch": "^7.4.1", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" }, "engines": { - "node": ">=12" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -5814,15 +5812,18 @@ } }, "node_modules/glob/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.2.tgz", + "integrity": "sha512-xy4q7wou3vUoC9k1xGTXc+awNdGaGVHtFUaey8tiX4H1QRc04DZ/rmDFwNm2EBsuYEhAZ6SgMmYf3InGY6OauA==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/global-dirs": { @@ -7058,9 +7059,9 @@ "dev": true }, "node_modules/jsdoc-type-pratt-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz", - "integrity": "sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", "dev": true, "engines": { "node": ">=12.0.0" @@ -7862,36 +7863,18 @@ "dev": true }, "node_modules/nise": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.2.tgz", - "integrity": "sha512-+gQjFi8v+tkfCuSCxfURHLhRhniE/+IaYbIphxAN2JRR9SHKhY8hgXpaXiYfHdw+gcGe4buxgbprBQFab9FkhA==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", + "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", "dev": true, "dependencies": { "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "^7.0.4", + "@sinonjs/fake-timers": "^10.0.2", "@sinonjs/text-encoding": "^0.7.1", "just-extend": "^4.0.2", "path-to-regexp": "^1.7.0" } }, - "node_modules/nise/node_modules/@sinonjs/fake-timers": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", - "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/nise/node_modules/@sinonjs/fake-timers/node_modules/@sinonjs/commons": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.5.tgz", - "integrity": "sha512-rTpCA0wG1wUxglBSFdMMY0oTrKYvgf4fNgv/sXbfCVAdf+FnPBdKJR/7XbpTCwbCrvCbdPYnlWaUUYz4V2fPDA==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, "node_modules/node-fetch": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", @@ -9411,48 +9394,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.2.1.tgz", - "integrity": "sha512-Pxxgq3W0HyA3XUvSXcFhRSs+43Jsx0ddxcFrbjxNGkL2Ak5BAUBxLqI5G6ADDeCHLfzzXFhe0b1yYcctGmytMA==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^7.4.1", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.2.tgz", - "integrity": "sha512-xy4q7wou3vUoC9k1xGTXc+awNdGaGVHtFUaey8tiX4H1QRc04DZ/rmDFwNm2EBsuYEhAZ6SgMmYf3InGY6OauA==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -9739,16 +9680,16 @@ "dev": true }, "node_modules/sinon": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.1.tgz", - "integrity": "sha512-PZXKc08f/wcA/BMRGBze2Wmw50CWPiAH3E21EOi4B49vJ616vW4DQh4fQrqsYox2aNR/N3kCqLuB0PwwOucQrg==", + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.2.tgz", + "integrity": "sha512-PCVP63XZkg0/LOqQH5rEU4LILuvTFMb5tNxTHfs6VUMNnZz2XrnGSTZbAGITjzwQWbl/Bl/8hi4G3zZWjyBwHg==", "dev": true, "dependencies": { - "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "10.0.2", + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^10.0.2", "@sinonjs/samsam": "^7.0.1", - "diff": "^5.0.0", - "nise": "^5.1.2", + "diff": "^5.1.0", + "nise": "^5.1.4", "supports-color": "^7.2.0" }, "funding": { @@ -9756,6 +9697,24 @@ "url": "https://opencollective.com/sinon" } }, + "node_modules/sinon/node_modules/@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/sinon/node_modules/diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/sinon/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -10719,9 +10678,9 @@ } }, "node_modules/typedoc": { - "version": "0.23.26", - "resolved": "http://registry.npmjs.org/typedoc/-/typedoc-0.23.26.tgz", - "integrity": "sha512-5m4KwR5tOLnk0OtMaRn9IdbeRM32uPemN9kur7YK9wFqx8U0CYrvO9aVq6ysdZSV1c824BTm+BuQl2Ze/k1HtA==", + "version": "0.23.27", + "resolved": "http://registry.npmjs.org/typedoc/-/typedoc-0.23.27.tgz", + "integrity": "sha512-YKjlxX3LEhYbMCkemjlpNh1OKDiFa+ynqP0VRPsH28bEugrMTGI6l8DC6oX5kzFcUKKlYWKpZDSGWszuO/FR3g==", "dev": true, "dependencies": { "lunr": "^2.3.9", @@ -10764,16 +10723,16 @@ } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=12.20" } }, "node_modules/unbox-primitive": { @@ -12346,14 +12305,14 @@ "dev": true }, "@es-joy/jsdoccomment": { - "version": "0.36.1", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.36.1.tgz", - "integrity": "sha512-922xqFsTpHs6D0BUiG4toiyPOMc8/jafnWKxz1KWgS4XzKPy2qXf1Pe6UFuNSCQqt6tOuhAWXBNuuyUhJmw9Vg==", + "version": "0.37.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.37.0.tgz", + "integrity": "sha512-hjK0wnsPCYLlF+HHB4R/RbUjOWeLW2SlarB67+Do5WsKILOkmIZvvPJFbtWSmbypxcjpoECLAMzoao0D4Bg5ZQ==", "dev": true, "requires": { "comment-parser": "1.3.1", "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "~3.1.0" + "jsdoc-type-pratt-parser": "~4.0.0" } }, "@eslint-community/eslint-utils": { @@ -15411,16 +15370,16 @@ } }, "eslint-plugin-jsdoc": { - "version": "40.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-40.0.1.tgz", - "integrity": "sha512-KkiRInury7YrjjV5aCHDxwsPy6XFt5p2b2CnpDMITnWs8patNPf5kj24+VXIWw45kP6z/B0GOKfrYczB56OjQQ==", + "version": "40.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-40.1.0.tgz", + "integrity": "sha512-ANvrhiu62VlSorARM0hup60VQsS3hNyp0Ca7cnJDj8tpJzM7tNhBVqMVYXSuLzEmqrpwx6aAh+NAN2DdAGG5fQ==", "dev": true, "requires": { - "@es-joy/jsdoccomment": "~0.36.1", + "@es-joy/jsdoccomment": "~0.37.0", "comment-parser": "1.3.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", - "esquery": "^1.4.0", + "esquery": "^1.5.0", "semver": "^7.3.8", "spdx-expression-parse": "^3.0.1" }, @@ -15576,9 +15535,9 @@ "dev": true }, "esquery": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.2.tgz", - "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -16093,16 +16052,15 @@ } }, "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.0.tgz", + "integrity": "sha512-EAZejC7JvnQINayvB/7BJbpZpNOJ8Lrw2OZNEvQxe0vaLn1SuwMcfV7/MNaX8L/T0wmptBFI4YMtDvSBxYDc7w==", "dev": true, "requires": { "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" + "minimatch": "^7.4.1", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" }, "dependencies": { "brace-expansion": { @@ -16115,9 +16073,9 @@ } }, "minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.2.tgz", + "integrity": "sha512-xy4q7wou3vUoC9k1xGTXc+awNdGaGVHtFUaey8tiX4H1QRc04DZ/rmDFwNm2EBsuYEhAZ6SgMmYf3InGY6OauA==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -17024,9 +16982,9 @@ "dev": true }, "jsdoc-type-pratt-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz", - "integrity": "sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", "dev": true }, "jsesc": { @@ -17649,38 +17607,16 @@ "dev": true }, "nise": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.2.tgz", - "integrity": "sha512-+gQjFi8v+tkfCuSCxfURHLhRhniE/+IaYbIphxAN2JRR9SHKhY8hgXpaXiYfHdw+gcGe4buxgbprBQFab9FkhA==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", + "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", "dev": true, "requires": { "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "^7.0.4", + "@sinonjs/fake-timers": "^10.0.2", "@sinonjs/text-encoding": "^0.7.1", "just-extend": "^4.0.2", "path-to-regexp": "^1.7.0" - }, - "dependencies": { - "@sinonjs/fake-timers": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", - "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - }, - "dependencies": { - "@sinonjs/commons": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.5.tgz", - "integrity": "sha512-rTpCA0wG1wUxglBSFdMMY0oTrKYvgf4fNgv/sXbfCVAdf+FnPBdKJR/7XbpTCwbCrvCbdPYnlWaUUYz4V2fPDA==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - } - } - } } }, "node-fetch": { @@ -18818,38 +18754,6 @@ "dev": true, "requires": { "glob": "^9.2.0" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "glob": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.2.1.tgz", - "integrity": "sha512-Pxxgq3W0HyA3XUvSXcFhRSs+43Jsx0ddxcFrbjxNGkL2Ak5BAUBxLqI5G6ADDeCHLfzzXFhe0b1yYcctGmytMA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "minimatch": "^7.4.1", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" - } - }, - "minimatch": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.2.tgz", - "integrity": "sha512-xy4q7wou3vUoC9k1xGTXc+awNdGaGVHtFUaey8tiX4H1QRc04DZ/rmDFwNm2EBsuYEhAZ6SgMmYf3InGY6OauA==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } } }, "run-parallel": { @@ -19081,19 +18985,34 @@ "dev": true }, "sinon": { - "version": "15.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.1.tgz", - "integrity": "sha512-PZXKc08f/wcA/BMRGBze2Wmw50CWPiAH3E21EOi4B49vJ616vW4DQh4fQrqsYox2aNR/N3kCqLuB0PwwOucQrg==", + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.2.tgz", + "integrity": "sha512-PCVP63XZkg0/LOqQH5rEU4LILuvTFMb5tNxTHfs6VUMNnZz2XrnGSTZbAGITjzwQWbl/Bl/8hi4G3zZWjyBwHg==", "dev": true, "requires": { - "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "10.0.2", + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^10.0.2", "@sinonjs/samsam": "^7.0.1", - "diff": "^5.0.0", - "nise": "^5.1.2", + "diff": "^5.1.0", + "nise": "^5.1.4", "supports-color": "^7.2.0" }, "dependencies": { + "@sinonjs/commons": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", + "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -19811,9 +19730,9 @@ } }, "typedoc": { - "version": "0.23.26", - "resolved": "http://registry.npmjs.org/typedoc/-/typedoc-0.23.26.tgz", - "integrity": "sha512-5m4KwR5tOLnk0OtMaRn9IdbeRM32uPemN9kur7YK9wFqx8U0CYrvO9aVq6ysdZSV1c824BTm+BuQl2Ze/k1HtA==", + "version": "0.23.27", + "resolved": "http://registry.npmjs.org/typedoc/-/typedoc-0.23.27.tgz", + "integrity": "sha512-YKjlxX3LEhYbMCkemjlpNh1OKDiFa+ynqP0VRPsH28bEugrMTGI6l8DC6oX5kzFcUKKlYWKpZDSGWszuO/FR3g==", "dev": true, "requires": { "lunr": "^2.3.9", @@ -19843,9 +19762,9 @@ } }, "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", "dev": true }, "unbox-primitive": { diff --git a/package.json b/package.json index bdaab9abd7..f00d964476 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "docx", - "version": "7.8.2", + "version": "8.0.0", "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", @@ -65,11 +63,10 @@ "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", @@ -87,7 +84,7 @@ "eslint-plugin-no-null": "^1.0.2", "eslint-plugin-prefer-arrow": "^1.2.3", "eslint-plugin-unicorn": "^46.0.0", - "glob": "^8.0.1", + "glob": "^9.3.0", "jszip": "^3.1.5", "mocha": "^10.0.0", "nyc": "^15.1.0", @@ -107,7 +104,7 @@ "tsconfig-paths": "^4.0.0", "tsconfig-paths-webpack-plugin": "^4.0.0", "typedoc": "^0.23.2", - "typescript": "4.9.5", + "typescript": "5.0.2", "unzipper": "^0.10.11", "webpack": "^5.28.0", "webpack-cli": "^5.0.0" diff --git a/scripts/types-absolute-fixer.ts b/scripts/types-absolute-fixer.ts index 43a338f20d..f2474ab893 100644 --- a/scripts/types-absolute-fixer.ts +++ b/scripts/types-absolute-fixer.ts @@ -9,7 +9,7 @@ for (const file of files) { from: /"@[a-z/-]*"/gi, to: (match) => { const matchSlug = match.replace(/['"]+/g, "").replace(/[@]+/g, "").trim(); - const levelCount = file.split("/").length - 2; + const levelCount = file.split(/[\/\\]/).length - 2; const backLevels = Array(levelCount).fill("../").join(""); return `"${backLevels}${matchSlug}"`; diff --git a/src/file/paragraph/run/comment-run.spec.ts b/src/file/paragraph/run/comment-run.spec.ts index 62d3a624b8..1fa9aab101 100644 --- a/src/file/paragraph/run/comment-run.spec.ts +++ b/src/file/paragraph/run/comment-run.spec.ts @@ -2,6 +2,8 @@ import { expect } from "chai"; import * as sinon from "sinon"; import { Formatter } from "@export/formatter"; + +import { Paragraph } from "../paragraph"; import { Comment, CommentRangeEnd, CommentRangeStart, CommentReference, Comments } from "./comment-run"; describe("CommentRangeStart", () => { @@ -56,7 +58,7 @@ describe("Comment", () => { it("should create", () => { const component = new Comment({ id: 0, - text: "test-comment", + children: [new Paragraph("test-comment")], date: new Date("1999-01-01T00:00:00.000Z"), }); const tree = new Formatter().format(component); @@ -88,7 +90,7 @@ describe("Comment", () => { it("should create by using default date", () => { const component = new Comment({ id: 0, - text: "test-comment", + children: [new Paragraph("test-comment")], }); const tree = new Formatter().format(component); expect(tree).to.deep.equal({ @@ -125,12 +127,12 @@ describe("Comments", () => { children: [ { id: 0, - text: "test-comment", + children: [new Paragraph("test-comment")], date: new Date("1999-01-01T00:00:00.000Z"), }, { id: 1, - text: "test-comment-2", + children: [new Paragraph("test-comment-2")], date: new Date("1999-01-01T00:00:00.000Z"), }, ], diff --git a/src/file/paragraph/run/comment-run.ts b/src/file/paragraph/run/comment-run.ts index 626f4ccba9..f204f7ddcd 100644 --- a/src/file/paragraph/run/comment-run.ts +++ b/src/file/paragraph/run/comment-run.ts @@ -1,11 +1,9 @@ -import { Paragraph } from "@file/paragraph"; +import { FileChild } from "@file/file-child"; import { XmlAttributeComponent, XmlComponent } from "@file/xml-components"; -import { TextRun } from "./text-run"; - export interface ICommentOptions { readonly id: number; - readonly text: string; + readonly children: readonly FileChild[]; readonly initials?: string; readonly author?: string; readonly date?: Date; @@ -120,7 +118,7 @@ export class CommentReference extends XmlComponent { } export class Comment extends XmlComponent { - public constructor({ id, initials, author, date = new Date(), text }: ICommentOptions) { + public constructor({ id, initials, author, date = new Date(), children }: ICommentOptions) { super("w:comment"); this.root.push( @@ -132,7 +130,9 @@ export class Comment extends XmlComponent { }), ); - this.root.push(new Paragraph({ children: [new TextRun(text)] })); + for (const child of children) { + this.root.push(child); + } } } export class Comments extends XmlComponent { diff --git a/tsconfig.typedoc.json b/tsconfig.typedoc.json index 0f192deeb8..93d7300b49 100644 --- a/tsconfig.typedoc.json +++ b/tsconfig.typedoc.json @@ -1,5 +1,8 @@ { "extends": "./tsconfig.json", + "compilerOptions": { + "allowSyntheticDefaultImports": true + }, "typedocOptions": { "out": "docs/api", "exclude": "test",