Explorar o código

@uppy/remote-sources: support companionKeysParams (#5434)

* @uppy/remote-sources: support companionKeysParams

* fix doc reference
Merlijn Vos hai 7 meses
pai
achega
38bf2a720c

+ 38 - 0
docs/presets/remote-sources.mdx

@@ -81,6 +81,42 @@ new Uppy();
   .use(RemoteSources, { companionUrl: 'https://your-companion-url' });
 ```
 
+### Use with Transloadit
+
+```js
+import { COMPANION_URL, COMPANION_ALLOWED_HOSTS } from '@uppy/transloadit';
+import RemoteSources from '@uppy/remote-sources';
+
+uppy.use(RemoteSources, {
+	companionUrl: COMPANION_URL,
+	companionAllowedHosts: COMPANION_ALLOWED_HOSTS,
+});
+```
+
+You may also hit rate limits, because the OAuth application is shared between
+everyone using Transloadit.
+
+To solve that, you can use your own OAuth keys with Transloadit’s hosted
+Companion servers by using Transloadit Template Credentials. [Create a Template
+Credential][template-credentials] on the Transloadit site. Select “Companion
+OAuth” for the service, and enter the key and secret for the provider you want
+to use. Then you can pass the name of the new credentials to that provider:
+
+```js
+import { COMPANION_URL, COMPANION_ALLOWED_HOSTS } from '@uppy/transloadit';
+import RemoteSources from '@uppy/remote-sources';
+
+uppy.use(RemoteSources, {
+	companionUrl: COMPANION_URL,
+	companionAllowedHosts: COMPANION_ALLOWED_HOSTS,
+	companionKeysParams: {
+		GoogleDrive: { key: '...', credentialsName: '...' },
+		Dropbox: { key: '...', credentialsName: '...' },
+		// ...etc
+	},
+});
+```
+
 ## API
 
 ### Options
@@ -139,3 +175,5 @@ DOM element, CSS selector, or plugin to place the drag and drop area into
 
 [`request.credentials` value]:
 	https://developer.mozilla.org/en-US/docs/Web/API/Request/credentials
+[template-credentials]:
+	https://transloadit.com/docs/#how-to-create-template-credentials

+ 1 - 1
packages/@uppy/companion-client/src/CompanionPluginOptions.ts

@@ -5,7 +5,7 @@ export interface CompanionPluginOptions extends UIPluginOptions {
   storage?: typeof tokenStorage
   companionUrl: string
   companionHeaders?: Record<string, string>
-  companionKeysParams?: Record<string, string>
+  companionKeysParams?: { key: string; credentialsName: string }
   companionCookiesRule?: 'same-origin' | 'include'
   companionAllowedHosts?: string | RegExp | (string | RegExp)[]
 }

+ 15 - 0
packages/@uppy/remote-sources/src/index.test.ts

@@ -50,4 +50,19 @@ describe('RemoteSources', () => {
       'Invalid plugin: "Webcam" is not one of: Box, Dropbox, Facebook, GoogleDrive, GooglePhotos, Instagram, OneDrive, Unsplash, Url, or Zoom.',
     )
   })
+
+  it('should pass companionKeysParams', () => {
+    const core = new Core()
+    const companionKeysParams = {
+      GoogleDrive: { key: 'google', credentialsName: 'google' },
+    }
+    core.use(Dashboard)
+    core.use(RemoteSources, {
+      companionUrl: 'https://example.com',
+      companionKeysParams,
+    })
+    expect(core.getPlugin('GoogleDrive')?.opts.companionKeysParams).toEqual(
+      companionKeysParams.GoogleDrive,
+    )
+  })
 })

+ 30 - 6
packages/@uppy/remote-sources/src/index.ts

@@ -32,14 +32,33 @@ const availablePlugins = {
   Zoom,
 }
 
-export interface RemoteSourcesOptions extends CompanionPluginOptions {
-  sources?: Array<keyof Omit<typeof availablePlugins, '__proto__'>>
+type AvailablePluginsKeys =
+  | 'Box'
+  | 'Dropbox'
+  | 'Facebook'
+  | 'GoogleDrive'
+  | 'GooglePhotos'
+  | 'Instagram'
+  | 'OneDrive'
+  | 'Unsplash'
+  | 'Url'
+  | 'Zoom'
+
+type NestedCompanionKeysParams = {
+  [key in AvailablePluginsKeys]?: CompanionPluginOptions['companionKeysParams']
+}
+
+export interface RemoteSourcesOptions
+  extends Omit<CompanionPluginOptions, 'companionKeysParams'> {
+  sources?: Array<AvailablePluginsKeys>
+  // Individual remote source plugins set the `key` and `credentialsName`
+  // in `companionKeysParams` but because this is a preset we need to change
+  // this to a record of plugin IDs to their respective `companionKeysParams`.
+  companionKeysParams?: NestedCompanionKeysParams
 }
 
 const defaultOptions = {
-  sources: Object.keys(availablePlugins) as Array<
-    keyof Omit<typeof availablePlugins, '__proto__'>
-  >,
+  sources: Object.keys(availablePlugins) as Array<AvailablePluginsKeys>,
 } satisfies Partial<RemoteSourcesOptions>
 
 type Opts = DefinePluginOpts<RemoteSourcesOptions, keyof typeof defaultOptions>
@@ -72,7 +91,12 @@ export default class RemoteSources<
 
   install(): void {
     this.opts.sources.forEach((pluginId) => {
-      const optsForRemoteSourcePlugin = { ...this.opts, sources: undefined }
+      // eslint-disable-next-line @typescript-eslint/no-unused-vars
+      const { sources, ...rest } = this.opts
+      const optsForRemoteSourcePlugin: CompanionPluginOptions = {
+        ...rest,
+        companionKeysParams: this.opts.companionKeysParams?.[pluginId],
+      }
       const plugin = availablePlugins[pluginId]
       if (plugin == null) {
         const pluginNames = Object.keys(availablePlugins)