Fix linting and add new lint rules

This commit is contained in:
Dolan Miu
2022-09-19 20:48:50 +01:00
parent e90d97b813
commit 5950055cca
13 changed files with 78 additions and 46 deletions

View File

@ -12,6 +12,7 @@ https://github.com/typescript-eslint/tslint-to-eslint-config/blob/master/docs/FA
Happy linting! 💖 Happy linting! 💖
*/ */
module.exports = { module.exports = {
extends: "eslint:recommended",
env: { env: {
browser: true, browser: true,
es6: true, es6: true,
@ -33,6 +34,31 @@ module.exports = {
], ],
root: true, root: true,
rules: { 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/adjacent-overload-signatures": "error",
"@typescript-eslint/array-type": [ "@typescript-eslint/array-type": [
"error", "error",
@ -95,22 +121,6 @@ module.exports = {
allowTypedFunctionExpressions: false, allowTypedFunctionExpressions: false,
}, },
], ],
"@typescript-eslint/indent": [
"error",
4,
{
ObjectExpression: "first",
FunctionDeclaration: {
parameters: "first",
},
FunctionExpression: {
parameters: "first",
},
SwitchCase: 1,
flatTernaryExpressions: false,
ignoredNodes: [],
},
],
"@typescript-eslint/naming-convention": [ "@typescript-eslint/naming-convention": [
"error", "error",
{ {
@ -176,7 +186,7 @@ module.exports = {
"import/order": "error", "import/order": "error",
indent: "off", indent: "off",
"jsdoc/check-alignment": "error", "jsdoc/check-alignment": "error",
"jsdoc/check-indentation": "error", "jsdoc/check-indentation": "off",
"jsdoc/newline-after-description": "error", "jsdoc/newline-after-description": "error",
"max-classes-per-file": "off", "max-classes-per-file": "off",
"max-len": "off", "max-len": "off",
@ -245,6 +255,7 @@ module.exports = {
"functional/no-method-signature": "error", "functional/no-method-signature": "error",
"functional/no-mixed-type": "error", "functional/no-mixed-type": "error",
"functional/prefer-readonly-type": "error", "functional/prefer-readonly-type": "error",
"no-unused-vars": ["error", { argsIgnorePattern: "^[_]+$" }],
}, },
overrides: [ overrides: [
{ {
@ -252,6 +263,7 @@ module.exports = {
rules: { rules: {
"@typescript-eslint/no-unused-expressions": "off", "@typescript-eslint/no-unused-expressions": "off",
"@typescript-eslint/dot-notation": "off", "@typescript-eslint/dot-notation": "off",
"prefer-destructuring": "off",
}, },
}, },
], ],

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

@ -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

@ -54,7 +54,7 @@ describe("Packer", () => {
assert.isTrue(buffer.byteLength > 0); assert.isTrue(buffer.byteLength > 0);
}); });
it("should handle exception if it throws any", async () => { it("should handle exception if it throws any", () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-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");
@ -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,7 +148,7 @@ describe("Packer", () => {
}); });
}); });
it("should handle exception if it throws any", async () => { it("should handle exception if it throws any", () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-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
@ -160,9 +160,11 @@ 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(() => {

View File

@ -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

@ -33,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

@ -37,13 +37,13 @@ export interface ISectionOptions {
} }
export class File { export class File {
// eslint-disable-next-line functional/immutable-data // 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/immutable-data // eslint-disable-next-line functional/prefer-readonly-type
private readonly headers: IDocumentHeader[] = []; private readonly headers: IDocumentHeader[] = [];
// eslint-disable-next-line functional/immutable-data // 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;
@ -128,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);
} }
@ -156,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) {
@ -167,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) {
@ -178,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,
@ -188,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,
@ -220,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",

View File

@ -6,13 +6,17 @@ export interface IHeaderOptions {
} }
export class Header { export class Header {
public constructor(public readonly options: IHeaderOptions = { children: [] }) { public readonly options: IHeaderOptions;
// noop
public constructor(options: IHeaderOptions = { children: [] }) {
this.options = options;
} }
} }
export class Footer { export class Footer {
public constructor(public readonly options: IHeaderOptions = { children: [] }) { public readonly options: IHeaderOptions;
// noop
public constructor(options: IHeaderOptions = { children: [] }) {
this.options = options;
} }
} }

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

@ -34,13 +34,14 @@ describe("Numbering", () => {
.filter((el) => el["w:lvl"]) .filter((el) => el["w:lvl"])
.forEach((el, ix) => { .forEach((el, ix) => {
expect(Object.keys(el)).to.have.lengthOf(1); expect(Object.keys(el)).to.have.lengthOf(1);
expect(Object.keys(el["w:lvl"]).sort()).to.deep.equal(["_attr", "w:start", "w:lvlJc", "w:numFmt", "w:pPr", "w:rPr"]); expect(Object.keys(el["w:lvl"])).to.deep.equal(["_attr", "w:start", "w:lvlJc", "w:numFmt", "w:pPr", "w:rPr"]);
expect(el["w:lvl"]).to.have.deep.members([ expect(el["w:lvl"]).to.have.deep.members([
{ _attr: { "w:ilvl": ix, "w15:tentative": 1 } }, { _attr: { "w:ilvl": ix, "w15:tentative": 1 } },
{ "w:start": [{ _attr: { "w:val": 1 } }] }, { "w:start": [{ _attr: { "w:val": 1 } }] },
{ "w:lvlJc": [{ _attr: { "w:val": "left" } }] }, { "w:lvlJc": [{ _attr: { "w:val": "left" } }] },
{ "w:numFmt": [{ _attr: { "w:val": "bullet" } }] }, { "w:numFmt": [{ _attr: { "w:val": "bullet" } }] },
]); ]);
// TODO
// Once chai 4.0.0 lands and #644 is resolved, we can add the following to the test: // Once chai 4.0.0 lands and #644 is resolved, we can add the following to the test:
// {"w:lvlText": {"_attr": {"w:val": "•"}}}, // {"w:lvlText": {"_attr": {"w:val": "•"}}},
// {"w:rPr": [{"w:rFonts": {"_attr": {"w:ascii": "Symbol", "w:cs": "Symbol", "w:eastAsia": "Symbol", "w:hAnsi": "Symbol", "w:hint": "default"}}}]}, // {"w:rPr": [{"w:rFonts": {"_attr": {"w:ascii": "Symbol", "w:cs": "Symbol", "w:eastAsia": "Symbol", "w:hAnsi": "Symbol", "w:hint": "default"}}}]},

View File

@ -771,7 +771,7 @@ describe("ImageRun", () => {
], ],
}); });
// 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;
}); });
@ -1028,7 +1028,7 @@ describe("ImageRun", () => {
], ],
}); });
// 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

@ -1,4 +1,3 @@
// eslint-disable @typescript-eslint/no-explicit-any
import { Element as XmlElement, xml2js } from "xml-js"; import { Element as XmlElement, xml2js } from "xml-js";
import { IXmlableObject, XmlAttributeComponent, XmlComponent } from "@file/xml-components"; import { IXmlableObject, XmlAttributeComponent, XmlComponent } from "@file/xml-components";
@ -15,7 +14,9 @@ export const convertToXmlComponent = (element: XmlElement): ImportedXmlComponent
switch (element.type) { switch (element.type) {
case undefined: case undefined:
case "element": case "element":
// eslint-disable-next-line no-case-declarations
const xmlComponent = new ImportedXmlComponent(element.name as string, element.attributes); const xmlComponent = new ImportedXmlComponent(element.name as string, element.attributes);
// eslint-disable-next-line no-case-declarations
const childElements = element.elements || []; const childElements = element.elements || [];
for (const childElm of childElements) { for (const childElm of childElements) {
const child = convertToXmlComponent(childElm); const child = convertToXmlComponent(childElm);
@ -31,6 +32,7 @@ export const convertToXmlComponent = (element: XmlElement): ImportedXmlComponent
} }
}; };
// eslint-disable-next-line @typescript-eslint/no-explicit-any
class ImportedXmlComponentAttributes extends XmlAttributeComponent<any> { class ImportedXmlComponentAttributes extends XmlAttributeComponent<any> {
// noop // noop
} }
@ -54,7 +56,7 @@ export class ImportedXmlComponent extends XmlComponent {
* @param importedContent xml content of the imported component * @param importedContent xml content of the imported component
*/ */
// tslint:disable-next-line:variable-name // eslint-disable-next-line @typescript-eslint/no-explicit-any
public constructor(rootKey: string, _attr?: any) { public constructor(rootKey: string, _attr?: any) {
super(rootKey); super(rootKey);
if (_attr) { if (_attr) {
@ -71,7 +73,7 @@ export class ImportedXmlComponent extends XmlComponent {
* Used for the attributes of root element that is being imported. * Used for the attributes of root element that is being imported.
*/ */
export class ImportedRootElementAttributes extends XmlComponent { export class ImportedRootElementAttributes extends XmlComponent {
// tslint:disable-next-line:variable-name // eslint-disable-next-line @typescript-eslint/no-explicit-any
public constructor(private readonly _attr: any) { public constructor(private readonly _attr: any) {
super(""); super("");
} }

View File

@ -32,7 +32,7 @@ export const unsignedDecimalNumber = (val: number): number => {
// http://www.datypic.com/sc/xsd/t-xsd_hexBinary.html // http://www.datypic.com/sc/xsd/t-xsd_hexBinary.html
const hexBinary = (val: string, length: number): string => { const hexBinary = (val: string, length: number): string => {
const expectedLength = length * 2; const expectedLength = length * 2;
if (val.length !== expectedLength || isNaN(Number("0x" + val))) { if (val.length !== expectedLength || isNaN(Number(`0x${val}`))) {
throw new Error(`Invalid hex value '${val}'. Expected ${expectedLength} digit hex value`); throw new Error(`Invalid hex value '${val}'. Expected ${expectedLength} digit hex value`);
} }
return val; return val;