Merge pull request #1662 from dolanmiu/feat/tslint-to-eslint

TSLint to ESLint
This commit is contained in:
Dolan
2022-09-22 09:12:55 +01:00
committed by GitHub
248 changed files with 5034 additions and 791 deletions

270
.eslintrc.js Normal file
View File

@ -0,0 +1,270 @@
/*
👋 Hi! This file was autogenerated by tslint-to-eslint-config.
https://github.com/typescript-eslint/tslint-to-eslint-config
It represents the closest reasonable ESLint configuration to this
project's original TSLint configuration.
We recommend eventually switching this configuration to extend from
the recommended rulesets in typescript-eslint.
https://github.com/typescript-eslint/tslint-to-eslint-config/blob/master/docs/FAQs.md
Happy linting! 💖
*/
module.exports = {
extends: "eslint:recommended",
env: {
browser: true,
es6: true,
node: true,
},
parser: "@typescript-eslint/parser",
parserOptions: {
project: "tsconfig.json",
sourceType: "module",
},
plugins: [
"eslint-plugin-import",
"eslint-plugin-no-null",
"eslint-plugin-unicorn",
"eslint-plugin-jsdoc",
"eslint-plugin-prefer-arrow",
"@typescript-eslint",
"functional",
],
root: true,
rules: {
"no-undef": "off",
"no-extra-boolean-cast": "off",
"no-alert": "error",
"no-self-compare": "error",
"no-unreachable-loop": "error",
"no-template-curly-in-string": "error",
"no-unused-private-class-members": "error",
"no-extend-native": "error",
"no-floating-decimal": "error",
"no-implied-eval": "error",
"no-iterator": "error",
"no-lone-blocks": "error",
"no-loop-func": "error",
"no-new-object": "error",
"no-proto": "error",
"no-useless-catch": "error",
"one-var-declaration-per-line": "error",
"prefer-arrow-callback": "error",
"prefer-destructuring": "error",
"prefer-exponentiation-operator": "error",
"prefer-promise-reject-errors": "error",
"prefer-regex-literals": "error",
"prefer-spread": "error",
"prefer-template": "error",
"require-await": "error",
"@typescript-eslint/adjacent-overload-signatures": "error",
"@typescript-eslint/array-type": [
"error",
{
default: "array",
},
],
"@typescript-eslint/ban-types": [
"error",
{
types: {
Object: {
message: "Avoid using the `Object` type. Did you mean `object`?",
},
Function: {
message: "Avoid using the `Function` type. Prefer a specific function type, like `() => void`.",
},
Boolean: {
message: "Avoid using the `Boolean` type. Did you mean `boolean`?",
},
Number: {
message: "Avoid using the `Number` type. Did you mean `number`?",
},
String: {
message: "Avoid using the `String` type. Did you mean `string`?",
},
Symbol: {
message: "Avoid using the `Symbol` type. Did you mean `symbol`?",
},
},
},
],
"@typescript-eslint/consistent-type-assertions": "error",
"@typescript-eslint/dot-notation": "error",
"@typescript-eslint/explicit-function-return-type": [
"error",
{
allowExpressions: false,
allowTypedFunctionExpressions: false,
allowHigherOrderFunctions: false,
allowDirectConstAssertionInArrowFunctions: true,
allowConciseArrowFunctionExpressionsStartingWithVoid: true,
},
],
"@typescript-eslint/explicit-member-accessibility": [
"error",
{
accessibility: "explicit",
overrides: {
accessors: "explicit",
},
},
],
"@typescript-eslint/explicit-module-boundary-types": [
"error",
{
allowArgumentsExplicitlyTypedAsAny: true,
allowDirectConstAssertionInArrowFunctions: true,
allowHigherOrderFunctions: false,
allowTypedFunctionExpressions: false,
},
],
"@typescript-eslint/naming-convention": [
"error",
{
selector: ["objectLiteralProperty"],
leadingUnderscore: "allow",
format: ["camelCase", "PascalCase"],
filter: {
regex: "(^[a-z]+:.+)|_attr|[0-9]",
match: false,
},
},
],
"@typescript-eslint/no-empty-function": "error",
"@typescript-eslint/no-empty-interface": "error",
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/no-misused-new": "error",
"@typescript-eslint/no-namespace": "error",
"@typescript-eslint/no-parameter-properties": "off",
"@typescript-eslint/no-require-imports": "error",
"@typescript-eslint/no-shadow": [
"error",
{
hoist: "all",
},
],
"@typescript-eslint/no-this-alias": "error",
"@typescript-eslint/no-unused-expressions": "error",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/no-var-requires": "error",
"@typescript-eslint/prefer-for-of": "error",
"@typescript-eslint/prefer-function-type": "error",
"@typescript-eslint/prefer-namespace-keyword": "error",
"@typescript-eslint/prefer-readonly": "error",
"@typescript-eslint/triple-slash-reference": [
"error",
{
path: "always",
types: "prefer-import",
lib: "always",
},
],
"@typescript-eslint/typedef": [
"error",
{
parameter: true,
propertyDeclaration: true,
},
],
"@typescript-eslint/unified-signatures": "error",
"arrow-body-style": "error",
complexity: "off",
"consistent-return": "error",
"constructor-super": "error",
curly: "error",
"dot-notation": "off",
eqeqeq: ["error", "smart"],
"guard-for-in": "error",
"id-denylist": ["error", "any", "Number", "number", "String", "string", "Boolean", "boolean", "Undefined", "undefined"],
"id-match": "error",
"import/no-default-export": "error",
"import/no-extraneous-dependencies": "off",
"import/no-internal-modules": "off",
"import/order": "error",
indent: "off",
"jsdoc/check-alignment": "error",
"jsdoc/check-indentation": "off",
"jsdoc/newline-after-description": "error",
"max-classes-per-file": "off",
"max-len": "off",
"new-parens": "error",
"no-bitwise": "error",
"no-caller": "error",
"no-cond-assign": "error",
"no-console": "error",
"no-debugger": "error",
"no-duplicate-case": "error",
"no-duplicate-imports": "error",
"no-empty": "error",
"no-empty-function": "off",
"no-eval": "error",
"no-extra-bind": "error",
"no-fallthrough": "off",
"no-invalid-this": "off",
"no-multiple-empty-lines": "error",
"no-new-func": "error",
"no-new-wrappers": "error",
"no-null/no-null": "error",
"no-param-reassign": "error",
"no-redeclare": "error",
"no-return-await": "error",
"no-sequences": "error",
"no-shadow": "off",
"no-sparse-arrays": "error",
"no-template-curly-in-string": "error",
"no-throw-literal": "error",
"no-trailing-spaces": "error",
"no-undef-init": "error",
"no-underscore-dangle": ["error", { allow: ["_attr"] }],
"no-unsafe-finally": "error",
"no-unused-expressions": "off",
"no-unused-labels": "error",
"no-use-before-define": "off",
"no-useless-constructor": "error",
"no-var": "error",
"object-shorthand": "off",
"one-var": ["error", "never"],
"prefer-arrow/prefer-arrow-functions": "error",
"prefer-const": "error",
"prefer-object-spread": "error",
radix: "error",
"space-in-parens": ["error", "never"],
"spaced-comment": [
"error",
"always",
{
markers: ["/"],
},
],
"unicorn/filename-case": "error",
"unicorn/prefer-ternary": "error",
"use-isnan": "error",
"valid-typeof": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"functional/immutable-data": [
"error",
{
assumeTypes: true,
ignoreImmediateMutation: true,
ignoreAccessorPattern: ["**.root*", "**.numberingReferences*", "**.sections*", "**.properties*"],
},
],
"functional/no-method-signature": "error",
"functional/no-mixed-type": "error",
"functional/prefer-readonly-type": "error",
"no-unused-vars": ["error", { argsIgnorePattern: "^[_]+$" }],
},
overrides: [
{
files: ["*.spec.ts"],
rules: {
"@typescript-eslint/no-unused-expressions": "off",
"@typescript-eslint/dot-notation": "off",
"prefer-destructuring": "off",
},
},
],
};

6
.nycrc
View File

@ -1,9 +1,9 @@
{ {
"check-coverage": true, "check-coverage": true,
"statements": 99.62, "statements": 99.72,
"branches": 96.81, "branches": 97.95,
"functions": 99.82, "functions": 99.82,
"lines": 99.62, "lines": 99.71,
"include": [ "include": [
"src/**/*.ts" "src/**/*.ts"
], ],

View File

@ -1,5 +1,3 @@
{ {
"recommendations": [ "recommendations": ["streetsidesoftware.code-spell-checker", "dbaeumer.vscode-eslint"]
"streetsidesoftware.code-spell-checker"
]
} }

View File

@ -1,4 +1,4 @@
// Simple example to add text to a document // 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, TextRun } from "../build"; import { Document, Packer, Paragraph, TextRun } from "../build";
@ -26,6 +26,5 @@ const doc = new Document({
], ],
}); });
Packer.toStream(doc).then((stream) => { const stream = Packer.toStream(doc);
stream.pipe(fs.createWriteStream("My Document.docx")); stream.pipe(fs.createWriteStream("My Document.docx"));
});

View File

@ -8,11 +8,11 @@
- Follow Prettier standards, and consider using the [Prettier VSCode](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) plugin. - Follow Prettier standards, and consider using the [Prettier VSCode](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) plugin.
- Follow the `TSLint` rules - Follow the `ESLint` rules
## Always think about the user ## Always think about the user
Put yourself in their position, and imagine how they would feel about your feature you wrote. Put yourself in their position, and imagine how they would feel about the feature you wrote.
1. Is it easy to use? 1. Is it easy to use?
2. Has it been documented well? 2. Has it been documented well?

4402
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@
"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 --production",
"lint": "tslint --project .", "lint": "eslint -c .eslintrc.js --ext .ts src",
"build": "npm run webpack && npm run fix-types", "build": "npm run webpack && npm run fix-types",
"webpack": "rimraf ./build && webpack --config ./webpack.config.ts", "webpack": "rimraf ./build && webpack --config ./webpack.config.ts",
"demo": "npm run build && npm run ts-node --skip-project ./demo", "demo": "npm run build && npm run ts-node --skip-project ./demo",
@ -72,10 +72,19 @@
"@types/sinon": "^10.0.0", "@types/sinon": "^10.0.0",
"@types/unzipper": "^0.10.4", "@types/unzipper": "^0.10.4",
"@types/webpack": "^5.0.0", "@types/webpack": "^5.0.0",
"@typescript-eslint/eslint-plugin": "^5.36.1",
"@typescript-eslint/parser": "^5.36.1",
"buffer": "^6.0.3", "buffer": "^6.0.3",
"chai": "^3.5.0", "chai": "^3.5.0",
"cspell": "^6.2.2", "cspell": "^6.2.2",
"docsify-cli": "^4.3.0", "docsify-cli": "^4.3.0",
"eslint": "^8.23.0",
"eslint-plugin-functional": "^4.3.1",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsdoc": "^39.3.6",
"eslint-plugin-no-null": "^1.0.2",
"eslint-plugin-prefer-arrow": "^1.2.3",
"eslint-plugin-unicorn": "^43.0.2",
"glob": "^8.0.1", "glob": "^8.0.1",
"jszip": "^3.1.5", "jszip": "^3.1.5",
"mocha": "^10.0.0", "mocha": "^10.0.0",
@ -95,8 +104,6 @@
"ts-node": "^10.2.1", "ts-node": "^10.2.1",
"tsconfig-paths": "^4.0.0", "tsconfig-paths": "^4.0.0",
"tsconfig-paths-webpack-plugin": "^4.0.0", "tsconfig-paths-webpack-plugin": "^4.0.0",
"tslint": "^6.1.3",
"tslint-immutable": "^6.0.1",
"typedoc": "^0.23.2", "typedoc": "^0.23.2",
"typescript": "4.7.4", "typescript": "4.7.4",
"unzipper": "^0.10.11", "unzipper": "^0.10.11",

View File

@ -1,7 +1,7 @@
import { IMediaData, Media } from "@file/media"; import { IMediaData, Media } from "@file/media";
export class ImageReplacer { export class ImageReplacer {
public replace(xmlData: string, mediaData: IMediaData[], offset: number): string { public replace(xmlData: string, mediaData: readonly IMediaData[], offset: number): string {
let currentXmlData = xmlData; let currentXmlData = xmlData;
mediaData.forEach((image, i) => { mediaData.forEach((image, i) => {
@ -11,7 +11,7 @@ export class ImageReplacer {
return currentXmlData; return currentXmlData;
} }
public getMediaData(xmlData: string, media: Media): IMediaData[] { public getMediaData(xmlData: string, media: Media): readonly IMediaData[] {
return media.Array.filter((image) => xmlData.search(`{${image.fileName}}`) > 0); return media.Array.filter((image) => xmlData.search(`{${image.fileName}}`) > 0);
} }
} }

View File

@ -25,7 +25,7 @@ describe("Compiler", () => {
}); });
describe("#compile()", () => { describe("#compile()", () => {
it("should pack all the content", async function () { it("should pack all the content", function () {
this.timeout(99999999); this.timeout(99999999);
const file = new File({ const file = new File({
sections: [], sections: [],
@ -53,7 +53,7 @@ describe("Compiler", () => {
expect(fileNames).to.include("_rels/.rels"); expect(fileNames).to.include("_rels/.rels");
}); });
it("should pack all additional headers and footers", async function () { it("should pack all additional headers and footers", function () {
const file = new File({ const file = new File({
sections: [ sections: [
{ {

View File

@ -20,10 +20,10 @@ interface IXmlifyedFileMapping {
readonly Numbering: IXmlifyedFile; readonly Numbering: IXmlifyedFile;
readonly Relationships: IXmlifyedFile; readonly Relationships: IXmlifyedFile;
readonly FileRelationships: IXmlifyedFile; readonly FileRelationships: IXmlifyedFile;
readonly Headers: IXmlifyedFile[]; readonly Headers: readonly IXmlifyedFile[];
readonly Footers: IXmlifyedFile[]; readonly Footers: readonly IXmlifyedFile[];
readonly HeaderRelationships: IXmlifyedFile[]; readonly HeaderRelationships: readonly IXmlifyedFile[];
readonly FooterRelationships: IXmlifyedFile[]; readonly FooterRelationships: readonly IXmlifyedFile[];
readonly ContentTypes: IXmlifyedFile; readonly ContentTypes: IXmlifyedFile;
readonly CustomProperties: IXmlifyedFile; readonly CustomProperties: IXmlifyedFile;
readonly AppProperties: IXmlifyedFile; readonly AppProperties: IXmlifyedFile;
@ -38,7 +38,7 @@ export class Compiler {
private readonly imageReplacer: ImageReplacer; private readonly imageReplacer: ImageReplacer;
private readonly numberingReplacer: NumberingReplacer; private readonly numberingReplacer: NumberingReplacer;
constructor() { public constructor() {
this.formatter = new Formatter(); this.formatter = new Formatter();
this.imageReplacer = new ImageReplacer(); this.imageReplacer = new ImageReplacer();
this.numberingReplacer = new NumberingReplacer(); this.numberingReplacer = new NumberingReplacer();
@ -47,15 +47,15 @@ export class Compiler {
public compile(file: File, prettifyXml?: boolean | PrettifyType): JSZip { public compile(file: File, prettifyXml?: boolean | PrettifyType): JSZip {
const zip = new JSZip(); const zip = new JSZip();
const xmlifiedFileMapping = this.xmlifyFile(file, prettifyXml); const xmlifiedFileMapping = this.xmlifyFile(file, prettifyXml);
const map = new Map<string, IXmlifyedFile | IXmlifyedFile[]>(Object.entries(xmlifiedFileMapping)); const map = new Map<string, IXmlifyedFile | readonly IXmlifyedFile[]>(Object.entries(xmlifiedFileMapping));
for (const [, obj] of map) { for (const [, obj] of map) {
if (Array.isArray(obj)) { if (Array.isArray(obj)) {
for (const subFile of obj) { for (const subFile of obj as readonly IXmlifyedFile[]) {
zip.file(subFile.path, subFile.data); zip.file(subFile.path, subFile.data);
} }
} else { } else {
zip.file(obj.path, obj.data); zip.file((obj as IXmlifyedFile).path, (obj as IXmlifyedFile).data);
} }
} }

View File

@ -1,7 +1,7 @@
import { ConcreteNumbering } from "@file/numbering"; import { ConcreteNumbering } from "@file/numbering";
export class NumberingReplacer { export class NumberingReplacer {
public replace(xmlData: string, concreteNumberings: ConcreteNumbering[]): string { public replace(xmlData: string, concreteNumberings: readonly ConcreteNumbering[]): string {
let currentXmlData = xmlData; let currentXmlData = xmlData;
for (const concreteNumbering of concreteNumberings) { for (const concreteNumbering of concreteNumberings) {

View File

@ -55,7 +55,7 @@ describe("Packer", () => {
}); });
it("should handle exception if it throws any", () => { it("should handle exception if it throws any", () => {
// tslint:disable-next-line:no-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
const compiler = stub((Packer as any).compiler, "compile"); const compiler = stub((Packer as any).compiler, "compile");
compiler.throwsException(); compiler.throwsException();
@ -65,7 +65,7 @@ describe("Packer", () => {
}); });
after(() => { after(() => {
// tslint:disable-next-line:no-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
(Packer as any).compiler.compile.restore(); (Packer as any).compiler.compile.restore();
}); });
}); });
@ -80,7 +80,7 @@ describe("Packer", () => {
}); });
it("should handle exception if it throws any", () => { it("should handle exception if it throws any", () => {
// tslint:disable-next-line:no-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
const compiler = stub((Packer as any).compiler, "compile"); const compiler = stub((Packer as any).compiler, "compile");
compiler.throwsException(); compiler.throwsException();
@ -90,14 +90,14 @@ describe("Packer", () => {
}); });
after(() => { after(() => {
// tslint:disable-next-line:no-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
(Packer as any).compiler.compile.restore(); (Packer as any).compiler.compile.restore();
}); });
}); });
describe("#toBlob()", () => { describe("#toBlob()", () => {
it("should create a standard docx file", async () => { it("should create a standard docx file", async () => {
// tslint:disable-next-line: no-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
stub((Packer as any).compiler, "compile").callsFake(() => ({ stub((Packer as any).compiler, "compile").callsFake(() => ({
// tslint:disable-next-line: no-empty // tslint:disable-next-line: no-empty
generateAsync: () => mock({}), generateAsync: () => mock({}),
@ -108,7 +108,7 @@ describe("Packer", () => {
}); });
it("should handle exception if it throws any", () => { it("should handle exception if it throws any", () => {
// tslint:disable-next-line:no-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
const compiler = stub((Packer as any).compiler, "compile"); const compiler = stub((Packer as any).compiler, "compile");
compiler.throwsException(); compiler.throwsException();
@ -118,14 +118,14 @@ describe("Packer", () => {
}); });
afterEach(() => { afterEach(() => {
// tslint:disable-next-line:no-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
(Packer as any).compiler.compile.restore(); (Packer as any).compiler.compile.restore();
}); });
}); });
describe("#toStream()", () => { describe("#toStream()", () => {
it("should create a standard docx file", async () => { it("should create a standard docx file", async () => {
// tslint:disable-next-line: no-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
stub((Packer as any).compiler, "compile").callsFake(() => ({ stub((Packer as any).compiler, "compile").callsFake(() => ({
// tslint:disable-next-line: no-empty // tslint:disable-next-line: no-empty
generateNodeStream: () => ({ generateNodeStream: () => ({
@ -139,7 +139,7 @@ describe("Packer", () => {
const stream = await Packer.toStream(file); const stream = await Packer.toStream(file);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
stream.on("error", () => { stream.on("error", () => {
reject(); reject(new Error());
}); });
stream.on("end", () => { stream.on("end", () => {
@ -148,8 +148,8 @@ describe("Packer", () => {
}); });
}); });
it("should handle exception if it throws any", async () => { it("should handle exception if it throws any", () => {
// tslint:disable-next-line:no-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
const compiler = stub((Packer as any).compiler, "compile").callsFake(() => ({ const compiler = stub((Packer as any).compiler, "compile").callsFake(() => ({
// tslint:disable-next-line: no-empty // tslint:disable-next-line: no-empty
on: (event: string, cb: () => void) => { on: (event: string, cb: () => void) => {
@ -160,13 +160,15 @@ describe("Packer", () => {
})); }));
compiler.throwsException(); compiler.throwsException();
return Packer.toStream(file).catch((error) => { try {
Packer.toStream(file);
} catch (error) {
assert.isDefined(error); assert.isDefined(error);
}); }
}); });
afterEach(() => { afterEach(() => {
// tslint:disable-next-line:no-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
(Packer as any).compiler.compile.restore(); (Packer as any).compiler.compile.restore();
}); });
}); });

View File

@ -1,5 +1,5 @@
import { File } from "@file/file";
import { Stream } from "stream"; import { Stream } from "stream";
import { File } from "@file/file";
import { Compiler } from "./next-compiler"; import { Compiler } from "./next-compiler";
@ -58,7 +58,7 @@ export class Packer {
return zipData; return zipData;
} }
public static async toStream(file: File, prettify?: boolean | PrettifyType): Promise<Stream> { public static toStream(file: File, prettify?: boolean | PrettifyType): Stream {
const zip = this.compiler.compile(file, prettify); const zip = this.compiler.compile(file, prettify);
const zipData = zip.generateNodeStream({ const zipData = zip.generateNodeStream({
type: "nodebuffer", type: "nodebuffer",

View File

@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
import { AppPropertiesAttributes } from "./app-properties-attributes"; import { AppPropertiesAttributes } from "./app-properties-attributes";
export class AppProperties extends XmlComponent { export class AppProperties extends XmlComponent {
constructor() { public constructor() {
super("Properties"); super("Properties");
this.root.push( this.root.push(

View File

@ -33,7 +33,7 @@ export interface IBorderOptions {
} }
export class BorderElement extends XmlComponent { export class BorderElement extends XmlComponent {
constructor(elementName: string, { color, size, space, style }: IBorderOptions) { public constructor(elementName: string, { color, size, space, style }: IBorderOptions) {
super(elementName); super(elementName);
this.root.push( this.root.push(
new BordersAttributes({ new BordersAttributes({

View File

@ -4,7 +4,7 @@ import { Default } from "./default/default";
import { Override } from "./override/override"; import { Override } from "./override/override";
export class ContentTypes extends XmlComponent { export class ContentTypes extends XmlComponent {
constructor() { public constructor() {
super("Types"); super("Types");
this.root.push( this.root.push(

View File

@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
import { DefaultAttributes } from "./default-attributes"; import { DefaultAttributes } from "./default-attributes";
export class Default extends XmlComponent { export class Default extends XmlComponent {
constructor(contentType: string, extension?: string) { public constructor(contentType: string, extension?: string) {
super("Default"); super("Default");
this.root.push( this.root.push(

View File

@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
import { OverrideAttributes } from "./override-attributes"; import { OverrideAttributes } from "./override-attributes";
export class Override extends XmlComponent { export class Override extends XmlComponent {
constructor(contentType: string, partName?: string) { public constructor(contentType: string, partName?: string) {
super("Override"); super("Override");
this.root.push( this.root.push(

View File

@ -12,7 +12,7 @@ import { Paragraph } from "../paragraph";
import { IStylesOptions } from "../styles"; import { IStylesOptions } from "../styles";
export interface IPropertiesOptions { export interface IPropertiesOptions {
readonly sections: ISectionOptions[]; readonly sections: readonly ISectionOptions[];
readonly title?: string; readonly title?: string;
readonly subject?: string; readonly subject?: string;
readonly creator?: string; readonly creator?: string;
@ -26,7 +26,7 @@ export interface IPropertiesOptions {
readonly comments?: ICommentsOptions; readonly comments?: ICommentsOptions;
readonly footnotes?: { readonly footnotes?: {
readonly [key: string]: { readonly [key: string]: {
readonly children: Paragraph[]; readonly children: readonly Paragraph[];
}; };
}; };
readonly background?: IDocumentBackgroundOptions; readonly background?: IDocumentBackgroundOptions;
@ -35,7 +35,7 @@ export interface IPropertiesOptions {
readonly updateFields?: boolean; readonly updateFields?: boolean;
}; };
readonly compatabilityModeVersion?: number; readonly compatabilityModeVersion?: number;
readonly customProperties?: ICustomPropertyOptions[]; readonly customProperties?: readonly ICustomPropertyOptions[];
readonly evenAndOddHeaderAndFooters?: boolean; readonly evenAndOddHeaderAndFooters?: boolean;
} }
@ -64,7 +64,7 @@ export interface IPropertiesOptions {
/* cSpell:enable */ /* cSpell:enable */
export class CoreProperties extends XmlComponent { export class CoreProperties extends XmlComponent {
constructor(options: Omit<IPropertiesOptions, "sections">) { public constructor(options: Omit<IPropertiesOptions, "sections">) {
super("cp:coreProperties"); super("cp:coreProperties");
this.root.push( this.root.push(
new DocumentAttributes({ new DocumentAttributes({
@ -102,7 +102,7 @@ export class CoreProperties extends XmlComponent {
} }
class TimestampElement extends XmlComponent { class TimestampElement extends XmlComponent {
constructor(name: string) { public constructor(name: string) {
super(name); super(name);
this.root.push( this.root.push(
new DocumentAttributes({ new DocumentAttributes({

View File

@ -3,11 +3,12 @@ import { CustomPropertiesAttributes } from "./custom-properties-attributes";
import { CustomProperty, ICustomPropertyOptions } from "./custom-property"; import { CustomProperty, ICustomPropertyOptions } from "./custom-property";
export class CustomProperties extends XmlComponent { export class CustomProperties extends XmlComponent {
// tslint:disable-next-line:readonly-keyword // eslint-disable-next-line functional/prefer-readonly-type
private nextId: number; private nextId: number;
// eslint-disable-next-line functional/prefer-readonly-type
private readonly properties: CustomProperty[] = []; private readonly properties: CustomProperty[] = [];
constructor(properties: ICustomPropertyOptions[]) { public constructor(properties: readonly ICustomPropertyOptions[]) {
super("Properties"); super("Properties");
this.root.push( this.root.push(
@ -32,6 +33,7 @@ export class CustomProperties extends XmlComponent {
} }
public addCustomProperty(property: ICustomPropertyOptions): void { public addCustomProperty(property: ICustomPropertyOptions): void {
// eslint-disable-next-line functional/immutable-data
this.properties.push(new CustomProperty(this.nextId++, property)); this.properties.push(new CustomProperty(this.nextId++, property));
} }
} }

View File

@ -7,7 +7,7 @@ export interface ICustomPropertyOptions {
} }
export class CustomProperty extends XmlComponent { export class CustomProperty extends XmlComponent {
constructor(id: number, properties: ICustomPropertyOptions) { public constructor(id: number, properties: ICustomPropertyOptions) {
super("property"); super("property");
this.root.push( this.root.push(
new CustomPropertyAttributes({ new CustomPropertyAttributes({
@ -21,7 +21,7 @@ export class CustomProperty extends XmlComponent {
} }
export class CustomPropertyValue extends XmlComponent { export class CustomPropertyValue extends XmlComponent {
constructor(value: string) { public constructor(value: string) {
super("vt:lpwstr"); super("vt:lpwstr");
this.root.push(value); this.root.push(value);
} }

View File

@ -7,9 +7,7 @@ describe("DocumentWrapper", () => {
it("should create", () => { it("should create", () => {
const file = new DocumentWrapper({ background: {} }); const file = new DocumentWrapper({ background: {} });
// tslint:disable-next-line: no-unused-expression
expect(file.View).to.be.ok; expect(file.View).to.be.ok;
// tslint:disable-next-line: no-unused-expression
expect(file.Relationships).to.be.ok; expect(file.Relationships).to.be.ok;
}); });
}); });

View File

@ -13,7 +13,7 @@ export class DocumentWrapper implements IViewWrapper {
private readonly document: Document; private readonly document: Document;
private readonly relationships: Relationships; private readonly relationships: Relationships;
constructor(options: IDocumentOptions) { public constructor(options: IDocumentOptions) {
this.document = new Document(options); this.document = new Document(options);
this.relationships = new Relationships(); this.relationships = new Relationships();
} }

View File

@ -4,9 +4,10 @@ import { IContext, IXmlableObject, XmlComponent } from "@file/xml-components";
import { ISectionPropertiesOptions, SectionProperties } from "./section-properties/section-properties"; import { ISectionPropertiesOptions, SectionProperties } from "./section-properties/section-properties";
export class Body extends XmlComponent { export class Body extends XmlComponent {
// eslint-disable-next-line functional/prefer-readonly-type
private readonly sections: SectionProperties[] = []; private readonly sections: SectionProperties[] = [];
constructor() { public constructor() {
super("w:body"); super("w:body");
} }
@ -16,6 +17,7 @@ export class Body extends XmlComponent {
* The spec says: * The spec says:
* - section element should be in the last paragraph of the section * - section element should be in the last paragraph of the section
* - last section should be direct child of body * - last section should be direct child of body
*
* @param options new section options * @param options new section options
*/ */
public addSection(options: ISectionPropertiesOptions): void { public addSection(options: ISectionPropertiesOptions): void {

View File

@ -14,7 +14,7 @@ export class ColumnAttributes extends XmlAttributeComponent<IColumnAttributes> {
} }
export class Column extends XmlComponent { export class Column extends XmlComponent {
constructor({ width, space }: IColumnAttributes) { public constructor({ width, space }: IColumnAttributes) {
super("w:col"); super("w:col");
this.root.push( this.root.push(
new ColumnAttributes({ new ColumnAttributes({

View File

@ -13,6 +13,13 @@ describe("Columns", () => {
expect(tree["w:cols"]).to.deep.equal({ _attr: { "w:num": 3, "w:space": 720 } }); expect(tree["w:cols"]).to.deep.equal({ _attr: { "w:num": 3, "w:space": 720 } });
}); });
it("should create set space and count to undefined if they are undefined", () => {
const columns = new Columns({});
const tree = new Formatter().format(columns);
expect(tree["w:cols"]).to.deep.equal({ _attr: {} });
});
it("should ignore individual column attributes if equalWidth is true", () => { it("should ignore individual column attributes if equalWidth is true", () => {
const unequalColumns = [new Column({ width: 1000, space: 400 }), new Column({ width: 2000 })]; const unequalColumns = [new Column({ width: 1000, space: 400 }), new Column({ width: 2000 })];
const columns = new Columns({ count: 3, space: 720, equalWidth: true, children: unequalColumns }); const columns = new Columns({ count: 3, space: 720, equalWidth: true, children: unequalColumns });

View File

@ -17,7 +17,7 @@ export interface IColumnsAttributes {
readonly count?: number; readonly count?: number;
readonly separate?: boolean; readonly separate?: boolean;
readonly equalWidth?: boolean; readonly equalWidth?: boolean;
readonly children?: Column[]; readonly children?: readonly Column[];
} }
export class ColumnsAttributes extends XmlAttributeComponent<IColumnsAttributes> { export class ColumnsAttributes extends XmlAttributeComponent<IColumnsAttributes> {
@ -30,7 +30,7 @@ export class ColumnsAttributes extends XmlAttributeComponent<IColumnsAttributes>
} }
export class Columns extends XmlComponent { export class Columns extends XmlComponent {
constructor({ space, count, separate, equalWidth, children }: IColumnsAttributes) { public constructor({ space, count, separate, equalWidth, children }: IColumnsAttributes) {
super("w:cols"); super("w:cols");
this.root.push( this.root.push(
new ColumnsAttributes({ new ColumnsAttributes({

View File

@ -38,7 +38,7 @@ export class DocGridAttributes extends XmlAttributeComponent<IDocGridAttributesP
} }
export class DocumentGrid extends XmlComponent { export class DocumentGrid extends XmlComponent {
constructor(linePitch: number, charSpace?: number, type?: DocumentGridType) { public constructor(linePitch: number, charSpace?: number, type?: DocumentGridType) {
super("w:docGrid"); super("w:docGrid");
this.root.push( this.root.push(

View File

@ -52,7 +52,7 @@ export enum HeaderFooterType {
FOOTER = "w:footerReference", FOOTER = "w:footerReference",
} }
export class HeaderFooterReference extends XmlComponent { export class HeaderFooterReference extends XmlComponent {
constructor(type: HeaderFooterType, options: IHeaderFooterOptions) { public constructor(type: HeaderFooterType, options: IHeaderFooterOptions) {
super(type); super(type);
this.root.push( this.root.push(

View File

@ -39,7 +39,7 @@ export class LineNumberAttributes extends XmlAttributeComponent<ILineNumberAttri
} }
export class LineNumberType extends XmlComponent { export class LineNumberType extends XmlComponent {
constructor({ countBy, start, restart, distance }: ILineNumberAttributes) { public constructor({ countBy, start, restart, distance }: ILineNumberAttributes) {
super("w:lnNumType"); super("w:lnNumType");
this.root.push( this.root.push(
new LineNumberAttributes({ new LineNumberAttributes({

View File

@ -71,7 +71,7 @@ class PageBordersAttributes extends XmlAttributeComponent<IPageBorderAttributes>
// <xsd:attribute name="offsetFrom" type="ST_PageBorderOffset" use="optional" default="text"/> // <xsd:attribute name="offsetFrom" type="ST_PageBorderOffset" use="optional" default="text"/>
// </xsd:complexType> // </xsd:complexType>
export class PageBorders extends IgnoreIfEmptyXmlComponent { export class PageBorders extends IgnoreIfEmptyXmlComponent {
constructor(options?: IPageBordersOptions) { public constructor(options?: IPageBordersOptions) {
super("w:pgBorders"); super("w:pgBorders");
if (!options) { if (!options) {

View File

@ -33,7 +33,7 @@ export class PageMarginAttributes extends XmlAttributeComponent<IPageMarginAttri
} }
export class PageMargin extends XmlComponent { export class PageMargin extends XmlComponent {
constructor( public constructor(
top: number | string, top: number | string,
right: number | string, right: number | string,
bottom: number | string, bottom: number | string,

View File

@ -41,7 +41,7 @@ export class PageNumberTypeAttributes extends XmlAttributeComponent<IPageNumberT
}; };
} }
export class PageNumberType extends XmlComponent { export class PageNumberType extends XmlComponent {
constructor({ start, formatType, separator }: IPageNumberTypeAttributes) { public constructor({ start, formatType, separator }: IPageNumberTypeAttributes) {
super("w:pgNumType"); super("w:pgNumType");
this.root.push( this.root.push(
new PageNumberTypeAttributes({ new PageNumberTypeAttributes({

View File

@ -33,7 +33,7 @@ export class PageSizeAttributes extends XmlAttributeComponent<IPageSizeAttribute
} }
export class PageSize extends XmlComponent { export class PageSize extends XmlComponent {
constructor(width: number | string, height: number | string, orientation: PageOrientation) { public constructor(width: number | string, height: number | string, orientation: PageOrientation) {
super("w:pgSz"); super("w:pgSz");
const flip = orientation === PageOrientation.LANDSCAPE; const flip = orientation === PageOrientation.LANDSCAPE;

View File

@ -10,7 +10,7 @@ class PageTextDirectionAttributes extends XmlAttributeComponent<{ readonly val:
} }
export class PageTextDirection extends XmlComponent { export class PageTextDirection extends XmlComponent {
constructor(value: PageTextDirectionType) { public constructor(value: PageTextDirectionType) {
super("w:textDirection"); super("w:textDirection");
this.root.push( this.root.push(

View File

@ -30,7 +30,7 @@ export class SectionTypeAttributes extends XmlAttributeComponent<{
} }
export class Type extends XmlComponent { export class Type extends XmlComponent {
constructor(value: SectionType) { public constructor(value: SectionType) {
super("w:type"); super("w:type");
this.root.push(new SectionTypeAttributes({ val: value })); this.root.push(new SectionTypeAttributes({ val: value }));
} }

View File

@ -92,7 +92,7 @@ export const sectionPageSizeDefaults = {
}; };
export class SectionProperties extends XmlComponent { export class SectionProperties extends XmlComponent {
constructor({ public constructor({
page: { page: {
size: { size: {
width = sectionPageSizeDefaults.WIDTH, width = sectionPageSizeDefaults.WIDTH,

View File

@ -63,7 +63,7 @@ export interface IDocumentBackgroundOptions {
// </xsd:complexType> // </xsd:complexType>
export class DocumentBackground extends XmlComponent { export class DocumentBackground extends XmlComponent {
constructor(options: IDocumentBackgroundOptions) { public constructor(options: IDocumentBackgroundOptions) {
super("w:background"); super("w:background");
this.root.push( this.root.push(

View File

@ -33,7 +33,7 @@ export interface IDocumentOptions {
export class Document extends XmlComponent { export class Document extends XmlComponent {
private readonly body: Body; private readonly body: Body;
constructor(options: IDocumentOptions) { public constructor(options: IDocumentOptions) {
super("w:document"); super("w:document");
this.root.push( this.root.push(
new DocumentAttributes({ new DocumentAttributes({

View File

@ -6,8 +6,8 @@ import { IDrawingOptions } from "../drawing";
import { TextWrappingType } from "../text-wrap"; import { TextWrappingType } from "../text-wrap";
import { Anchor } from "./anchor"; import { Anchor } from "./anchor";
function createAnchor(drawingOptions: IDrawingOptions): Anchor { const createAnchor = (drawingOptions: IDrawingOptions): Anchor =>
return new Anchor( new Anchor(
{ {
fileName: "test.png", fileName: "test.png",
stream: new Buffer(""), stream: new Buffer(""),
@ -34,7 +34,6 @@ function createAnchor(drawingOptions: IDrawingOptions): Anchor {
}, },
drawingOptions, drawingOptions,
); );
}
describe("Anchor", () => { describe("Anchor", () => {
let anchor: Anchor; let anchor: Anchor;

View File

@ -37,7 +37,7 @@ import { AnchorAttributes } from "./anchor-attributes";
// <xsd:attribute name="allowOverlap" type="xsd:boolean" use="required"/> // <xsd:attribute name="allowOverlap" type="xsd:boolean" use="required"/>
// </xsd:complexType> // </xsd:complexType>
export class Anchor extends XmlComponent { export class Anchor extends XmlComponent {
constructor(mediaData: IMediaData, transform: IMediaDataTransformation, drawingOptions: IDrawingOptions) { public constructor(mediaData: IMediaData, transform: IMediaDataTransformation, drawingOptions: IDrawingOptions) {
super("wp:anchor"); super("wp:anchor");
const floating: IFloating = { const floating: IFloating = {

View File

@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
import { DocPropertiesAttributes } from "./doc-properties-attributes"; import { DocPropertiesAttributes } from "./doc-properties-attributes";
export class DocProperties extends XmlComponent { export class DocProperties extends XmlComponent {
constructor() { public constructor() {
super("wp:docPr"); super("wp:docPr");
this.root.push( this.root.push(

View File

@ -6,8 +6,8 @@ import { Drawing, IDrawingOptions } from "./drawing";
const imageBase64Data = `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`; const imageBase64Data = `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`;
function createDrawing(drawingOptions?: IDrawingOptions): Drawing { const createDrawing = (drawingOptions?: IDrawingOptions): Drawing =>
return new Drawing( new Drawing(
{ {
fileName: "test.jpg", fileName: "test.jpg",
stream: Buffer.from(imageBase64Data, "base64"), stream: Buffer.from(imageBase64Data, "base64"),
@ -24,7 +24,6 @@ function createDrawing(drawingOptions?: IDrawingOptions): Drawing {
}, },
drawingOptions, drawingOptions,
); );
}
describe("Drawing", () => { describe("Drawing", () => {
let currentBreak: Drawing; let currentBreak: Drawing;

View File

@ -25,7 +25,7 @@ export interface IDrawingOptions {
export class Drawing extends XmlComponent { export class Drawing extends XmlComponent {
private readonly inline: Inline; private readonly inline: Inline;
constructor(imageData: IMediaData, drawingOptions: IDrawingOptions = {}) { public constructor(imageData: IMediaData, drawingOptions: IDrawingOptions = {}) {
super("w:drawing"); super("w:drawing");
if (!drawingOptions.floating) { if (!drawingOptions.floating) {

View File

@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
import { EffectExtentAttributes } from "./effect-extent-attributes"; import { EffectExtentAttributes } from "./effect-extent-attributes";
export class EffectExtent extends XmlComponent { export class EffectExtent extends XmlComponent {
constructor() { public constructor() {
super("wp:effectExtent"); super("wp:effectExtent");
this.root.push( this.root.push(

View File

@ -5,7 +5,7 @@ import { ExtentAttributes } from "./extent-attributes";
export class Extent extends XmlComponent { export class Extent extends XmlComponent {
private readonly attributes: ExtentAttributes; private readonly attributes: ExtentAttributes;
constructor(x: number, y: number) { public constructor(x: number, y: number) {
super("wp:extent"); super("wp:extent");
this.attributes = new ExtentAttributes({ this.attributes = new ExtentAttributes({

View File

@ -3,7 +3,7 @@ import { HorizontalPositionAlign, VerticalPositionAlign } from "@file/shared/ali
import { XmlComponent } from "@file/xml-components"; import { XmlComponent } from "@file/xml-components";
export class Align extends XmlComponent { export class Align extends XmlComponent {
constructor(value: HorizontalPositionAlign | VerticalPositionAlign) { public constructor(value: HorizontalPositionAlign | VerticalPositionAlign) {
super("wp:align"); super("wp:align");
this.root.push(value); this.root.push(value);
} }

View File

@ -13,7 +13,7 @@ class HorizontalPositionAttributes extends XmlAttributeComponent<{
} }
export class HorizontalPosition extends XmlComponent { export class HorizontalPosition extends XmlComponent {
constructor(horizontalPosition: IHorizontalPositionOptions) { public constructor(horizontalPosition: IHorizontalPositionOptions) {
super("wp:positionH"); super("wp:positionH");
this.root.push( this.root.push(

View File

@ -2,7 +2,7 @@
import { XmlComponent } from "@file/xml-components"; import { XmlComponent } from "@file/xml-components";
export class PositionOffset extends XmlComponent { export class PositionOffset extends XmlComponent {
constructor(offsetValue: number) { public constructor(offsetValue: number) {
super("wp:posOffset"); super("wp:posOffset");
this.root.push(offsetValue.toString()); this.root.push(offsetValue.toString());
} }

View File

@ -12,7 +12,7 @@ class SimplePosAttributes extends XmlAttributeComponent<{
} }
export class SimplePos extends XmlComponent { export class SimplePos extends XmlComponent {
constructor() { public constructor() {
super("wp:simplePos"); super("wp:simplePos");
// NOTE: It's not fully supported in Microsoft Word, but this element is needed anyway // NOTE: It's not fully supported in Microsoft Word, but this element is needed anyway

View File

@ -13,7 +13,7 @@ class VerticalPositionAttributes extends XmlAttributeComponent<{
} }
export class VerticalPosition extends XmlComponent { export class VerticalPosition extends XmlComponent {
constructor(verticalPosition: IVerticalPositionOptions) { public constructor(verticalPosition: IVerticalPositionOptions) {
super("wp:positionV"); super("wp:positionV");
this.root.push( this.root.push(

View File

@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
import { GraphicFrameLockAttributes } from "./graphic-frame-lock-attributes"; import { GraphicFrameLockAttributes } from "./graphic-frame-lock-attributes";
export class GraphicFrameLocks extends XmlComponent { export class GraphicFrameLocks extends XmlComponent {
constructor() { public constructor() {
super("a:graphicFrameLocks"); super("a:graphicFrameLocks");
this.root.push( this.root.push(

View File

@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
import { GraphicFrameLocks } from "./graphic-frame-locks/graphic-frame-locks"; import { GraphicFrameLocks } from "./graphic-frame-locks/graphic-frame-locks";
export class GraphicFrameProperties extends XmlComponent { export class GraphicFrameProperties extends XmlComponent {
constructor() { public constructor() {
super("wp:cNvGraphicFramePr"); super("wp:cNvGraphicFramePr");
this.root.push(new GraphicFrameLocks()); this.root.push(new GraphicFrameLocks());

View File

@ -7,7 +7,7 @@ import { Pic } from "./pic";
export class GraphicData extends XmlComponent { export class GraphicData extends XmlComponent {
private readonly pic: Pic; private readonly pic: Pic;
constructor(mediaData: IMediaData, transform: IMediaDataTransformation) { public constructor(mediaData: IMediaData, transform: IMediaDataTransformation) {
super("a:graphicData"); super("a:graphicData");
this.root.push( this.root.push(

View File

@ -6,7 +6,7 @@ import { SourceRectangle } from "./source-rectangle";
import { Stretch } from "./stretch"; import { Stretch } from "./stretch";
export class BlipFill extends XmlComponent { export class BlipFill extends XmlComponent {
constructor(mediaData: IMediaData) { public constructor(mediaData: IMediaData) {
super("pic:blipFill"); super("pic:blipFill");
this.root.push(new Blip(mediaData)); this.root.push(new Blip(mediaData));

View File

@ -12,7 +12,7 @@ class BlipAttributes extends XmlAttributeComponent<{
} }
export class Blip extends XmlComponent { export class Blip extends XmlComponent {
constructor(mediaData: IMediaData) { public constructor(mediaData: IMediaData) {
super("a:blip"); super("a:blip");
this.root.push( this.root.push(
new BlipAttributes({ new BlipAttributes({

View File

@ -1,7 +1,7 @@
import { XmlComponent } from "@file/xml-components"; import { XmlComponent } from "@file/xml-components";
export class SourceRectangle extends XmlComponent { export class SourceRectangle extends XmlComponent {
constructor() { public constructor() {
super("a:srcRect"); super("a:srcRect");
} }
} }

View File

@ -1,13 +1,13 @@
import { XmlComponent } from "@file/xml-components"; import { XmlComponent } from "@file/xml-components";
class FillRectangle extends XmlComponent { class FillRectangle extends XmlComponent {
constructor() { public constructor() {
super("a:fillRect"); super("a:fillRect");
} }
} }
export class Stretch extends XmlComponent { export class Stretch extends XmlComponent {
constructor() { public constructor() {
super("a:stretch"); super("a:stretch");
this.root.push(new FillRectangle()); this.root.push(new FillRectangle());
} }

View File

@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
import { PicLocks } from "./pic-locks/pic-locks"; import { PicLocks } from "./pic-locks/pic-locks";
export class ChildNonVisualProperties extends XmlComponent { export class ChildNonVisualProperties extends XmlComponent {
constructor() { public constructor() {
super("pic:cNvPicPr"); super("pic:cNvPicPr");
this.root.push(new PicLocks()); this.root.push(new PicLocks());

View File

@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
import { PicLocksAttributes } from "./pic-locks-attributes"; import { PicLocksAttributes } from "./pic-locks-attributes";
export class PicLocks extends XmlComponent { export class PicLocks extends XmlComponent {
constructor() { public constructor() {
super("a:picLocks"); super("a:picLocks");
this.root.push( this.root.push(
new PicLocksAttributes({ new PicLocksAttributes({

View File

@ -3,7 +3,7 @@ import { ChildNonVisualProperties } from "./child-non-visual-pic-properties/chil
import { NonVisualProperties } from "./non-visual-properties/non-visual-properties"; import { NonVisualProperties } from "./non-visual-properties/non-visual-properties";
export class NonVisualPicProperties extends XmlComponent { export class NonVisualPicProperties extends XmlComponent {
constructor() { public constructor() {
super("pic:nvPicPr"); super("pic:nvPicPr");
this.root.push(new NonVisualProperties()); this.root.push(new NonVisualProperties());

View File

@ -2,7 +2,7 @@ import { XmlComponent } from "@file/xml-components";
import { NonVisualPropertiesAttributes } from "./non-visual-properties-attributes"; import { NonVisualPropertiesAttributes } from "./non-visual-properties-attributes";
export class NonVisualProperties extends XmlComponent { export class NonVisualProperties extends XmlComponent {
constructor() { public constructor() {
super("pic:cNvPr"); super("pic:cNvPr");
this.root.push( this.root.push(

View File

@ -8,7 +8,7 @@ import { PicAttributes } from "./pic-attributes";
import { ShapeProperties } from "./shape-properties/shape-properties"; import { ShapeProperties } from "./shape-properties/shape-properties";
export class Pic extends XmlComponent { export class Pic extends XmlComponent {
constructor(mediaData: IMediaData, transform: IMediaDataTransformation) { public constructor(mediaData: IMediaData, transform: IMediaDataTransformation) {
super("pic:pic"); super("pic:pic");
this.root.push( this.root.push(

View File

@ -5,7 +5,7 @@ import { ExtentsAttributes } from "./extents-attributes";
export class Extents extends XmlComponent { export class Extents extends XmlComponent {
private readonly attributes: ExtentsAttributes; private readonly attributes: ExtentsAttributes;
constructor(x: number, y: number) { public constructor(x: number, y: number) {
super("a:ext"); super("a:ext");
this.attributes = new ExtentsAttributes({ this.attributes = new ExtentsAttributes({

View File

@ -21,7 +21,7 @@ export class FormAttributes extends XmlAttributeComponent<{
export class Form extends XmlComponent { export class Form extends XmlComponent {
private readonly extents: Extents; private readonly extents: Extents;
constructor(options: IMediaDataTransformation) { public constructor(options: IMediaDataTransformation) {
super("a:xfrm"); super("a:xfrm");
this.root.push( this.root.push(

View File

@ -3,7 +3,7 @@ import { XmlComponent } from "@file/xml-components";
import { OffsetAttributes } from "./off-attributes"; import { OffsetAttributes } from "./off-attributes";
export class Offset extends XmlComponent { export class Offset extends XmlComponent {
constructor() { public constructor() {
super("a:off"); super("a:off");
this.root.push( this.root.push(

View File

@ -1,7 +1,7 @@
import { XmlComponent } from "@file/xml-components"; import { XmlComponent } from "@file/xml-components";
export class NoFill extends XmlComponent { export class NoFill extends XmlComponent {
constructor() { public constructor() {
super("a:noFill"); super("a:noFill");
} }
} }

View File

@ -3,7 +3,7 @@ import { XmlComponent } from "@file/xml-components";
import { NoFill } from "./no-fill"; import { NoFill } from "./no-fill";
export class Outline extends XmlComponent { export class Outline extends XmlComponent {
constructor() { public constructor() {
super("a:ln"); super("a:ln");
this.root.push(new NoFill()); this.root.push(new NoFill());

View File

@ -2,7 +2,7 @@
import { XmlComponent } from "@file/xml-components"; import { XmlComponent } from "@file/xml-components";
export class AdjustmentValues extends XmlComponent { export class AdjustmentValues extends XmlComponent {
constructor() { public constructor() {
super("a:avLst"); super("a:avLst");
} }
} }

View File

@ -4,7 +4,7 @@ import { AdjustmentValues } from "./adjustment-values/adjustment-values";
import { PresetGeometryAttributes } from "./preset-geometry-attributes"; import { PresetGeometryAttributes } from "./preset-geometry-attributes";
export class PresetGeometry extends XmlComponent { export class PresetGeometry extends XmlComponent {
constructor() { public constructor() {
super("a:prstGeom"); super("a:prstGeom");
this.root.push( this.root.push(

View File

@ -10,7 +10,7 @@ import { ShapePropertiesAttributes } from "./shape-properties-attributes";
export class ShapeProperties extends XmlComponent { export class ShapeProperties extends XmlComponent {
private readonly form: Form; private readonly form: Form;
constructor(transform: IMediaDataTransformation) { public constructor(transform: IMediaDataTransformation) {
super("pic:spPr"); super("pic:spPr");
this.root.push( this.root.push(

View File

@ -14,7 +14,7 @@ class GraphicAttributes extends XmlAttributeComponent<{
export class Graphic extends XmlComponent { export class Graphic extends XmlComponent {
private readonly data: GraphicData; private readonly data: GraphicData;
constructor(mediaData: IMediaData, transform: IMediaDataTransformation) { public constructor(mediaData: IMediaData, transform: IMediaDataTransformation) {
super("a:graphic"); super("a:graphic");
this.root.push( this.root.push(
new GraphicAttributes({ new GraphicAttributes({

View File

@ -26,7 +26,7 @@ export class Inline extends XmlComponent {
private readonly extent: Extent; private readonly extent: Extent;
private readonly graphic: Graphic; private readonly graphic: Graphic;
constructor(mediaData: IMediaData, transform: IMediaDataTransformation) { public constructor(mediaData: IMediaData, transform: IMediaDataTransformation) {
super("wp:inline"); super("wp:inline");
this.root.push( this.root.push(

View File

@ -2,7 +2,7 @@
import { XmlComponent } from "@file/xml-components"; import { XmlComponent } from "@file/xml-components";
export class WrapNone extends XmlComponent { export class WrapNone extends XmlComponent {
constructor() { public constructor() {
super("wp:wrapNone"); super("wp:wrapNone");
} }
} }

View File

@ -1,8 +1,9 @@
// http://officeopenxml.com/drwPicFloating-textWrap.php // http://officeopenxml.com/drwPicFloating-textWrap.php
import { XmlAttributeComponent, XmlComponent } from "@file/xml-components"; import { XmlAttributeComponent, XmlComponent } from "@file/xml-components";
import { ITextWrapping, TextWrappingSide } from ".";
import { IDistance } from "../drawing"; import { IDistance } from "../drawing";
import { IMargins } from "../floating"; import { IMargins } from "../floating";
import { ITextWrapping, TextWrappingSide } from "./text-wrapping";
interface IWrapSquareAttributes extends IDistance { interface IWrapSquareAttributes extends IDistance {
readonly wrapText?: TextWrappingSide; readonly wrapText?: TextWrappingSide;
@ -19,7 +20,7 @@ class WrapSquareAttributes extends XmlAttributeComponent<IWrapSquareAttributes>
} }
export class WrapSquare extends XmlComponent { export class WrapSquare extends XmlComponent {
constructor( public constructor(
textWrapping: ITextWrapping, textWrapping: ITextWrapping,
margins: IMargins = { margins: IMargins = {
top: 0, top: 0,

View File

@ -14,7 +14,7 @@ class WrapTightAttributes extends XmlAttributeComponent<{
} }
export class WrapTight extends XmlComponent { export class WrapTight extends XmlComponent {
constructor( public constructor(
margins: IMargins = { margins: IMargins = {
top: 0, top: 0,
bottom: 0, bottom: 0,

View File

@ -14,7 +14,7 @@ class WrapTopAndBottomAttributes extends XmlAttributeComponent<{
} }
export class WrapTopAndBottom extends XmlComponent { export class WrapTopAndBottom extends XmlComponent {
constructor( public constructor(
margins: IMargins = { margins: IMargins = {
top: 0, top: 0,
bottom: 0, bottom: 0,

View File

@ -6,6 +6,7 @@ import { sectionMarginDefaults, sectionPageSizeDefaults } from "./document";
import { File } from "./file"; import { File } from "./file";
import { Footer, Header } from "./header"; import { Footer, Header } from "./header";
import { Paragraph } from "./paragraph"; import { Paragraph } from "./paragraph";
import { Media } from "./media";
const PAGE_SIZE_DEFAULTS = { const PAGE_SIZE_DEFAULTS = {
"w:h": sectionPageSizeDefaults.HEIGHT, "w:h": sectionPageSizeDefaults.HEIGHT,
@ -397,7 +398,6 @@ describe("File", () => {
sections: [], sections: [],
}); });
// tslint:disable-next-line: no-unused-expression
expect(doc.Comments).to.not.be.undefined; expect(doc.Comments).to.not.be.undefined;
}); });
}); });
@ -409,8 +409,61 @@ describe("File", () => {
sections: [], sections: [],
}); });
// tslint:disable-next-line: no-unused-expression
expect(doc.Numbering).to.not.be.undefined; expect(doc.Numbering).to.not.be.undefined;
}); });
}); });
describe("#getters", () => {
it("should have defined getters", () => {
const doc = new File({
sections: [],
});
expect(doc.CoreProperties).to.not.be.undefined;
expect(doc.Media).to.not.be.undefined;
expect(doc.FileRelationships).to.not.be.undefined;
expect(doc.Headers).to.not.be.undefined;
expect(doc.Footers).to.not.be.undefined;
expect(doc.ContentTypes).to.not.be.undefined;
expect(doc.CustomProperties).to.not.be.undefined;
expect(doc.AppProperties).to.not.be.undefined;
expect(doc.FootNotes).to.not.be.undefined;
expect(doc.Settings).to.not.be.undefined;
expect(doc.Comments).to.not.be.undefined;
});
});
describe("#templates", () => {
// Test will be deprecated when import-dotx and templates are deprecated
it("should work with template", () => {
const doc = new File(
{
sections: [],
},
{
template: {
currentRelationshipId: 1,
headers: [],
footers: [],
styles: "",
titlePageIsDefined: true,
media: new Media(),
},
},
);
expect(doc).to.not.be.undefined;
});
});
describe("#externalStyles", () => {
it("should work with external styles", () => {
const doc = new File({
sections: [],
externalStyles: "",
});
expect(doc.Styles).to.not.be.undefined;
});
});
}); });

View File

@ -33,15 +33,17 @@ export interface ISectionOptions {
readonly even?: Footer; readonly even?: Footer;
}; };
readonly properties?: ISectionPropertiesOptions; readonly properties?: ISectionPropertiesOptions;
readonly children: (Paragraph | Table | TableOfContents)[]; readonly children: readonly (Paragraph | Table | TableOfContents)[];
} }
export class File { export class File {
// tslint:disable-next-line:readonly-keyword // eslint-disable-next-line functional/prefer-readonly-type
private currentRelationshipId: number = 1; private currentRelationshipId: number = 1;
private readonly documentWrapper: DocumentWrapper; private readonly documentWrapper: DocumentWrapper;
// eslint-disable-next-line functional/prefer-readonly-type
private readonly headers: IDocumentHeader[] = []; private readonly headers: IDocumentHeader[] = [];
// eslint-disable-next-line functional/prefer-readonly-type
private readonly footers: IDocumentFooter[] = []; private readonly footers: IDocumentFooter[] = [];
private readonly coreProperties: CoreProperties; private readonly coreProperties: CoreProperties;
private readonly numbering: Numbering; private readonly numbering: Numbering;
@ -55,7 +57,7 @@ export class File {
private readonly styles: Styles; private readonly styles: Styles;
private readonly comments: Comments; private readonly comments: Comments;
constructor(options: IPropertiesOptions, fileProperties: IFileProperties = {}) { public constructor(options: IPropertiesOptions, fileProperties: IFileProperties = {}) {
this.coreProperties = new CoreProperties({ this.coreProperties = new CoreProperties({
...options, ...options,
creator: options.creator ?? "Un-named", creator: options.creator ?? "Un-named",
@ -63,13 +65,7 @@ export class File {
lastModifiedBy: options.lastModifiedBy ?? "Un-named", lastModifiedBy: options.lastModifiedBy ?? "Un-named",
}); });
this.numbering = new Numbering( this.numbering = new Numbering(options.numbering ? options.numbering : { config: [] });
options.numbering
? options.numbering
: {
config: [],
},
);
this.comments = new Comments(options.comments ?? { children: [] }); this.comments = new Comments(options.comments ?? { children: [] });
this.fileRelationships = new Relationships(); this.fileRelationships = new Relationships();
@ -132,7 +128,7 @@ export class File {
} }
if (options.footnotes) { if (options.footnotes) {
// tslint:disable-next-line: forin // eslint-disable-next-line guard-for-in
for (const key in options.footnotes) { for (const key in options.footnotes) {
this.footnotesWrapper.View.createFootNote(parseFloat(key), options.footnotes[key].children); this.footnotesWrapper.View.createFootNote(parseFloat(key), options.footnotes[key].children);
} }
@ -160,6 +156,7 @@ export class File {
} }
private createHeader(header: Header): HeaderWrapper { private createHeader(header: Header): HeaderWrapper {
// eslint-disable-next-line functional/immutable-data
const wrapper = new HeaderWrapper(this.media, this.currentRelationshipId++); const wrapper = new HeaderWrapper(this.media, this.currentRelationshipId++);
for (const child of header.options.children) { for (const child of header.options.children) {
@ -171,6 +168,7 @@ export class File {
} }
private createFooter(footer: Footer): FooterWrapper { private createFooter(footer: Footer): FooterWrapper {
// eslint-disable-next-line functional/immutable-data
const wrapper = new FooterWrapper(this.media, this.currentRelationshipId++); const wrapper = new FooterWrapper(this.media, this.currentRelationshipId++);
for (const child of footer.options.children) { for (const child of footer.options.children) {
@ -182,6 +180,7 @@ export class File {
} }
private addHeaderToDocument(header: HeaderWrapper, type: HeaderFooterReferenceType = HeaderFooterReferenceType.DEFAULT): void { private addHeaderToDocument(header: HeaderWrapper, type: HeaderFooterReferenceType = HeaderFooterReferenceType.DEFAULT): void {
// eslint-disable-next-line functional/immutable-data
this.headers.push({ header, type }); this.headers.push({ header, type });
this.documentWrapper.Relationships.createRelationship( this.documentWrapper.Relationships.createRelationship(
header.View.ReferenceId, header.View.ReferenceId,
@ -192,6 +191,7 @@ export class File {
} }
private addFooterToDocument(footer: FooterWrapper, type: HeaderFooterReferenceType = HeaderFooterReferenceType.DEFAULT): void { private addFooterToDocument(footer: FooterWrapper, type: HeaderFooterReferenceType = HeaderFooterReferenceType.DEFAULT): void {
// eslint-disable-next-line functional/immutable-data
this.footers.push({ footer, type }); this.footers.push({ footer, type });
this.documentWrapper.Relationships.createRelationship( this.documentWrapper.Relationships.createRelationship(
footer.View.ReferenceId, footer.View.ReferenceId,
@ -224,26 +224,31 @@ export class File {
); );
this.documentWrapper.Relationships.createRelationship( this.documentWrapper.Relationships.createRelationship(
// eslint-disable-next-line functional/immutable-data
this.currentRelationshipId++, this.currentRelationshipId++,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
"styles.xml", "styles.xml",
); );
this.documentWrapper.Relationships.createRelationship( this.documentWrapper.Relationships.createRelationship(
// eslint-disable-next-line functional/immutable-data
this.currentRelationshipId++, this.currentRelationshipId++,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering",
"numbering.xml", "numbering.xml",
); );
this.documentWrapper.Relationships.createRelationship( this.documentWrapper.Relationships.createRelationship(
// eslint-disable-next-line functional/immutable-data
this.currentRelationshipId++, this.currentRelationshipId++,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes",
"footnotes.xml", "footnotes.xml",
); );
this.documentWrapper.Relationships.createRelationship( this.documentWrapper.Relationships.createRelationship(
// eslint-disable-next-line functional/immutable-data
this.currentRelationshipId++, this.currentRelationshipId++,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings",
"settings.xml", "settings.xml",
); );
this.documentWrapper.Relationships.createRelationship( this.documentWrapper.Relationships.createRelationship(
// eslint-disable-next-line functional/immutable-data
this.currentRelationshipId++, this.currentRelationshipId++,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments", "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
"comments.xml", "comments.xml",
@ -274,11 +279,11 @@ export class File {
return this.fileRelationships; return this.fileRelationships;
} }
public get Headers(): HeaderWrapper[] { public get Headers(): readonly HeaderWrapper[] {
return this.headers.map((item) => item.header); return this.headers.map((item) => item.header);
} }
public get Footers(): FooterWrapper[] { public get Footers(): readonly FooterWrapper[] {
return this.footers.map((item) => item.footer); return this.footers.map((item) => item.footer);
} }

View File

@ -41,7 +41,7 @@ describe("FooterWrapper", () => {
it("should call the underlying footer's addChildElement", () => { it("should call the underlying footer's addChildElement", () => {
const file = new FooterWrapper(new Media(), 1); const file = new FooterWrapper(new Media(), 1);
const spy = sinon.spy(file.View, "addChildElement"); const spy = sinon.spy(file.View, "addChildElement");
// tslint:disable-next-line:no-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
file.addChildElement({} as any); file.addChildElement({} as any);
expect(spy.called).to.equal(true); expect(spy.called).to.equal(true);

View File

@ -17,7 +17,7 @@ export class FooterWrapper implements IViewWrapper {
private readonly footer: Footer; private readonly footer: Footer;
private readonly relationships: Relationships; private readonly relationships: Relationships;
constructor(private readonly media: Media, referenceId: number, initContent?: XmlComponent) { public constructor(private readonly media: Media, referenceId: number, initContent?: XmlComponent) {
this.footer = new Footer(referenceId, initContent); this.footer = new Footer(referenceId, initContent);
this.relationships = new Relationships(); this.relationships = new Relationships();
} }

View File

@ -7,7 +7,7 @@ import { FooterAttributes } from "./footer-attributes";
export class Footer extends InitializableXmlComponent { export class Footer extends InitializableXmlComponent {
private readonly refId: number; private readonly refId: number;
constructor(referenceNumber: number, initContent?: XmlComponent) { public constructor(referenceNumber: number, initContent?: XmlComponent) {
super("w:ftr", initContent); super("w:ftr", initContent);
this.refId = referenceNumber; this.refId = referenceNumber;
if (!initContent) { if (!initContent) {

View File

@ -7,9 +7,7 @@ describe("FootnotesWrapper", () => {
it("should create", () => { it("should create", () => {
const file = new FootnotesWrapper(); const file = new FootnotesWrapper();
// tslint:disable-next-line: no-unused-expression
expect(file.View).to.be.ok; expect(file.View).to.be.ok;
// tslint:disable-next-line: no-unused-expression
expect(file.Relationships).to.be.ok; expect(file.Relationships).to.be.ok;
}); });
}); });

View File

@ -6,7 +6,7 @@ export class FootnotesWrapper implements IViewWrapper {
private readonly footnotess: FootNotes; private readonly footnotess: FootNotes;
private readonly relationships: Relationships; private readonly relationships: Relationships;
constructor() { public constructor() {
this.footnotess = new FootNotes(); this.footnotess = new FootNotes();
this.relationships = new Relationships(); this.relationships = new Relationships();
} }

View File

@ -12,11 +12,11 @@ export enum FootnoteType {
export interface IFootnoteOptions { export interface IFootnoteOptions {
readonly id: number; readonly id: number;
readonly type?: FootnoteType; readonly type?: FootnoteType;
readonly children: Paragraph[]; readonly children: readonly Paragraph[];
} }
export class Footnote extends XmlComponent { export class Footnote extends XmlComponent {
constructor(options: IFootnoteOptions) { public constructor(options: IFootnoteOptions) {
super("w:footnote"); super("w:footnote");
this.root.push( this.root.push(
new FootnoteAttributes({ new FootnoteAttributes({

View File

@ -2,7 +2,7 @@ import { Run } from "@file/paragraph";
import { ContinuationSeperator } from "./continuation-seperator"; import { ContinuationSeperator } from "./continuation-seperator";
export class ContinuationSeperatorRun extends Run { export class ContinuationSeperatorRun extends Run {
constructor() { public constructor() {
super({}); super({});
this.root.push(new ContinuationSeperator()); this.root.push(new ContinuationSeperator());

View File

@ -1,7 +1,7 @@
import { XmlComponent } from "@file/xml-components"; import { XmlComponent } from "@file/xml-components";
export class ContinuationSeperator extends XmlComponent { export class ContinuationSeperator extends XmlComponent {
constructor() { public constructor() {
super("w:continuationSeparator"); super("w:continuationSeparator");
} }
} }

View File

@ -3,7 +3,7 @@ import { Run } from "@file/paragraph";
import { FootnoteRef } from "./footnote-ref"; import { FootnoteRef } from "./footnote-ref";
export class FootnoteRefRun extends Run { export class FootnoteRefRun extends Run {
constructor() { public constructor() {
super({ super({
style: "FootnoteReference", style: "FootnoteReference",
}); });

View File

@ -1,7 +1,7 @@
import { XmlComponent } from "@file/xml-components"; import { XmlComponent } from "@file/xml-components";
export class FootnoteRef extends XmlComponent { export class FootnoteRef extends XmlComponent {
constructor() { public constructor() {
super("w:footnoteRef"); super("w:footnoteRef");
} }
} }

View File

@ -10,7 +10,7 @@ export class FootNoteReferenceRunAttributes extends XmlAttributeComponent<{
} }
export class FootnoteReference extends XmlComponent { export class FootnoteReference extends XmlComponent {
constructor(id: number) { public constructor(id: number) {
super("w:footnoteReference"); super("w:footnoteReference");
this.root.push( this.root.push(
@ -22,7 +22,7 @@ export class FootnoteReference extends XmlComponent {
} }
export class FootnoteReferenceRun extends Run { export class FootnoteReferenceRun extends Run {
constructor(id: number) { public constructor(id: number) {
super({ style: "FootnoteReference" }); super({ style: "FootnoteReference" });
this.root.push(new FootnoteReference(id)); this.root.push(new FootnoteReference(id));

View File

@ -2,7 +2,7 @@ import { Run } from "@file/paragraph";
import { Seperator } from "./seperator"; import { Seperator } from "./seperator";
export class SeperatorRun extends Run { export class SeperatorRun extends Run {
constructor() { public constructor() {
super({}); super({});
this.root.push(new Seperator()); this.root.push(new Seperator());

View File

@ -1,7 +1,7 @@
import { XmlComponent } from "@file/xml-components"; import { XmlComponent } from "@file/xml-components";
export class Seperator extends XmlComponent { export class Seperator extends XmlComponent {
constructor() { public constructor() {
super("w:separator"); super("w:separator");
} }
} }

View File

@ -7,7 +7,7 @@ import { SeperatorRun } from "./footnote/run/seperator-run";
import { FootnotesAttributes } from "./footnotes-attributes"; import { FootnotesAttributes } from "./footnotes-attributes";
export class FootNotes extends XmlComponent { export class FootNotes extends XmlComponent {
constructor() { public constructor() {
super("w:footnotes"); super("w:footnotes");
this.root.push( this.root.push(
@ -67,7 +67,7 @@ export class FootNotes extends XmlComponent {
this.root.push(spacing); this.root.push(spacing);
} }
public createFootNote(id: number, paragraph: Paragraph[]): void { public createFootNote(id: number, paragraph: readonly Paragraph[]): void {
const footnote = new Footnote({ const footnote = new Footnote({
id: id, id: id,
children: paragraph, children: paragraph,

View File

@ -41,7 +41,7 @@ describe("HeaderWrapper", () => {
it("should call the underlying header's addChildElement", () => { it("should call the underlying header's addChildElement", () => {
const file = new HeaderWrapper(new Media(), 1); const file = new HeaderWrapper(new Media(), 1);
const spy = sinon.spy(file.View, "addChildElement"); const spy = sinon.spy(file.View, "addChildElement");
// tslint:disable-next-line:no-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
file.addChildElement({} as any); file.addChildElement({} as any);
expect(spy.called).to.equal(true); expect(spy.called).to.equal(true);

View File

@ -17,7 +17,7 @@ export class HeaderWrapper implements IViewWrapper {
private readonly header: Header; private readonly header: Header;
private readonly relationships: Relationships; private readonly relationships: Relationships;
constructor(private readonly media: Media, referenceId: number, initContent?: XmlComponent) { public constructor(private readonly media: Media, referenceId: number, initContent?: XmlComponent) {
this.header = new Header(referenceId, initContent); this.header = new Header(referenceId, initContent);
this.relationships = new Relationships(); this.relationships = new Relationships();
} }

View File

@ -2,13 +2,21 @@ import { Paragraph } from "./paragraph";
import { Table } from "./table"; import { Table } from "./table";
export interface IHeaderOptions { export interface IHeaderOptions {
readonly children: (Paragraph | Table)[]; readonly children: readonly (Paragraph | Table)[];
} }
export class Header { export class Header {
constructor(public readonly options: IHeaderOptions = { children: [] }) {} public readonly options: IHeaderOptions;
public constructor(options: IHeaderOptions = { children: [] }) {
this.options = options;
}
} }
export class Footer { export class Footer {
constructor(public readonly options: IHeaderOptions = { children: [] }) {} public readonly options: IHeaderOptions;
public constructor(options: IHeaderOptions = { children: [] }) {
this.options = options;
}
} }

View File

@ -7,7 +7,7 @@ import { HeaderAttributes } from "./header-attributes";
export class Header extends InitializableXmlComponent { export class Header extends InitializableXmlComponent {
private readonly refId: number; private readonly refId: number;
constructor(referenceNumber: number, initContent?: XmlComponent) { public constructor(referenceNumber: number, initContent?: XmlComponent) {
super("w:hdr", initContent); super("w:hdr", initContent);
this.refId = referenceNumber; this.refId = referenceNumber;

View File

@ -37,6 +37,7 @@ describe("Media", () => {
}); });
it("should return UInt8Array if atob is present", () => { it("should return UInt8Array if atob is present", () => {
// eslint-disable-next-line functional/immutable-data
global.atob = () => "atob result"; global.atob = () => "atob result";
const image = new Media().addMedia("", { const image = new Media().addMedia("", {
@ -45,11 +46,12 @@ describe("Media", () => {
}); });
expect(image.stream).to.be.an.instanceof(Uint8Array); expect(image.stream).to.be.an.instanceof(Uint8Array);
// tslint:disable-next-line: no-any // eslint-disable-next-line @typescript-eslint/no-explicit-any, functional/immutable-data
(global as any).atob = undefined; (global as any).atob = undefined;
}); });
it("should use data as is if its not a string", () => { it("should use data as is if its not a string", () => {
// eslint-disable-next-line functional/immutable-data
global.atob = () => "atob result"; global.atob = () => "atob result";
const image = new Media().addMedia(Buffer.from(""), { const image = new Media().addMedia(Buffer.from(""), {
@ -58,7 +60,7 @@ describe("Media", () => {
}); });
expect(image.stream).to.be.an.instanceof(Uint8Array); expect(image.stream).to.be.an.instanceof(Uint8Array);
// tslint:disable-next-line: no-any // eslint-disable-next-line @typescript-eslint/no-explicit-any, functional/immutable-data
(global as any).atob = undefined; (global as any).atob = undefined;
}); });
}); });

View File

@ -13,9 +13,10 @@ export interface IMediaTransformation {
} }
export class Media { export class Media {
// eslint-disable-next-line functional/prefer-readonly-type
private readonly map: Map<string, IMediaData>; private readonly map: Map<string, IMediaData>;
constructor() { public constructor() {
this.map = new Map<string, IMediaData>(); this.map = new Map<string, IMediaData>();
} }
@ -68,6 +69,7 @@ export class Media {
.map((c) => c.charCodeAt(0)), .map((c) => c.charCodeAt(0)),
); );
} else { } else {
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
const b = require("buf" + "fer"); const b = require("buf" + "fer");
return new b.Buffer(dataURI, "base64"); return new b.Buffer(dataURI, "base64");
} }

View File

@ -32,7 +32,7 @@ class AbstractNumberingAttributes extends XmlAttributeComponent<{
export class AbstractNumbering extends XmlComponent { export class AbstractNumbering extends XmlComponent {
public readonly id: number; public readonly id: number;
constructor(id: number, levelOptions: ILevelsOptions[]) { public constructor(id: number, levelOptions: readonly ILevelsOptions[]) {
super("w:abstractNum"); super("w:abstractNum");
this.root.push( this.root.push(
new AbstractNumberingAttributes({ new AbstractNumberingAttributes({

Some files were not shown because too many files have changed in this diff Show More