Переглянути джерело

@uppy/url: refactor to ESM (#3713)

Antoine du Hamel 2 роки тому
батько
коміт
a3465f7166

+ 1 - 0
.eslintrc.js

@@ -213,6 +213,7 @@ module.exports = {
         'packages/@uppy/progress-bar/src/**/*.js',
         'packages/@uppy/svelte/src/**/*.js',
         'packages/@uppy/svelte/rollup.config.js',
+        'packages/@uppy/url/src/**/*.js',
         'packages/@uppy/vue/src/**/*.js',
         'packages/@uppy/webcam/src/**/*.js',
       ],

+ 1 - 0
packages/@uppy/url/package.json

@@ -6,6 +6,7 @@
   "main": "lib/index.js",
   "style": "dist/style.min.css",
   "types": "types/index.d.ts",
+  "type": "module",
   "keywords": [
     "file uploader",
     "url",

+ 192 - 0
packages/@uppy/url/src/Url.jsx

@@ -0,0 +1,192 @@
+import { h } from 'preact'
+import { UIPlugin } from '@uppy/core'
+import { RequestClient } from '@uppy/companion-client'
+import toArray from '@uppy/utils/lib/toArray'
+import UrlUI from './UrlUI.jsx'
+import forEachDroppedOrPastedUrl from './utils/forEachDroppedOrPastedUrl.js'
+
+import packageJson from '../package.json'
+import locale from './locale.js'
+
+function UrlIcon () {
+  return (
+    <svg aria-hidden="true" focusable="false" width="32" height="32" viewBox="0 0 32 32">
+      <g fill="none" fillRule="evenodd">
+        <rect className="uppy-ProviderIconBg" fill="#FF753E" width="32" height="32" rx="16" />
+        <path d="M22.788 15.389l-2.199 2.19a3.184 3.184 0 0 1-.513.437c-.806.584-1.686.876-2.638.876a4.378 4.378 0 0 1-3.519-1.752c-.22-.292-.146-.802.147-1.021.293-.22.806-.146 1.026.146.953 1.313 2.785 1.532 4.105.583a.571.571 0 0 0 .293-.292l2.199-2.189c1.1-1.167 1.1-2.992-.073-4.086a2.976 2.976 0 0 0-4.105 0l-1.246 1.24a.71.71 0 0 1-1.026 0 .703.703 0 0 1 0-1.022l1.246-1.24a4.305 4.305 0 0 1 6.083 0c1.833 1.605 1.906 4.451.22 6.13zm-7.183 5.035l-1.246 1.24a2.976 2.976 0 0 1-4.105 0c-1.172-1.094-1.172-2.991-.073-4.086l2.2-2.19.292-.291c.66-.438 1.393-.657 2.2-.584.805.146 1.465.51 1.905 1.168.22.292.733.365 1.026.146.293-.22.367-.73.147-1.022-.733-.949-1.76-1.532-2.859-1.678-1.1-.22-2.272.073-3.225.802l-.44.438-2.199 2.19c-1.686 1.75-1.612 4.524.074 6.202.88.803 1.979 1.241 3.078 1.241 1.1 0 2.199-.438 3.079-1.24l1.246-1.241a.703.703 0 0 0 0-1.022c-.294-.292-.807-.365-1.1-.073z" fill="#FFF" fillRule="nonzero" />
+      </g>
+    </svg>
+  )
+}
+
+function addProtocolToURL (url) {
+  const protocolRegex = /^[a-z0-9]+:\/\//
+  const defaultProtocol = 'http://'
+  if (protocolRegex.test(url)) {
+    return url
+  }
+
+  return defaultProtocol + url
+}
+
+function canHandleRootDrop (e) {
+  const items = toArray(e.dataTransfer.items)
+  const urls = items.filter((item) => item.kind === 'string'
+    && item.type === 'text/uri-list')
+  return urls.length > 0
+}
+
+function checkIfCorrectURL (url) {
+  if (!url) return false
+
+  const protocol = url.match(/^([a-z0-9]+):\/\//)[1]
+  if (protocol !== 'http' && protocol !== 'https') {
+    return false
+  }
+
+  return true
+}
+
+function getFileNameFromUrl (url) {
+  return url.substring(url.lastIndexOf('/') + 1)
+}
+/**
+ * Url
+ *
+ */
+export default class Url extends UIPlugin {
+  static VERSION = packageJson.version
+
+  constructor (uppy, opts) {
+    super(uppy, opts)
+    this.id = this.opts.id || 'Url'
+    this.title = this.opts.title || 'Link'
+    this.type = 'acquirer'
+    this.icon = () => <UrlIcon />
+
+    // Set default options and locale
+    this.defaultLocale = locale
+
+    const defaultOptions = {}
+
+    this.opts = { ...defaultOptions, ...opts }
+
+    this.i18nInit()
+
+    this.hostname = this.opts.companionUrl
+
+    if (!this.hostname) {
+      throw new Error('Companion hostname is required, please consult https://uppy.io/docs/companion')
+    }
+
+    // Bind all event handlers for referencability
+    this.getMeta = this.getMeta.bind(this)
+    this.addFile = this.addFile.bind(this)
+    this.handleRootDrop = this.handleRootDrop.bind(this)
+    this.handleRootPaste = this.handleRootPaste.bind(this)
+
+    this.client = new RequestClient(uppy, {
+      companionUrl: this.opts.companionUrl,
+      companionHeaders: this.opts.companionHeaders,
+      companionCookiesRule: this.opts.companionCookiesRule,
+    })
+  }
+
+  getMeta (url) {
+    return this.client.post('url/meta', { url })
+      .then((res) => {
+        if (res.error) {
+          this.uppy.log('[URL] Error:')
+          this.uppy.log(res.error)
+          throw new Error('Failed to fetch the file')
+        }
+        return res
+      })
+  }
+
+  async addFile (protocollessUrl) {
+    const url = this.addProtocolToURL(protocollessUrl)
+    if (!this.checkIfCorrectURL(url)) {
+      this.uppy.log(`[URL] Incorrect URL entered: ${url}`)
+      this.uppy.info(this.i18n('enterCorrectUrl'), 'error', 4000)
+      return undefined
+    }
+
+    try {
+      const meta = await this.getMeta(url)
+
+      const tagFile = {
+        source: this.id,
+        name: this.getFileNameFromUrl(url),
+        type: meta.type,
+        data: {
+          size: meta.size,
+        },
+        isRemote: true,
+        body: {
+          url,
+        },
+        remote: {
+          companionUrl: this.opts.companionUrl,
+          url: `${this.hostname}/url/get`,
+          body: {
+            fileId: url,
+            url,
+          },
+          providerOptions: this.client.opts,
+        },
+      }
+      this.uppy.log('[Url] Adding remote file')
+      try {
+        return this.uppy.addFile(tagFile)
+      } catch (err) {
+        if (!err.isRestriction) {
+          this.uppy.log(err)
+        }
+        return err
+      }
+    } catch (err) {
+      this.uppy.log(err)
+      this.uppy.info({
+        message: this.i18n('failedToFetch'),
+        details: err,
+      }, 'error', 4000)
+      return err
+    }
+  }
+
+  handleRootDrop (e) {
+    forEachDroppedOrPastedUrl(e.dataTransfer, 'drop', (url) => {
+      this.uppy.log(`[URL] Adding file from dropped url: ${url}`)
+      this.addFile(url)
+    })
+  }
+
+  handleRootPaste (e) {
+    forEachDroppedOrPastedUrl(e.clipboardData, 'paste', (url) => {
+      this.uppy.log(`[URL] Adding file from pasted url: ${url}`)
+      this.addFile(url)
+    })
+  }
+
+  render () {
+    return <UrlUI i18n={this.i18n} addFile={this.addFile} />
+  }
+
+  install () {
+    const { target } = this.opts
+    if (target) {
+      this.mount(target, this)
+    }
+  }
+
+  uninstall () {
+    this.unmount()
+  }
+}
+
+// TODO: remove from prototype in the next major.
+Url.prototype.addProtocolToURL = addProtocolToURL
+Url.prototype.canHandleRootDrop = canHandleRootDrop
+Url.prototype.checkIfCorrectURL = checkIfCorrectURL
+Url.prototype.getFileNameFromUrl = getFileNameFromUrl

+ 10 - 7
packages/@uppy/url/src/UrlUI.js → packages/@uppy/url/src/UrlUI.jsx

@@ -1,4 +1,4 @@
-const { h, Component } = require('preact')
+import { h, Component } from 'preact'
 
 class UrlUI extends Component {
   constructor (props) {
@@ -12,23 +12,26 @@ class UrlUI extends Component {
   }
 
   handleKeyPress (ev) {
+    const { addFile } = this.props
     if (ev.keyCode === 13) {
-      this.props.addFile(this.input.value)
+      addFile(this.input.value)
     }
   }
 
   handleClick () {
-    this.props.addFile(this.input.value)
+    const { addFile } = this.props
+    addFile(this.input.value)
   }
 
   render () {
+    const { i18n } = this.props
     return (
       <div className="uppy-Url">
         <input
           className="uppy-u-reset uppy-c-textInput uppy-Url-input"
           type="text"
-          aria-label={this.props.i18n('enterUrlToImport')}
-          placeholder={this.props.i18n('enterUrlToImport')}
+          aria-label={i18n('enterUrlToImport')}
+          placeholder={i18n('enterUrlToImport')}
           onKeyUp={this.handleKeyPress}
           ref={(input) => { this.input = input }}
           data-uppy-super-focusable
@@ -38,11 +41,11 @@ class UrlUI extends Component {
           type="button"
           onClick={this.handleClick}
         >
-          {this.props.i18n('import')}
+          {i18n('import')}
         </button>
       </div>
     )
   }
 }
 
-module.exports = UrlUI
+export default UrlUI

+ 1 - 189
packages/@uppy/url/src/index.js

@@ -1,189 +1 @@
-const { UIPlugin } = require('@uppy/core')
-const { h } = require('preact')
-const { RequestClient } = require('@uppy/companion-client')
-const toArray = require('@uppy/utils/lib/toArray')
-const UrlUI = require('./UrlUI.js')
-const forEachDroppedOrPastedUrl = require('./utils/forEachDroppedOrPastedUrl')
-
-const locale = require('./locale')
-
-function UrlIcon () {
-  return (
-    <svg aria-hidden="true" focusable="false" width="32" height="32" viewBox="0 0 32 32">
-      <g fill="none" fillRule="evenodd">
-        <rect className="uppy-ProviderIconBg" fill="#FF753E" width="32" height="32" rx="16" />
-        <path d="M22.788 15.389l-2.199 2.19a3.184 3.184 0 0 1-.513.437c-.806.584-1.686.876-2.638.876a4.378 4.378 0 0 1-3.519-1.752c-.22-.292-.146-.802.147-1.021.293-.22.806-.146 1.026.146.953 1.313 2.785 1.532 4.105.583a.571.571 0 0 0 .293-.292l2.199-2.189c1.1-1.167 1.1-2.992-.073-4.086a2.976 2.976 0 0 0-4.105 0l-1.246 1.24a.71.71 0 0 1-1.026 0 .703.703 0 0 1 0-1.022l1.246-1.24a4.305 4.305 0 0 1 6.083 0c1.833 1.605 1.906 4.451.22 6.13zm-7.183 5.035l-1.246 1.24a2.976 2.976 0 0 1-4.105 0c-1.172-1.094-1.172-2.991-.073-4.086l2.2-2.19.292-.291c.66-.438 1.393-.657 2.2-.584.805.146 1.465.51 1.905 1.168.22.292.733.365 1.026.146.293-.22.367-.73.147-1.022-.733-.949-1.76-1.532-2.859-1.678-1.1-.22-2.272.073-3.225.802l-.44.438-2.199 2.19c-1.686 1.75-1.612 4.524.074 6.202.88.803 1.979 1.241 3.078 1.241 1.1 0 2.199-.438 3.079-1.24l1.246-1.241a.703.703 0 0 0 0-1.022c-.294-.292-.807-.365-1.1-.073z" fill="#FFF" fillRule="nonzero" />
-      </g>
-    </svg>
-  )
-}
-
-/**
- * Url
- *
- */
-module.exports = class Url extends UIPlugin {
-  static VERSION = require('../package.json').version
-
-  constructor (uppy, opts) {
-    super(uppy, opts)
-    this.id = this.opts.id || 'Url'
-    this.title = this.opts.title || 'Link'
-    this.type = 'acquirer'
-    this.icon = () => <UrlIcon />
-
-    // Set default options and locale
-    this.defaultLocale = locale
-
-    const defaultOptions = {}
-
-    this.opts = { ...defaultOptions, ...opts }
-
-    this.i18nInit()
-
-    this.hostname = this.opts.companionUrl
-
-    if (!this.hostname) {
-      throw new Error('Companion hostname is required, please consult https://uppy.io/docs/companion')
-    }
-
-    // Bind all event handlers for referencability
-    this.getMeta = this.getMeta.bind(this)
-    this.addFile = this.addFile.bind(this)
-    this.handleRootDrop = this.handleRootDrop.bind(this)
-    this.handleRootPaste = this.handleRootPaste.bind(this)
-
-    this.client = new RequestClient(uppy, {
-      companionUrl: this.opts.companionUrl,
-      companionHeaders: this.opts.companionHeaders,
-      companionCookiesRule: this.opts.companionCookiesRule,
-    })
-  }
-
-  getFileNameFromUrl (url) {
-    return url.substring(url.lastIndexOf('/') + 1)
-  }
-
-  checkIfCorrectURL (url) {
-    if (!url) return false
-
-    const protocol = url.match(/^([a-z0-9]+):\/\//)[1]
-    if (protocol !== 'http' && protocol !== 'https') {
-      return false
-    }
-
-    return true
-  }
-
-  addProtocolToURL (url) {
-    const protocolRegex = /^[a-z0-9]+:\/\//
-    const defaultProtocol = 'http://'
-    if (protocolRegex.test(url)) {
-      return url
-    }
-
-    return defaultProtocol + url
-  }
-
-  getMeta (url) {
-    return this.client.post('url/meta', { url })
-      .then((res) => {
-        if (res.error) {
-          this.uppy.log('[URL] Error:')
-          this.uppy.log(res.error)
-          throw new Error('Failed to fetch the file')
-        }
-        return res
-      })
-  }
-
-  addFile (url) {
-    url = this.addProtocolToURL(url)
-    if (!this.checkIfCorrectURL(url)) {
-      this.uppy.log(`[URL] Incorrect URL entered: ${url}`)
-      this.uppy.info(this.i18n('enterCorrectUrl'), 'error', 4000)
-      return
-    }
-
-    return this.getMeta(url)
-      .then((meta) => {
-        const tagFile = {
-          source: this.id,
-          name: this.getFileNameFromUrl(url),
-          type: meta.type,
-          data: {
-            size: meta.size,
-          },
-          isRemote: true,
-          body: {
-            url,
-          },
-          remote: {
-            companionUrl: this.opts.companionUrl,
-            url: `${this.hostname}/url/get`,
-            body: {
-              fileId: url,
-              url,
-            },
-            providerOptions: this.client.opts,
-          },
-        }
-        return tagFile
-      })
-      .then((tagFile) => {
-        this.uppy.log('[Url] Adding remote file')
-        try {
-          return this.uppy.addFile(tagFile)
-        } catch (err) {
-          if (!err.isRestriction) {
-            this.uppy.log(err)
-          }
-          return err
-        }
-      })
-      .catch((err) => {
-        this.uppy.log(err)
-        this.uppy.info({
-          message: this.i18n('failedToFetch'),
-          details: err,
-        }, 'error', 4000)
-        return err
-      })
-  }
-
-  canHandleRootDrop (e) {
-    const items = toArray(e.dataTransfer.items)
-    const urls = items.filter((item) => item.kind === 'string'
-      && item.type === 'text/uri-list')
-    return urls.length > 0
-  }
-
-  handleRootDrop (e) {
-    forEachDroppedOrPastedUrl(e.dataTransfer, 'drop', (url) => {
-      this.uppy.log(`[URL] Adding file from dropped url: ${url}`)
-      this.addFile(url)
-    })
-  }
-
-  handleRootPaste (e) {
-    forEachDroppedOrPastedUrl(e.clipboardData, 'paste', (url) => {
-      this.uppy.log(`[URL] Adding file from pasted url: ${url}`)
-      this.addFile(url)
-    })
-  }
-
-  render () {
-    return <UrlUI i18n={this.i18n} addFile={this.addFile} />
-  }
-
-  install () {
-    const { target } = this.opts
-    if (target) {
-      this.mount(target, this)
-    }
-  }
-
-  uninstall () {
-    this.unmount()
-  }
-}
+export { default } from './Url.jsx'

+ 1 - 1
packages/@uppy/url/src/locale.js

@@ -1,4 +1,4 @@
-module.exports = {
+export default {
   strings: {
     // Label for the "Import" button.
     import: 'Import',

+ 2 - 2
packages/@uppy/url/src/utils/forEachDroppedOrPastedUrl.js

@@ -1,4 +1,4 @@
-const toArray = require('@uppy/utils/lib/toArray')
+import toArray from '@uppy/utils/lib/toArray'
 
 /*
   SITUATION
@@ -58,7 +58,7 @@ const toArray = require('@uppy/utils/lib/toArray')
  * @param {string} isDropOrPaste - either 'drop' or 'paste'
  * @param {Function} callback - (urlString) => {}
  */
-module.exports = function forEachDroppedOrPastedUrl (dataTransfer, isDropOrPaste, callback) {
+export default function forEachDroppedOrPastedUrl (dataTransfer, isDropOrPaste, callback) {
   const items = toArray(dataTransfer.items)
 
   let urlItems

+ 1 - 1
website/src/docs/url.md

@@ -87,7 +87,7 @@ This option correlates to the [RequestCredentials value](https://developer.mozil
 <!-- eslint-disable no-restricted-globals, no-multiple-empty-lines -->
 
 ```js
-module.exports = {
+export default {
   strings: {
     // Label for the "Import" button.
     import: 'Import',