Преглед на файлове

@uppy/utils: resolve remaining linter errors (#3091)

Antoine du Hamel преди 3 години
родител
ревизия
c94664613a

+ 68 - 66
packages/@uppy/utils/src/Translator.js

@@ -1,5 +1,67 @@
 const has = require('./hasProperty')
 
+function insertReplacement (source, rx, replacement) {
+  const newParts = []
+  source.forEach((chunk) => {
+    // When the source contains multiple placeholders for interpolation,
+    // we should ignore chunks that are not strings, because those
+    // can be JSX objects and will be otherwise incorrectly turned into strings.
+    // Without this condition we’d get this: [object Object] hello [object Object] my <button>
+    if (typeof chunk !== 'string') {
+      return newParts.push(chunk)
+    }
+
+    return rx[Symbol.split](chunk).forEach((raw, i, list) => {
+      if (raw !== '') {
+        newParts.push(raw)
+      }
+
+      // Interlace with the `replacement` value
+      if (i < list.length - 1) {
+        newParts.push(replacement)
+      }
+    })
+  })
+  return newParts
+}
+
+/**
+ * Takes a string with placeholder variables like `%{smart_count} file selected`
+ * and replaces it with values from options `{smart_count: 5}`
+ *
+ * @license https://github.com/airbnb/polyglot.js/blob/master/LICENSE
+ * taken from https://github.com/airbnb/polyglot.js/blob/master/lib/polyglot.js#L299
+ *
+ * @param {string} phrase that needs interpolation, with placeholders
+ * @param {object} options with values that will be used to replace placeholders
+ * @returns {any[]} interpolated
+ */
+function interpolate (phrase, options) {
+  const dollarRegex = /\$/g
+  const dollarBillsYall = '$$$$'
+  let interpolated = [phrase]
+
+  if (options == null) return interpolated
+
+  for (const arg of Object.keys(options)) {
+    if (arg !== '_') {
+      // Ensure replacement value is escaped to prevent special $-prefixed
+      // regex replace tokens. the "$$$$" is needed because each "$" needs to
+      // be escaped with "$" itself, and we need two in the resulting output.
+      let replacement = options[arg]
+      if (typeof replacement === 'string') {
+        replacement = dollarRegex[Symbol.replace](replacement, dollarBillsYall)
+      }
+      // We create a new `RegExp` each time instead of using a more-efficient
+      // string replace so that the same argument can be replaced multiple times
+      // in the same phrase.
+      interpolated = insertReplacement(interpolated, new RegExp(`%\\{${arg}\\}`, 'g'), replacement)
+    }
+  }
+
+  return interpolated
+}
+
 /**
  * Translates strings with interpolation & pluralization support.
  * Extensible with custom dictionaries and pluralization functions.
@@ -27,14 +89,14 @@ module.exports = class Translator {
     }
 
     if (Array.isArray(locales)) {
-      locales.forEach((locale) => this._apply(locale))
+      locales.forEach(this.#apply, this)
     } else {
-      this._apply(locales)
+      this.#apply(locales)
     }
   }
 
-  _apply (locale) {
-    if (!locale || !locale.strings) {
+  #apply (locale) {
+    if (!locale?.strings) {
       return
     }
 
@@ -43,66 +105,6 @@ module.exports = class Translator {
     this.locale.pluralize = locale.pluralize || prevLocale.pluralize
   }
 
-  /**
-   * Takes a string with placeholder variables like `%{smart_count} file selected`
-   * and replaces it with values from options `{smart_count: 5}`
-   *
-   * @license https://github.com/airbnb/polyglot.js/blob/master/LICENSE
-   * taken from https://github.com/airbnb/polyglot.js/blob/master/lib/polyglot.js#L299
-   *
-   * @param {string} phrase that needs interpolation, with placeholders
-   * @param {object} options with values that will be used to replace placeholders
-   * @returns {any[]} interpolated
-   */
-  interpolate (phrase, options) {
-    const dollarRegex = /\$/g
-    const dollarBillsYall = '$$$$'
-    let interpolated = [phrase]
-
-    for (const arg in options) {
-      if (arg !== '_' && has(options, arg)) {
-        // Ensure replacement value is escaped to prevent special $-prefixed
-        // regex replace tokens. the "$$$$" is needed because each "$" needs to
-        // be escaped with "$" itself, and we need two in the resulting output.
-        let replacement = options[arg]
-        if (typeof replacement === 'string') {
-          replacement = dollarRegex[Symbol.replace](replacement, dollarBillsYall)
-        }
-        // We create a new `RegExp` each time instead of using a more-efficient
-        // string replace so that the same argument can be replaced multiple times
-        // in the same phrase.
-        interpolated = insertReplacement(interpolated, new RegExp(`%\\{${arg}\\}`, 'g'), replacement)
-      }
-    }
-
-    return interpolated
-
-    function insertReplacement (source, rx, replacement) {
-      const newParts = []
-      source.forEach((chunk) => {
-        // When the source contains multiple placeholders for interpolation,
-        // we should ignore chunks that are not strings, because those
-        // can be JSX objects and will be otherwise incorrectly turned into strings.
-        // Without this condition we’d get this: [object Object] hello [object Object] my <button>
-        if (typeof chunk !== 'string') {
-          return newParts.push(chunk)
-        }
-
-        rx[Symbol.split](chunk).forEach((raw, i, list) => {
-          if (raw !== '') {
-            newParts.push(raw)
-          }
-
-          // Interlace with the `replacement` value
-          if (i < list.length - 1) {
-            newParts.push(replacement)
-          }
-        })
-      })
-      return newParts
-    }
-  }
-
   /**
    * Public translate method
    *
@@ -132,11 +134,11 @@ module.exports = class Translator {
     if (hasPluralForms) {
       if (options && typeof options.smart_count !== 'undefined') {
         const plural = this.locale.pluralize(options.smart_count)
-        return this.interpolate(string[plural], options)
+        return interpolate(string[plural], options)
       }
       throw new Error('Attempted to use a string with plural forms, but no value was given for %{smart_count}')
     }
 
-    return this.interpolate(string, options)
+    return interpolate(string, options)
   }
 }

+ 2 - 1
packages/@uppy/utils/src/delay.test.js

@@ -14,7 +14,8 @@ describe('delay', () => {
     const signal = { aborted: true }
     const start = Date.now()
     await expect(delay(100, { signal })).rejects.toHaveProperty('name', 'AbortError')
-    // should really be instant but using a very large range in case CI decides to be super busy and block the event loop for a while
+    // should really be instant but using a very large range in case CI decides
+    // to be super busy and block the event loop for a while.
     expect(Date.now() - start).toBeLessThan(50)
   })
 

+ 2 - 2
packages/@uppy/utils/src/emitSocketProgress.js

@@ -1,6 +1,6 @@
 const throttle = require('lodash.throttle')
 
-function _emitSocketProgress (uploader, progressData, file) {
+function emitSocketProgress (uploader, progressData, file) {
   const { progress, bytesUploaded, bytesTotal } = progressData
   if (progress) {
     uploader.uppy.log(`Upload progress: ${progress}`)
@@ -12,7 +12,7 @@ function _emitSocketProgress (uploader, progressData, file) {
   }
 }
 
-module.exports = throttle(_emitSocketProgress, 300, {
+module.exports = throttle(emitSocketProgress, 300, {
   leading: true,
   trailing: true,
 })

+ 2 - 0
packages/@uppy/utils/src/findDOMElement.js

@@ -14,4 +14,6 @@ module.exports = function findDOMElement (element, context = document) {
   if (isDOMElement(element)) {
     return element
   }
+
+  return null
 }

+ 12 - 12
packages/@uppy/utils/src/generateFileID.js

@@ -1,3 +1,15 @@
+function encodeCharacter (character) {
+  return character.charCodeAt(0).toString(32)
+}
+
+function encodeFilename (name) {
+  let suffix = ''
+  return name.replace(/[^A-Z0-9]/ig, (character) => {
+    suffix += `-${encodeCharacter(character)}`
+    return '/'
+  }) + suffix
+}
+
 /**
  * Takes a file object and turns it into fileID, by converting file.name to lowercase,
  * removing extra characters and adding type, size and lastModified
@@ -31,15 +43,3 @@ module.exports = function generateFileID (file) {
 
   return id
 }
-
-function encodeFilename (name) {
-  let suffix = ''
-  return name.replace(/[^A-Z0-9]/ig, (character) => {
-    suffix += `-${encodeCharacter(character)}`
-    return '/'
-  }) + suffix
-}
-
-function encodeCharacter (character) {
-  return character.charCodeAt(0).toString(32)
-}

+ 9 - 4
packages/@uppy/utils/src/getDroppedFiles/index.js

@@ -2,17 +2,22 @@ const webkitGetAsEntryApi = require('./utils/webkitGetAsEntryApi/index')
 const fallbackApi = require('./utils/fallbackApi')
 
 /**
- * Returns a promise that resolves to the array of dropped files (if a folder is dropped, and browser supports folder parsing - promise resolves to the flat array of all files in all directories).
- * Each file has .relativePath prop appended to it (e.g. "/docs/Prague/ticket_from_prague_to_ufa.pdf") if browser supports it. Otherwise it's undefined.
+ * Returns a promise that resolves to the array of dropped files (if a folder is
+ * dropped, and browser supports folder parsing - promise resolves to the flat
+ * array of all files in all directories).
+ * Each file has .relativePath prop appended to it (e.g. "/docs/Prague/ticket_from_prague_to_ufa.pdf")
+ * if browser supports it. Otherwise it's undefined.
  *
  * @param {DataTransfer} dataTransfer
- * @param {Function} logDropError - a function that's called every time some folder or some file error out (e.g. because of the folder name being too long on Windows). Notice that resulting promise will always be resolved anyway.
+ * @param {Function} logDropError - a function that's called every time some
+ * folder or some file error out (e.g. because of the folder name being too long
+ * on Windows). Notice that resulting promise will always be resolved anyway.
  *
  * @returns {Promise} - Array<File>
  */
 module.exports = function getDroppedFiles (dataTransfer, { logDropError = () => {} } = {}) {
   // Get all files from all subdirs. Works (at least) in Chrome, Mozilla, and Safari
-  if (dataTransfer.items && dataTransfer.items[0] && 'webkitGetAsEntry' in dataTransfer.items[0]) {
+  if (dataTransfer.items?.[0] && 'webkitGetAsEntry' in dataTransfer.items[0]) {
     return webkitGetAsEntryApi(dataTransfer, logDropError)
   // Otherwise just return all first-order files
   }

+ 2 - 1
packages/@uppy/utils/src/getDroppedFiles/utils/webkitGetAsEntryApi/getFilesAndDirectoriesFromDirectory.js

@@ -10,7 +10,8 @@ module.exports = function getFilesAndDirectoriesFromDirectory (directoryReader,
   directoryReader.readEntries(
     (entries) => {
       const newEntries = [...oldEntries, ...entries]
-      // According to the FileSystem API spec, getFilesAndDirectoriesFromDirectory() must be called until it calls the onSuccess with an empty array.
+      // According to the FileSystem API spec, getFilesAndDirectoriesFromDirectory()
+      // must be called until it calls the onSuccess with an empty array.
       if (entries.length) {
         setTimeout(() => {
           getFilesAndDirectoriesFromDirectory(directoryReader, newEntries, logDropError, { onSuccess })

+ 3 - 1
packages/@uppy/utils/src/getDroppedFiles/utils/webkitGetAsEntryApi/getRelativePath.js

@@ -3,7 +3,9 @@
  *
  * @param {FileEntry} fileEntry
  *
- * @returns {string|null} - if file is not in a folder - return null (this is to be consistent with .relativePath-s of files selected from My Device). If file is in a folder - return its fullPath, e.g. '/simpsons/hi.jpeg'.
+ * @returns {string|null} - if file is not in a folder - return null (this is to
+ * be consistent with .relativePath-s of files selected from My Device). If file
+ * is in a folder - return its fullPath, e.g. '/simpsons/hi.jpeg'.
  */
 module.exports = function getRelativePath (fileEntry) {
   // fileEntry.fullPath - "/simpsons/hi.jpeg" or undefined (for browsers that don't support it)

+ 4 - 4
packages/@uppy/utils/src/getDroppedFiles/utils/webkitGetAsEntryApi/index.js

@@ -19,6 +19,7 @@ module.exports = function webkitGetAsEntryApi (dataTransfer, logDropError) {
       // Creates a new File object which can be used to read the file.
       entry.file(
         (file) => {
+          // eslint-disable-next-line no-param-reassign
           file.relativePath = getRelativePath(entry)
           files.push(file)
           resolve()
@@ -33,10 +34,9 @@ module.exports = function webkitGetAsEntryApi (dataTransfer, logDropError) {
     } else if (entry.isDirectory) {
       const directoryReader = entry.createReader()
       getFilesAndDirectoriesFromDirectory(directoryReader, [], logDropError, {
-        onSuccess: (entries) => {
-          const promises = entries.map((entry) => createPromiseToAddFileOrParseDirectory(entry))
-          Promise.all(promises).then(() => resolve())
-        },
+        onSuccess: (entries) => resolve(Promise.all(
+          entries.map(createPromiseToAddFileOrParseDirectory)
+        )),
       })
     }
   })

+ 1 - 1
packages/@uppy/utils/src/getETA.js

@@ -6,7 +6,7 @@ module.exports = function getETA (fileProgress) {
 
   const uploadSpeed = getSpeed(fileProgress)
   const bytesRemaining = getBytesRemaining(fileProgress)
-  const secondsRemaining = Math.round(bytesRemaining / uploadSpeed * 10) / 10
+  const secondsRemaining = Math.round((bytesRemaining / uploadSpeed) * 10) / 10
 
   return secondsRemaining
 }

+ 10 - 9
packages/@uppy/utils/src/getTimeStamp.js

@@ -1,3 +1,13 @@
+/**
+ * Adds zero to strings shorter than two characters.
+ *
+ * @param {number} number
+ * @returns {string}
+ */
+function pad (number) {
+  return number < 10 ? `0${number}` : number.toString()
+}
+
 /**
  * Returns a timestamp in the format of `hours:minutes:seconds`
  */
@@ -8,12 +18,3 @@ module.exports = function getTimeStamp () {
   const seconds = pad(date.getSeconds())
   return `${hours}:${minutes}:${seconds}`
 }
-
-/**
- * Adds zero to strings shorter than two characters
- * @param {number}
- * @returns {string}
- */
-function pad (number) {
-  return number < 10 ? `0${number}` : number.toString()
-}