Convert to vite and clean up build
This commit is contained in:
@ -23,6 +23,7 @@
|
|||||||
"dolan",
|
"dolan",
|
||||||
"execa",
|
"execa",
|
||||||
"falsey",
|
"falsey",
|
||||||
|
"fflate",
|
||||||
"Initializable",
|
"Initializable",
|
||||||
"iroha",
|
"iroha",
|
||||||
"jsonify",
|
"jsonify",
|
||||||
|
@ -5,7 +5,9 @@ env:
|
|||||||
node: true
|
node: true
|
||||||
parser: "@typescript-eslint/parser"
|
parser: "@typescript-eslint/parser"
|
||||||
parserOptions:
|
parserOptions:
|
||||||
project: tsconfig.json
|
project:
|
||||||
|
- tsconfig.json
|
||||||
|
- demo/tsconfig.json
|
||||||
sourceType: module
|
sourceType: module
|
||||||
plugins:
|
plugins:
|
||||||
- eslint-plugin-import
|
- eslint-plugin-import
|
||||||
@ -226,6 +228,8 @@ rules:
|
|||||||
no-unused-vars:
|
no-unused-vars:
|
||||||
- error
|
- error
|
||||||
- argsIgnorePattern: ^[_]+$
|
- argsIgnorePattern: ^[_]+$
|
||||||
|
ignorePatterns:
|
||||||
|
- vite.config.ts
|
||||||
overrides:
|
overrides:
|
||||||
- files:
|
- files:
|
||||||
- "*.spec.ts"
|
- "*.spec.ts"
|
||||||
|
4
.github/dependabot.yml
vendored
4
.github/dependabot.yml
vendored
@ -16,10 +16,6 @@ updates:
|
|||||||
- 14.14.29
|
- 14.14.29
|
||||||
- 14.14.30
|
- 14.14.30
|
||||||
- 15.0.0
|
- 15.0.0
|
||||||
- dependency-name: webpack
|
|
||||||
versions:
|
|
||||||
- 5.31.2
|
|
||||||
- 5.35.0
|
|
||||||
- dependency-name: ts-loader
|
- dependency-name: ts-loader
|
||||||
versions:
|
versions:
|
||||||
- 9.1.0
|
- 9.1.0
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Simple example to add text to a document
|
// Simple example to add text to a document
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Packer, Paragraph, Tab, TextRun } from "../build";
|
import { Document, Packer, Paragraph, Tab, TextRun } from "docx";
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
sections: [
|
sections: [
|
||||||
|
@ -1,17 +1,7 @@
|
|||||||
// Example on how to customize the look at feel using Styles
|
// Example on how to customize the look at feel using Styles
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import {
|
import { AlignmentType, convertInchesToTwip, Document, HeadingLevel, LevelFormat, Packer, Paragraph, TextRun, UnderlineType } from "docx";
|
||||||
AlignmentType,
|
|
||||||
convertInchesToTwip,
|
|
||||||
Document,
|
|
||||||
HeadingLevel,
|
|
||||||
LevelFormat,
|
|
||||||
Packer,
|
|
||||||
Paragraph,
|
|
||||||
TextRun,
|
|
||||||
UnderlineType,
|
|
||||||
} from "../build";
|
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
creator: "Clippy",
|
creator: "Clippy",
|
||||||
|
@ -11,7 +11,7 @@ import {
|
|||||||
Tab,
|
Tab,
|
||||||
TextRun,
|
TextRun,
|
||||||
VerticalPositionAlign,
|
VerticalPositionAlign,
|
||||||
} from "../build";
|
} from "docx";
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
sections: [
|
sections: [
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Exporting the document as a stream
|
// Exporting the document as a stream
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, Packer, Paragraph, Tab, TextRun } from "../build";
|
import { Document, Packer, Paragraph, Tab, TextRun } from "docx";
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
sections: [
|
sections: [
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
// Example of using tab stops
|
// Example of using tab stops
|
||||||
// Import from 'docx' rather than '../build' if you install from npm
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { Document, HeadingLevel, Packer, Paragraph, TabStopPosition, TabStopType, TextRun } from "../build";
|
import { Document, HeadingLevel, Packer, Paragraph, TabStopPosition, TabStopType, TextRun } from "docx";
|
||||||
|
|
||||||
const columnWidth = TabStopPosition.MAX / 4;
|
const columnWidth = TabStopPosition.MAX / 4;
|
||||||
const receiptTabStops = [
|
const receiptTabStops = [
|
||||||
// no need to define first left tab column
|
// no need to define first left tab column
|
||||||
// the right aligned tab column position should point to the end of column
|
// the right aligned tab column position should point to the end of column
|
||||||
// i.e. in this case
|
// i.e. in this case
|
||||||
// (end position of 1st) + (end position of current)
|
// (end position of 1st) + (end position of current)
|
||||||
// columnWidth + columnWidth = columnWidth * 2
|
// columnWidth + columnWidth = columnWidth * 2
|
||||||
|
|
||||||
{ type: TabStopType.RIGHT, position: columnWidth * 2 },
|
{ type: TabStopType.RIGHT, position: columnWidth * 2 },
|
||||||
{ type: TabStopType.RIGHT, position: columnWidth * 3 },
|
{ type: TabStopType.RIGHT, position: columnWidth * 3 },
|
||||||
{ type: TabStopType.RIGHT, position: TabStopPosition.MAX },
|
{ type: TabStopType.RIGHT, position: TabStopPosition.MAX },
|
||||||
],
|
];
|
||||||
twoTabStops = [{ type: TabStopType.RIGHT, position: TabStopPosition.MAX }];
|
const twoTabStops = [{ type: TabStopType.RIGHT, position: TabStopPosition.MAX }];
|
||||||
|
|
||||||
const doc = new Document({
|
const doc = new Document({
|
||||||
sections: [
|
sections: [
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
// tslint:disable:no-console
|
/* eslint-disable no-console */
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import prompt from "prompt";
|
import prompt, { Schema } from "prompt";
|
||||||
// import shelljs from "shelljs";
|
|
||||||
import { $ } from "execa";
|
import { $ } from "execa";
|
||||||
|
|
||||||
console.log("What demo do you wish to run? (Enter a number)");
|
console.log("What demo do you wish to run? (Enter a number)");
|
||||||
|
|
||||||
const schema = {
|
const schema: Schema = {
|
||||||
properties: {
|
properties: {
|
||||||
number: {
|
demoNumber: {
|
||||||
pattern: /^[0-9]+$/,
|
pattern: /^[0-9]+$/,
|
||||||
message: "Please enter a number.",
|
message: "Please enter a number.",
|
||||||
required: true,
|
required: true,
|
||||||
@ -18,8 +17,8 @@ const schema = {
|
|||||||
|
|
||||||
prompt.start();
|
prompt.start();
|
||||||
|
|
||||||
prompt.get(schema as any, async (_, result) => {
|
prompt.get(schema, async (_, result) => {
|
||||||
const demoNumber = result.number as string;
|
const demoNumber = result.demoNumber as string;
|
||||||
const files = fs.readdirSync("./demo").filter((fn) => fn.startsWith(demoNumber));
|
const files = fs.readdirSync("./demo").filter((fn) => fn.startsWith(demoNumber));
|
||||||
|
|
||||||
if (files.length === 0) {
|
if (files.length === 0) {
|
||||||
@ -30,12 +29,6 @@ prompt.get(schema as any, async (_, result) => {
|
|||||||
const filePath = `./demo/${files[0]}`;
|
const filePath = `./demo/${files[0]}`;
|
||||||
|
|
||||||
console.log(`Running demo ${demoNumber}: ${files[0]}`);
|
console.log(`Running demo ${demoNumber}: ${files[0]}`);
|
||||||
const { stdout } = await $`npm run ts-node -- ${filePath}`;
|
await $`ts-node --project demo/tsconfig.json ${filePath}`;
|
||||||
console.log(stdout);
|
console.log("Successfully created document!");
|
||||||
|
|
||||||
// if (shelljs.exec(`npm run ts-node -- ${filePath}`).code === 0) {
|
|
||||||
// console.log("Document created successfully");
|
|
||||||
// } else {
|
|
||||||
// console.error("Something went wrong with the demo");
|
|
||||||
// }
|
|
||||||
});
|
});
|
||||||
|
10
demo/tsconfig.json
Normal file
10
demo/tsconfig.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"extends": "../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "./",
|
||||||
|
"paths": {
|
||||||
|
"docx": ["../build"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["../demo"]
|
||||||
|
}
|
2658
package-lock.json
generated
2658
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
37
package.json
37
package.json
@ -2,20 +2,33 @@
|
|||||||
"name": "docx",
|
"name": "docx",
|
||||||
"version": "8.0.3",
|
"version": "8.0.3",
|
||||||
"description": "Easily generate .docx files with JS/TS with a nice declarative API. Works for Node and on the Browser.",
|
"description": "Easily generate .docx files with JS/TS with a nice declarative API. Works for Node and on the Browser.",
|
||||||
"main": "build/index.js",
|
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
"main": "build/index.umd.cjs",
|
||||||
|
"module": "./build/index.js",
|
||||||
|
"types": "./build/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"browser": {
|
||||||
|
"default": "./build/index.umd.cjs"
|
||||||
|
},
|
||||||
|
"require": "./build/index.cjs",
|
||||||
|
"types": "./build/index.d.ts",
|
||||||
|
"import": "./build/index.js",
|
||||||
|
"default": "./build/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"build"
|
||||||
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
|
||||||
"build": "tsc && vite build",
|
"build": "tsc && vite build",
|
||||||
"preview": "vite preview",
|
|
||||||
"pretest": "rimraf ./build",
|
"pretest": "rimraf ./build",
|
||||||
"test": "mocha --config=.mocharc.json",
|
"test": "mocha --config=.mocharc.json",
|
||||||
"test.coverage": "nyc npm test",
|
"test.coverage": "nyc npm test",
|
||||||
"test.watch": "npm test -- --watch",
|
"test.watch": "npm test -- --watch",
|
||||||
"prepublishOnly": "npm run build --production",
|
"prepublishOnly": "npm run build --omit=dev",
|
||||||
"lint": "eslint --ext .ts src",
|
"lint": "eslint --ext .ts src",
|
||||||
"webpack": "rimraf ./build && webpack --config ./webpack.config.ts",
|
"demo": "ts-node --project demo/tsconfig.json ./demo/index.ts",
|
||||||
"demo": "ts-node --esm ./demo/index.ts",
|
|
||||||
"typedoc": "rimraf ./build && typedoc src/index.ts --tsconfig tsconfig.typedoc.json",
|
"typedoc": "rimraf ./build && typedoc src/index.ts --tsconfig tsconfig.typedoc.json",
|
||||||
"style": "prettier -l \"{src,scripts,demo}/**/*.{ts,html}\"",
|
"style": "prettier -l \"{src,scripts,demo}/**/*.{ts,html}\"",
|
||||||
"style.fix": "npm run style -- --write",
|
"style.fix": "npm run style -- --write",
|
||||||
@ -24,15 +37,12 @@
|
|||||||
"e2e": "ts-node scripts/e2e.ts",
|
"e2e": "ts-node scripts/e2e.ts",
|
||||||
"serve.docs": "cd docs && docsify serve",
|
"serve.docs": "cd docs && docsify serve",
|
||||||
"extract": "ts-node --project tsconfig.spec.json scripts/extract-document.ts",
|
"extract": "ts-node --project tsconfig.spec.json scripts/extract-document.ts",
|
||||||
"ts-node": "ts-node --skip-project"
|
"ts-node": "ts-node --project demo/tsconfig.json"
|
||||||
},
|
},
|
||||||
"pre-commit": [
|
"pre-commit": [
|
||||||
"style",
|
"style",
|
||||||
"lint"
|
"lint"
|
||||||
],
|
],
|
||||||
"files": [
|
|
||||||
"build"
|
|
||||||
],
|
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/dolanmiu/docx.git"
|
"url": "git+https://github.com/dolanmiu/docx.git"
|
||||||
@ -49,10 +59,10 @@
|
|||||||
"officegen",
|
"officegen",
|
||||||
"clippy"
|
"clippy"
|
||||||
],
|
],
|
||||||
"types": "./build/index.d.ts",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "^18.0.0",
|
"@types/node": "^18.0.0",
|
||||||
"jszip": "^3.1.5",
|
"fflate": "^0.8.0",
|
||||||
|
"jszip": "3.2.0",
|
||||||
"nanoid": "^3.3.4",
|
"nanoid": "^3.3.4",
|
||||||
"xml": "^1.0.1",
|
"xml": "^1.0.1",
|
||||||
"xml-js": "^1.6.8"
|
"xml-js": "^1.6.8"
|
||||||
@ -101,7 +111,6 @@
|
|||||||
"request": "^2.88.0",
|
"request": "^2.88.0",
|
||||||
"request-promise": "^4.2.2",
|
"request-promise": "^4.2.2",
|
||||||
"rimraf": "^4.0.4",
|
"rimraf": "^4.0.4",
|
||||||
"shelljs": "^0.8.4",
|
|
||||||
"sinon": "^15.0.0",
|
"sinon": "^15.0.0",
|
||||||
"stream-browserify": "^3.0.0",
|
"stream-browserify": "^3.0.0",
|
||||||
"ts-loader": "^9.0.0",
|
"ts-loader": "^9.0.0",
|
||||||
@ -112,6 +121,8 @@
|
|||||||
"typescript": "5.0.3",
|
"typescript": "5.0.3",
|
||||||
"unzipper": "^0.10.11",
|
"unzipper": "^0.10.11",
|
||||||
"vite": "^4.3.2",
|
"vite": "^4.3.2",
|
||||||
|
"vite-plugin-dts": "^2.3.0",
|
||||||
|
"vite-plugin-node-polyfills": "^0.8.2",
|
||||||
"vite-tsconfig-paths": "^4.2.0",
|
"vite-tsconfig-paths": "^4.2.0",
|
||||||
"webpack": "^5.28.0",
|
"webpack": "^5.28.0",
|
||||||
"webpack-cli": "^5.0.0"
|
"webpack-cli": "^5.0.0"
|
||||||
|
@ -1,180 +1,180 @@
|
|||||||
/* tslint:disable:typedef space-before-function-paren */
|
// /* tslint:disable:typedef space-before-function-paren */
|
||||||
import { expect } from "chai";
|
// import { expect } from "chai";
|
||||||
import * as sinon from "sinon";
|
// import * as sinon from "sinon";
|
||||||
|
|
||||||
import { File } from "@file/file";
|
// import { File } from "@file/file";
|
||||||
import { Footer, Header } from "@file/header";
|
// import { Footer, Header } from "@file/header";
|
||||||
import { ImageRun, Paragraph } from "@file/paragraph";
|
// import { ImageRun, Paragraph } from "@file/paragraph";
|
||||||
import * as convenienceFunctions from "@util/convenience-functions";
|
// import * as convenienceFunctions from "@util/convenience-functions";
|
||||||
|
|
||||||
import { Compiler } from "./next-compiler";
|
// import { Compiler } from "./next-compiler";
|
||||||
|
|
||||||
describe("Compiler", () => {
|
// describe("Compiler", () => {
|
||||||
let compiler: Compiler;
|
// let compiler: Compiler;
|
||||||
|
|
||||||
beforeEach(() => {
|
// beforeEach(() => {
|
||||||
compiler = new Compiler();
|
// compiler = new Compiler();
|
||||||
});
|
// });
|
||||||
|
|
||||||
before(() => {
|
// before(() => {
|
||||||
sinon.stub(convenienceFunctions, "uniqueId").callsFake(() => "test");
|
// sinon.stub(convenienceFunctions, "uniqueId").callsFake(() => "test");
|
||||||
});
|
// });
|
||||||
|
|
||||||
after(() => {
|
// after(() => {
|
||||||
(convenienceFunctions.uniqueId as sinon.SinonStub).restore();
|
// (convenienceFunctions.uniqueId as sinon.SinonStub).restore();
|
||||||
});
|
// });
|
||||||
|
|
||||||
describe("#compile()", () => {
|
// describe("#compile()", () => {
|
||||||
it("should pack all the content", function () {
|
// it("should pack all the content", async function () {
|
||||||
this.timeout(99999999);
|
// this.timeout(99999999);
|
||||||
const file = new File({
|
// const file = new File({
|
||||||
sections: [],
|
// sections: [],
|
||||||
comments: {
|
// comments: {
|
||||||
children: [],
|
// children: [],
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
const zipFile = compiler.compile(file);
|
// const zipFile = await compiler.compile(file);
|
||||||
const fileNames = Object.keys(zipFile.files).map((f) => zipFile.files[f].name);
|
// const fileNames = Object.keys(zipFile.files).map((f) => zipFile.files[f].name);
|
||||||
|
|
||||||
expect(fileNames).is.an.instanceof(Array);
|
// expect(fileNames).is.an.instanceof(Array);
|
||||||
expect(fileNames).has.length(17);
|
// expect(fileNames).has.length(17);
|
||||||
expect(fileNames).to.include("word/document.xml");
|
// expect(fileNames).to.include("word/document.xml");
|
||||||
expect(fileNames).to.include("word/styles.xml");
|
// expect(fileNames).to.include("word/styles.xml");
|
||||||
expect(fileNames).to.include("docProps/core.xml");
|
// expect(fileNames).to.include("docProps/core.xml");
|
||||||
expect(fileNames).to.include("docProps/custom.xml");
|
// expect(fileNames).to.include("docProps/custom.xml");
|
||||||
expect(fileNames).to.include("docProps/app.xml");
|
// expect(fileNames).to.include("docProps/app.xml");
|
||||||
expect(fileNames).to.include("word/numbering.xml");
|
// expect(fileNames).to.include("word/numbering.xml");
|
||||||
expect(fileNames).to.include("word/footnotes.xml");
|
// expect(fileNames).to.include("word/footnotes.xml");
|
||||||
expect(fileNames).to.include("word/_rels/footnotes.xml.rels");
|
// expect(fileNames).to.include("word/_rels/footnotes.xml.rels");
|
||||||
expect(fileNames).to.include("word/settings.xml");
|
// expect(fileNames).to.include("word/settings.xml");
|
||||||
expect(fileNames).to.include("word/comments.xml");
|
// expect(fileNames).to.include("word/comments.xml");
|
||||||
expect(fileNames).to.include("word/_rels/document.xml.rels");
|
// expect(fileNames).to.include("word/_rels/document.xml.rels");
|
||||||
expect(fileNames).to.include("[Content_Types].xml");
|
// expect(fileNames).to.include("[Content_Types].xml");
|
||||||
expect(fileNames).to.include("_rels/.rels");
|
// expect(fileNames).to.include("_rels/.rels");
|
||||||
});
|
// });
|
||||||
|
|
||||||
it("should pack all additional headers and footers", function () {
|
// it("should pack all additional headers and footers", function () {
|
||||||
const file = new File({
|
// const file = new File({
|
||||||
sections: [
|
// sections: [
|
||||||
{
|
// {
|
||||||
headers: {
|
// headers: {
|
||||||
default: new Header({
|
// default: new Header({
|
||||||
children: [new Paragraph("test")],
|
// children: [new Paragraph("test")],
|
||||||
}),
|
// }),
|
||||||
},
|
// },
|
||||||
footers: {
|
// footers: {
|
||||||
default: new Footer({
|
// default: new Footer({
|
||||||
children: [new Paragraph("test")],
|
// children: [new Paragraph("test")],
|
||||||
}),
|
// }),
|
||||||
},
|
// },
|
||||||
children: [],
|
// children: [],
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
headers: {
|
// headers: {
|
||||||
default: new Header({
|
// default: new Header({
|
||||||
children: [new Paragraph("test")],
|
// children: [new Paragraph("test")],
|
||||||
}),
|
// }),
|
||||||
},
|
// },
|
||||||
footers: {
|
// footers: {
|
||||||
default: new Footer({
|
// default: new Footer({
|
||||||
children: [new Paragraph("test")],
|
// children: [new Paragraph("test")],
|
||||||
}),
|
// }),
|
||||||
},
|
// },
|
||||||
children: [],
|
// children: [],
|
||||||
},
|
// },
|
||||||
],
|
// ],
|
||||||
});
|
// });
|
||||||
|
|
||||||
this.timeout(99999999);
|
// this.timeout(99999999);
|
||||||
|
|
||||||
const zipFile = compiler.compile(file);
|
// const zipFile = compiler.compile(file);
|
||||||
const fileNames = Object.keys(zipFile.files).map((f) => zipFile.files[f].name);
|
// const fileNames = Object.keys(zipFile.files).map((f) => zipFile.files[f].name);
|
||||||
|
|
||||||
expect(fileNames).is.an.instanceof(Array);
|
// expect(fileNames).is.an.instanceof(Array);
|
||||||
expect(fileNames).has.length(25);
|
// expect(fileNames).has.length(25);
|
||||||
|
|
||||||
expect(fileNames).to.include("word/header1.xml");
|
// expect(fileNames).to.include("word/header1.xml");
|
||||||
expect(fileNames).to.include("word/_rels/header1.xml.rels");
|
// expect(fileNames).to.include("word/_rels/header1.xml.rels");
|
||||||
expect(fileNames).to.include("word/header2.xml");
|
// expect(fileNames).to.include("word/header2.xml");
|
||||||
expect(fileNames).to.include("word/_rels/header2.xml.rels");
|
// expect(fileNames).to.include("word/_rels/header2.xml.rels");
|
||||||
expect(fileNames).to.include("word/footer1.xml");
|
// expect(fileNames).to.include("word/footer1.xml");
|
||||||
expect(fileNames).to.include("word/_rels/footer1.xml.rels");
|
// expect(fileNames).to.include("word/_rels/footer1.xml.rels");
|
||||||
expect(fileNames).to.include("word/footer2.xml");
|
// expect(fileNames).to.include("word/footer2.xml");
|
||||||
expect(fileNames).to.include("word/_rels/footer2.xml.rels");
|
// expect(fileNames).to.include("word/_rels/footer2.xml.rels");
|
||||||
});
|
// });
|
||||||
|
|
||||||
it("should call the format method X times equalling X files to be formatted", () => {
|
// 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 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.
|
// // This also caused issues such as running prepForXml multiple times as format() was ran multiple times.
|
||||||
const paragraph = new Paragraph("");
|
// const paragraph = new Paragraph("");
|
||||||
const file = new File({
|
// const file = new File({
|
||||||
sections: [
|
// sections: [
|
||||||
{
|
// {
|
||||||
properties: {},
|
// properties: {},
|
||||||
children: [paragraph],
|
// children: [paragraph],
|
||||||
},
|
// },
|
||||||
],
|
// ],
|
||||||
});
|
// });
|
||||||
|
|
||||||
// tslint:disable-next-line: no-string-literal
|
// // tslint:disable-next-line: no-string-literal
|
||||||
const spy = sinon.spy(compiler["formatter"], "format");
|
// const spy = sinon.spy(compiler["formatter"], "format");
|
||||||
|
|
||||||
compiler.compile(file);
|
// compiler.compile(file);
|
||||||
expect(spy.callCount).to.equal(13);
|
// expect(spy.callCount).to.equal(13);
|
||||||
});
|
// });
|
||||||
|
|
||||||
it("should work with media datas", () => {
|
// it("should work with media datas", () => {
|
||||||
// This test is required because before, there was a case where Document was formatted twice, which was inefficient
|
// // 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.
|
// // This also caused issues such as running prepForXml multiple times as format() was ran multiple times.
|
||||||
const file = new File({
|
// const file = new File({
|
||||||
sections: [
|
// sections: [
|
||||||
{
|
// {
|
||||||
headers: {
|
// headers: {
|
||||||
default: new Header({
|
// default: new Header({
|
||||||
children: [new Paragraph("test")],
|
// children: [new Paragraph("test")],
|
||||||
}),
|
// }),
|
||||||
},
|
// },
|
||||||
footers: {
|
// footers: {
|
||||||
default: new Footer({
|
// default: new Footer({
|
||||||
children: [new Paragraph("test")],
|
// children: [new Paragraph("test")],
|
||||||
}),
|
// }),
|
||||||
},
|
// },
|
||||||
children: [
|
// children: [
|
||||||
new Paragraph({
|
// new Paragraph({
|
||||||
children: [
|
// children: [
|
||||||
new ImageRun({
|
// new ImageRun({
|
||||||
data: Buffer.from("", "base64"),
|
// data: Buffer.from("", "base64"),
|
||||||
transformation: {
|
// transformation: {
|
||||||
width: 100,
|
// width: 100,
|
||||||
height: 100,
|
// height: 100,
|
||||||
},
|
// },
|
||||||
}),
|
// }),
|
||||||
],
|
// ],
|
||||||
}),
|
// }),
|
||||||
],
|
// ],
|
||||||
},
|
// },
|
||||||
],
|
// ],
|
||||||
});
|
// });
|
||||||
|
|
||||||
// tslint:disable-next-line: no-string-literal
|
// // tslint:disable-next-line: no-string-literal
|
||||||
sinon.stub(compiler["imageReplacer"], "getMediaData").returns([
|
// sinon.stub(compiler["imageReplacer"], "getMediaData").returns([
|
||||||
{
|
// {
|
||||||
stream: Buffer.from(""),
|
// stream: Buffer.from(""),
|
||||||
fileName: "test",
|
// fileName: "test",
|
||||||
transformation: {
|
// transformation: {
|
||||||
pixels: {
|
// pixels: {
|
||||||
x: 100,
|
// x: 100,
|
||||||
y: 100,
|
// y: 100,
|
||||||
},
|
// },
|
||||||
emus: {
|
// emus: {
|
||||||
x: 100,
|
// x: 100,
|
||||||
y: 100,
|
// y: 100,
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
]);
|
// ]);
|
||||||
|
|
||||||
compiler.compile(file);
|
// compiler.compile(file);
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import JSZip from "jszip";
|
import { strToU8, zip } from "fflate";
|
||||||
import xml from "xml";
|
import xml from "xml";
|
||||||
|
|
||||||
import { File } from "@file/file";
|
import { File } from "@file/file";
|
||||||
@ -44,26 +44,39 @@ export class Compiler {
|
|||||||
this.numberingReplacer = new NumberingReplacer();
|
this.numberingReplacer = new NumberingReplacer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public compile(file: File, prettifyXml?: PrettifyType): JSZip {
|
public compile(file: File, prettifyXml?: PrettifyType): Promise<Uint8Array> {
|
||||||
const zip = new JSZip();
|
|
||||||
const xmlifiedFileMapping = this.xmlifyFile(file, prettifyXml);
|
const xmlifiedFileMapping = this.xmlifyFile(file, prettifyXml);
|
||||||
const map = new Map<string, IXmlifyedFile | readonly IXmlifyedFile[]>(Object.entries(xmlifiedFileMapping));
|
const map = new Map<string, IXmlifyedFile | readonly IXmlifyedFile[]>(Object.entries(xmlifiedFileMapping));
|
||||||
|
|
||||||
for (const [, obj] of map) {
|
return new Promise<Uint8Array>((resolve, reject) => {
|
||||||
if (Array.isArray(obj)) {
|
zip(
|
||||||
for (const subFile of obj as readonly IXmlifyedFile[]) {
|
{
|
||||||
zip.file(subFile.path, subFile.data);
|
...Array.from(map.entries()).reduce((acc, [, obj]) => {
|
||||||
}
|
if (Array.isArray(obj)) {
|
||||||
} else {
|
for (const subFile of obj as readonly IXmlifyedFile[]) {
|
||||||
zip.file((obj as IXmlifyedFile).path, (obj as IXmlifyedFile).data);
|
// eslint-disable-next-line functional/immutable-data
|
||||||
}
|
acc[subFile.path] = strToU8(subFile.data);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// eslint-disable-next-line functional/immutable-data
|
||||||
|
acc[(obj as IXmlifyedFile).path] = strToU8((obj as IXmlifyedFile).data);
|
||||||
|
}
|
||||||
|
|
||||||
for (const { stream, fileName } of file.Media.Array) {
|
return acc;
|
||||||
zip.file(`word/media/${fileName}`, stream);
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
}
|
}, {} as any),
|
||||||
|
...file.Media.Array.reduce((acc, { stream, fileName }) => ({ ...acc, [`word/media/${fileName}`]: stream }), {}),
|
||||||
return zip;
|
},
|
||||||
|
{},
|
||||||
|
(err, data) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
resolve(data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private xmlifyFile(file: File, prettify?: PrettifyType): IXmlifyedFileMapping {
|
private xmlifyFile(file: File, prettify?: PrettifyType): IXmlifyedFileMapping {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Stream } from "stream";
|
import { Stream } from "stream";
|
||||||
import { File } from "@file/file";
|
import { File } from "@file/file";
|
||||||
|
import { strFromU8 } from "fflate";
|
||||||
|
|
||||||
import { Compiler } from "./next-compiler";
|
import { Compiler } from "./next-compiler";
|
||||||
|
|
||||||
@ -15,59 +16,52 @@ export enum PrettifyType {
|
|||||||
|
|
||||||
export class Packer {
|
export class Packer {
|
||||||
public static async toString(file: File, prettify?: boolean | PrettifyType): Promise<string> {
|
public static async toString(file: File, prettify?: boolean | PrettifyType): Promise<string> {
|
||||||
const zip = this.compiler.compile(file, prettify === true ? PrettifyType.WITH_2_BLANKS : prettify === false ? undefined : prettify);
|
const zip = await this.compiler.compile(
|
||||||
const zipData = await zip.generateAsync({
|
file,
|
||||||
type: "string",
|
prettify === true ? PrettifyType.WITH_2_BLANKS : prettify === false ? undefined : prettify,
|
||||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
);
|
||||||
compression: "DEFLATE",
|
return strFromU8(zip);
|
||||||
});
|
|
||||||
|
|
||||||
return zipData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async toBuffer(file: File, prettify?: boolean | PrettifyType): Promise<Buffer> {
|
public static async toBuffer(file: File, prettify?: boolean | PrettifyType): Promise<Buffer> {
|
||||||
const zip = this.compiler.compile(file, prettify === true ? PrettifyType.WITH_2_BLANKS : prettify === false ? undefined : prettify);
|
const zip = await this.compiler.compile(
|
||||||
const zipData = await zip.generateAsync({
|
file,
|
||||||
type: "nodebuffer",
|
prettify === true ? PrettifyType.WITH_2_BLANKS : prettify === false ? undefined : prettify,
|
||||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
);
|
||||||
compression: "DEFLATE",
|
return Buffer.from(zip.buffer);
|
||||||
});
|
|
||||||
|
|
||||||
return zipData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async toBase64String(file: File, prettify?: boolean | PrettifyType): Promise<string> {
|
public static async toBase64String(file: File, prettify?: boolean | PrettifyType): Promise<string> {
|
||||||
const zip = this.compiler.compile(file, prettify === true ? PrettifyType.WITH_2_BLANKS : prettify === false ? undefined : prettify);
|
const zip = await this.compiler.compile(
|
||||||
const zipData = await zip.generateAsync({
|
file,
|
||||||
type: "base64",
|
prettify === true ? PrettifyType.WITH_2_BLANKS : prettify === false ? undefined : prettify,
|
||||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
);
|
||||||
compression: "DEFLATE",
|
|
||||||
});
|
|
||||||
|
|
||||||
return zipData;
|
return Promise.resolve(strFromU8(zip));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async toBlob(file: File, prettify?: boolean | PrettifyType): Promise<Blob> {
|
public static async toBlob(file: File, prettify?: boolean | PrettifyType): Promise<Blob> {
|
||||||
const zip = this.compiler.compile(file, prettify === true ? PrettifyType.WITH_2_BLANKS : prettify === false ? undefined : prettify);
|
const zip = await this.compiler.compile(
|
||||||
const zipData = await zip.generateAsync({
|
file,
|
||||||
type: "blob",
|
prettify === true ? PrettifyType.WITH_2_BLANKS : prettify === false ? undefined : prettify,
|
||||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
);
|
||||||
compression: "DEFLATE",
|
|
||||||
});
|
|
||||||
|
|
||||||
return zipData;
|
return new Blob([zip.buffer]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static toStream(file: File, prettify?: boolean | PrettifyType): Stream {
|
public static toStream(file: File, prettify?: boolean | PrettifyType): Stream {
|
||||||
const zip = this.compiler.compile(file, prettify === true ? PrettifyType.WITH_2_BLANKS : prettify === false ? undefined : prettify);
|
const zip = this.compiler.compile(file, prettify === true ? PrettifyType.WITH_2_BLANKS : prettify === false ? undefined : prettify);
|
||||||
const zipData = zip.generateNodeStream({
|
|
||||||
type: "nodebuffer",
|
|
||||||
streamFiles: true,
|
|
||||||
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
||||||
compression: "DEFLATE",
|
|
||||||
});
|
|
||||||
|
|
||||||
return zipData;
|
const stream = new Stream();
|
||||||
|
// eslint-disable-next-line functional/immutable-data
|
||||||
|
stream.pipe = (dest) => {
|
||||||
|
zip.then((z) => {
|
||||||
|
dest.write(z);
|
||||||
|
});
|
||||||
|
return dest;
|
||||||
|
};
|
||||||
|
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly compiler = new Compiler();
|
private static readonly compiler = new Compiler();
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "./tsconfig.json",
|
|
||||||
"include": ["src/**/*.ts"],
|
|
||||||
"exclude": ["src/**/*.spec.ts"]
|
|
||||||
}
|
|
@ -36,6 +36,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ts-node": {
|
"ts-node": {
|
||||||
|
"esm": true,
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
import { defineConfig } from "vite";
|
|
||||||
import { resolve } from "path";
|
|
||||||
import tsconfigPaths from "vite-tsconfig-paths";
|
|
||||||
|
|
||||||
/** @type {import('vite').UserConfig} */
|
|
||||||
export default defineConfig({
|
|
||||||
plugins: [
|
|
||||||
tsconfigPaths(),
|
|
||||||
|
|
||||||
],
|
|
||||||
build: {
|
|
||||||
lib: {
|
|
||||||
entry: [resolve(__dirname, "src/index.ts")],
|
|
||||||
name: "docx",
|
|
||||||
fileName: "index",
|
|
||||||
formats: ["iife", "es", "cjs", "umd"],
|
|
||||||
},
|
|
||||||
outDir: resolve(__dirname, "dist"),
|
|
||||||
commonjsOptions: {
|
|
||||||
include: [/node_modules/],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
36
vite.config.ts
Normal file
36
vite.config.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { defineConfig } from "vite";
|
||||||
|
import { resolve } from "path";
|
||||||
|
import tsconfigPaths from "vite-tsconfig-paths";
|
||||||
|
import dts from "vite-plugin-dts";
|
||||||
|
import { nodePolyfills } from "vite-plugin-node-polyfills";
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
tsconfigPaths(),
|
||||||
|
dts(),
|
||||||
|
nodePolyfills({
|
||||||
|
exclude: ["fs"],
|
||||||
|
protocolImports: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"@util/": `${resolve(__dirname, "src/util")}/`,
|
||||||
|
"@export/": `${resolve(__dirname, "src/export")}/`,
|
||||||
|
"@file/": `${resolve(__dirname, "src/file")}/`,
|
||||||
|
"@shared": `${resolve(__dirname, "src/shared")}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
lib: {
|
||||||
|
entry: [resolve(__dirname, "src/index.ts")],
|
||||||
|
name: "docx",
|
||||||
|
fileName: "index",
|
||||||
|
formats: ["iife", "es", "cjs", "umd"],
|
||||||
|
},
|
||||||
|
outDir: resolve(__dirname, "build"),
|
||||||
|
commonjsOptions: {
|
||||||
|
include: [/node_modules/],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
@ -1,51 +0,0 @@
|
|||||||
const path = require("path");
|
|
||||||
const { ProvidePlugin } = require("webpack");
|
|
||||||
const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
|
|
||||||
|
|
||||||
const configuration = {
|
|
||||||
mode: "production",
|
|
||||||
|
|
||||||
entry: "./src/index.ts",
|
|
||||||
|
|
||||||
output: {
|
|
||||||
path: path.resolve("build"),
|
|
||||||
filename: "index.js",
|
|
||||||
libraryTarget: "umd",
|
|
||||||
library: "docx",
|
|
||||||
globalObject: "globalThis",
|
|
||||||
},
|
|
||||||
|
|
||||||
resolve: {
|
|
||||||
extensions: [".ts", ".js"],
|
|
||||||
modules: [path.resolve("./src"), "node_modules"],
|
|
||||||
fallback: {
|
|
||||||
buffer: require.resolve("buffer"),
|
|
||||||
stream: require.resolve("stream-browserify"),
|
|
||||||
},
|
|
||||||
plugins: [new TsconfigPathsPlugin()],
|
|
||||||
alias: {
|
|
||||||
jszip: require.resolve('jszip/lib/index.js'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
module: {
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
test: /\.ts$/,
|
|
||||||
loader: "ts-loader",
|
|
||||||
options: {
|
|
||||||
configFile: "tsconfig.lib.json",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
plugins: [
|
|
||||||
// fix "process is not defined" error
|
|
||||||
new ProvidePlugin({
|
|
||||||
process: "process/browser",
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = configuration;
|
|
Reference in New Issue
Block a user