From 1d0321552721030ae5ca15ec91204ab82f1a7ef6 Mon Sep 17 00:00:00 2001 From: dependentmadani Date: Sun, 21 Jul 2024 02:47:07 +0100 Subject: [PATCH] update(eslint): eslint now is working fine --- eslint.config.mjs | 18 +++++++++ src/index.ts | 12 +++--- src/ui.ts | 87 ++++++++++++++++++++++-------------------- src/uploader.ts | 49 +++++++++++++----------- src/utils/dom.ts | 2 +- src/utils/isPromise.ts | 2 +- 6 files changed, 98 insertions(+), 72 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 7a183521..193d8c62 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -19,7 +19,10 @@ export default [ 'jsdoc/no-types': ['off'], 'jsdoc/require-returns-description': ['off'], 'jsdoc/check-tag-names': ['off'], + 'jsdoc/require-jsdoc': ['off'], + '@typescript-eslint/no-unsafe-assignment': ['off'], '@typescript-eslint/no-unsafe-member-access': ['off'], + '@typescript-eslint/no-explicit-any': ['off'], "@typescript-eslint/naming-convention": [ "error", { @@ -27,6 +30,21 @@ export default [ "format": ["camelCase"], "leadingUnderscore": "allow" }, + ], + "@typescript-eslint/ban-types": ["error", + { + "types": { + "String": true, + "Boolean": true, + "Number": true, + "Symbol": true, + "{}": false, + "Object": true, + "object": false, + "Function": false, + }, + "extendDefaults": true + } ] } }, diff --git a/src/index.ts b/src/index.ts index 6a3d6ec1..11b30e15 100644 --- a/src/index.ts +++ b/src/index.ts @@ -307,7 +307,7 @@ export default class ImageTool implements BlockTool { public async onPaste(event: CustomEvent): Promise { switch (event.type) { case 'tag': { - const image: { src: string } = event.detail.data; + const image = event.detail.data as { src: string }; /** Images from PDF */ if (/^blob:/.test(image.src)) { @@ -323,13 +323,13 @@ export default class ImageTool implements BlockTool { break; } case 'pattern': { - const url: string = event.detail.data; + const url = event.detail.data as string; this.uploadUrl(url); break; } case 'file': { - const file: Blob = event.detail.file; + const file = event.detail.file as Blob; this.uploadFile(file); break; @@ -389,7 +389,7 @@ export default class ImageTool implements BlockTool { * @returns {void} */ private onUpload(response: UploadResponseFormat): void { - if (response.success && response.file) { + if (response.success && response.file.url) { this.image = response.file; } else { this.uploadingFailed('incorrect response: ' + JSON.stringify(response)); @@ -399,7 +399,7 @@ export default class ImageTool implements BlockTool { /** * Handle uploader errors * @private - * @param {string} errorText - uploading error text + * @param {string} errorText - uploading error info * @returns {void} */ private uploadingFailed(errorText: string): void { @@ -420,7 +420,7 @@ export default class ImageTool implements BlockTool { */ private tuneToggled(tuneName: keyof ImageToolData): void { // inverse tune state - this.setTune(tuneName, !this._data[tuneName]); + this.setTune(tuneName, this._data[tuneName] != undefined ? false : true); } /** diff --git a/src/ui.ts b/src/ui.ts index c6e0a610..5eb9c18b 100644 --- a/src/ui.ts +++ b/src/ui.ts @@ -87,9 +87,14 @@ interface ConstructorParams { * - apply tune view */ export default class Ui { -/** - * API instance for Editor.js. - */ + /** + * Nodes representing various elements in the UI. + */ + public nodes: Nodes; + + /** + * API instance for Editor.js. + */ private api: API; /** @@ -108,15 +113,11 @@ export default class Ui { private readOnly: boolean; /** - * Nodes representing various elements in the UI. - */ - public nodes: Nodes; - /** - * @param ui - image tool Ui module - * @param ui.api - Editor.js API - * @param ui.config - user config - * @param ui.onSelectFile - callback for clicks on Select file button - * @param ui.readOnly - read-only mode flag + * @param {object} ui - image tool Ui module + * @param {object} ui.api - Editor.js API + * @param {ImageConfig} ui.config - user config + * @param {Function} ui.onSelectFile - callback for clicks on Select file button + * @param {boolean} ui.readOnly - read-only mode flag */ constructor({ api, config, onSelectFile, readOnly }: ConstructorParams) { this.api = api; @@ -153,9 +154,9 @@ export default class Ui { /** * CSS classes - * @returns + * @returns {object} */ - get CSS(): Record { + public get CSS(): Record { return { baseClass: this.api.styles.block, loading: this.api.styles.loader, @@ -175,11 +176,11 @@ export default class Ui { /** * Renders tool UI - * @param toolData - saved tool data - * @returns + * @param {ImageToolData} toolData - saved tool data + * @returns {Element} */ - render(toolData: ImageToolData): HTMLElement { - if (!toolData.file || Object.keys(toolData.file).length === 0) { + public render(toolData: ImageToolData): HTMLElement { + if (toolData.file == undefined || Object.keys(toolData.file).length === 0) { this.toggleStatus(UiState.Empty); } else { this.toggleStatus(UiState.Uploading); @@ -190,12 +191,12 @@ export default class Ui { /** * Creates upload-file button - * @returns + * @returns {Element} */ - createFileButton(): HTMLElement { + public createFileButton(): HTMLElement { const button = make('div', [this.CSS.button]); - button.innerHTML = this.config.buttonContent || `${IconPicture} ${this.api.i18n.t('Select an Image')}`; + button.innerHTML = this.config.buttonContent != undefined ? this.config.buttonContent : `${IconPicture} ${this.api.i18n.t('Select an Image')}`; button.addEventListener('click', () => { this.onSelectFile(); @@ -206,10 +207,10 @@ export default class Ui { /** * Shows uploading preloader - * @param src - preview source - * @returns + * @param {string} src - preview source + * @returns {void} */ - showPreloader(src: string): void { + public showPreloader(src: string): void { this.nodes.imagePreloader.style.backgroundImage = `url(${src})`; this.toggleStatus(UiState.Uploading); @@ -217,19 +218,19 @@ export default class Ui { /** * Hide uploading preloader - * @returns + * @returns {void} */ - hidePreloader(): void { + public hidePreloader(): void { this.nodes.imagePreloader.style.backgroundImage = ''; this.toggleStatus(UiState.Empty); } /** * Shows an image - * @param url - image source - * @returns + * @param {string} url - image source + * @returns {void} */ - fillImage(url: string): void { + public fillImage(url: string): void { /** * Check for a source extension to compose element correctly: video tag for mp4, img — for others */ @@ -243,6 +244,7 @@ export default class Ui { * We use eventName variable because IMG and VIDEO tags have different event to be called on source load * - IMG: load * - VIDEO: loadeddata + * @type {string} */ let eventName = 'load'; @@ -252,6 +254,7 @@ export default class Ui { if (tag === 'VIDEO') { /** * Add attributes for playing muted mp4 as a gif + * @type {boolean} */ attributes.autoplay = true; attributes.loop = true; @@ -260,12 +263,14 @@ export default class Ui { /** * Change event to be listened + * @type {string} */ eventName = 'loadeddata'; } /** * Compose tag with defined attributes + * @type {Element} */ this.nodes.imageEl = make(tag, this.CSS.imageEl, attributes); @@ -278,7 +283,7 @@ export default class Ui { /** * Preloader does not exists on first rendering with presaved data */ - if (this.nodes.imagePreloader) { + if (this.nodes.imagePreloader != undefined) { this.nodes.imagePreloader.style.backgroundImage = ''; } }); @@ -288,21 +293,21 @@ export default class Ui { /** * Shows caption input - * @param text - caption text - * @returns + * @param {string} text - caption content text + * @returns {void} */ - fillCaption(text: string): void { - if (this.nodes.caption) { + public fillCaption(text: string): void { + if (this.nodes.caption != undefined) { this.nodes.caption.innerHTML = text; } } /** * Changes UI status - * @param status - see {@link Ui.status} constants - * @returns + * @param {string} status - see {@link Ui.status} constants + * @returns {void} */ - toggleStatus(status: UiState): void { + public toggleStatus(status: UiState): void { for (const statusType in UiState) { if (Object.prototype.hasOwnProperty.call(UiState, statusType)) { this.nodes.wrapper.classList.toggle(`${this.CSS.wrapper}--${UiState[statusType as keyof typeof UiState]}`, status === UiState[statusType as keyof typeof UiState]); @@ -312,11 +317,11 @@ export default class Ui { /** * Apply visual representation of activated tune - * @param tuneName - one of available tunes {@link Tunes.tunes} - * @param status - true for enable, false for disable - * @returns + * @param {string} tuneName - one of available tunes {@link Tunes.tunes} + * @param {boolean} status - true for enable, false for disable + * @returns {void} */ - applyTune(tuneName: string, status: boolean): void { + public applyTune(tuneName: string, status: boolean): void { this.nodes.wrapper.classList.toggle(`${this.CSS.wrapper}--${tuneName}`, status); } } diff --git a/src/uploader.ts b/src/uploader.ts index 73b6c417..9d904c0d 100644 --- a/src/uploader.ts +++ b/src/uploader.ts @@ -11,12 +11,14 @@ interface UploaderParams { * Configuration for the uploader */ config: ImageConfig; + /** - * - * @param response: Callback function for successful upload - * @returns void + * Handles the upload response. + * @param {UploadResponseFormat} response - Response format expected from the backend on file uploading. + * @returns {void} */ onUpload: (response: UploadResponseFormat) => void; + /** * * @param error : error type @@ -36,10 +38,10 @@ export default class Uploader { private onUpload: (response: UploadResponseFormat) => void; private onError: (error: any) => void; /** - * @param params - uploader module params - * @param params.config - image tool config - * @param params.onUpload - one callback for all uploading (file, url, d-n-d, pasting) - * @param params.onError - callback for uploading errors + * @param {object} params - uploader module params + * @param {ImageConfig} params.config - image tool config + * @param {Function} params.onUpload - one callback for all uploading (file, url, d-n-d, pasting) + * @param {Function} params.onError - callback for uploading errors */ constructor({ config, onUpload, onError }: UploaderParams) { this.config = config; @@ -50,10 +52,10 @@ export default class Uploader { /** * Handle clicks on the upload file button * Fires ajax.transport() - * @param onPreview - callback fired when preview is ready + * @param {Function} onPreview - callback fired when preview is ready */ - uploadSelectedFile({ onPreview }: UploadOptions) { - const preparePreview = function (file: File) { + public uploadSelectedFile({ onPreview }: UploadOptions): void { + const preparePreview = function (file: File): void { const reader = new FileReader(); reader.readAsDataURL(file); @@ -72,7 +74,7 @@ export default class Uploader { if (this.config.uploader && typeof this.config.uploader.uploadByFile === 'function') { const uploadByFile = this.config.uploader.uploadByFile; - upload = ajax.selectFiles({ accept: this.config.types || 'image/*' }).then((files: File[]) => { + upload = ajax.selectFiles({ accept: this.config.types != undefined ? this.config.types : 'image/*' }).then((files: File[]) => { preparePreview(files[0]); const customUpload = uploadByFile(files[0]); @@ -89,13 +91,13 @@ export default class Uploader { upload = ajax.transport({ url: this.config.endpoints.byFile, data: this.config.additionalRequestData, - accept: this.config.types || 'image/*', + accept: this.config.types != undefined ? this.config.types : 'image/*', headers: this.config.additionalRequestHeaders as Record, beforeSend: (files: File[]) => { preparePreview(files[0]); }, - fieldName: this.config.field || 'image', - }).then((response: any) => response.body); + fieldName: this.config.field != undefined ? this.config.field : 'image', + }).then((response: any) => response.body as UploadResponseFormat); } upload.then((response) => { @@ -108,9 +110,9 @@ export default class Uploader { /** * Handle clicks on the upload file button * Fires ajax.post() - * @param url - image source url + * @param {string} url - image source url */ - uploadByUrl(url: string) { + public uploadByUrl(url: string): void { let upload; /** @@ -133,7 +135,7 @@ export default class Uploader { }, this.config.additionalRequestData), type: ajax.contentType.JSON, headers: this.config.additionalRequestHeaders as Record, - }).then((response: any) => response.body); + }).then((response: any) => response.body as UploadResponseFormat); } upload.then((response: UploadResponseFormat) => { @@ -146,12 +148,13 @@ export default class Uploader { /** * Handle clicks on the upload file button * Fires ajax.post() - * @param file - file pasted by drag-n-drop - * @param onPreview - file pasted by drag-n-drop + * @param {File} file - file pasted by drag-n-drop + * @param {Function} onPreview - file pasted by drag-n-drop */ - uploadByFile(file: Blob, { onPreview }: UploadOptions) { + public uploadByFile(file: Blob, { onPreview }: UploadOptions): void { /** * Load file for preview + * @type {FileReader} */ const reader = new FileReader(); @@ -177,10 +180,10 @@ export default class Uploader { */ const formData = new FormData(); - formData.append(this.config.field || 'image', file); + formData.append(this.config.field != undefined ? this.config.field : 'image', file); if (this.config.additionalRequestData && Object.keys(this.config.additionalRequestData).length) { - Object.entries(this.config.additionalRequestData).forEach(([name, value]: [string, any]) => { + Object.entries(this.config.additionalRequestData).forEach(([name, value]: [string, string | Blob]) => { formData.append(name, value); }); } @@ -190,7 +193,7 @@ export default class Uploader { data: formData, type: ajax.contentType.JSON, headers: this.config.additionalRequestHeaders as Record, - }).then((response: any) => response.body); + }).then((response: any) => response.body as UploadResponseFormat); } upload.then((response) => { diff --git a/src/utils/dom.ts b/src/utils/dom.ts index a45aa0cd..7cb6deb8 100644 --- a/src/utils/dom.ts +++ b/src/utils/dom.ts @@ -10,7 +10,7 @@ export function make(tagName: string, classNames: string[] | string | null = nul if (Array.isArray(classNames)) { el.classList.add(...classNames); - } else if (classNames) { + } else if (classNames != null) { el.classList.add(classNames); } diff --git a/src/utils/isPromise.ts b/src/utils/isPromise.ts index e7421256..fc04ce3b 100644 --- a/src/utils/isPromise.ts +++ b/src/utils/isPromise.ts @@ -4,5 +4,5 @@ * @returns */ export default function isPromise(object: any): object is Promise { - return object && typeof object.then === 'function'; + return object != undefined && typeof object.then === 'function'; }