# File Picker

The [File Picker](https://www.npmjs.com/package/@apideck/file-picker-js) is an open-source, plug-and-play, component that connects to many cloud storage APIs and offers easy file uploads and downloads between your app and any cloud storage service.
This NPM package works with the [File Storage API](https://developers.apideck.com/apis/file-storage/reference) and allows your users to select, search and upload files to multiple services.

Setting up File Picker takes three steps: configure Apideck, create a Vault session, and add the component to your app.

- [Step 1: Setup Apideck](#step-1-setup-apideck)
- [Step 2: Create a session](#step-2-create-a-session)
- [Step 3: Add File Picker](#step-3-add-file-picker)

## Step 1: Setup Apideck

### Create an account

If you haven't already, head over to our [Signup page](https://www.apideck.com/signup?products=unify&source=docs-file-picker) and create an account. Choose an application name and a subdomain. Afterward, you will be redirected to the Apideck dashboard.

### Enable Unified APIs and connectors

Go to the [Unified APIs](https://platform.apideck.com/configuration) page in the Apideck dashboard. Choose one or more Unified APIs to enable. You'll see a list of the available connectors for each Unified API. Choose a couple of connectors to enable. The Unified APIs and connectors you select become available to your users in [Vault](https://developers.apideck.com/apis/vault/reference).

### Get your API key and Application ID

Go to the [API Keys](https://platform.apideck.com/configuration/api-keys) page in the Apideck dashboard. Copy your application ID and API key.
If your API key ever gets compromised, you can regenerate it on this page.

![API keys overview](/get-started/api-keys.png)

## Step 2: Create a session

Vault lets your users (called consumers in Apideck) easily connect and configure integrations. You can create a consumer through a Vault session through the following endpoint https://developers.apideck.com/apis/vault/reference#tag/Sessions.

Most of the time, this is an ID of your internal data model that represents a user or account in your system. E.g., account:12345. If the consumer doesn't exist yet, Vault will upsert a consumer based on your ID.

> **Note 🚨**
>
> Session creation should always happen server-side to prevent token leakage.

Use the API call below to create a session for a consumer. This will return a Vault URL that you forward to a consumer to connect integrations.

```sh meta=terminal
curl --request POST \
  --url 'https://unify.apideck.com/vault/sessions' \
  --header 'Authorization: Bearer {API_KEY}' \
  --header 'x-apideck-app-id: {APP_ID}' \
  --header 'x-apideck-consumer-id: {CONSUMER_ID}' \
```

You can also use our Node SDK to create a session.

```sh meta=terminal
yarn add @apideck/unify
```

Below is an example of creating a Serverless Function to create a session inside a Next.js project:

```ts meta=/api/vault/sessions.ts
import { VercelRequest, VercelResponse } from '@vercel/node'
import { Apideck } from '@apideck/unify'

const createSession = async (_: VercelRequest, res: VercelResponse) => {
  const apideck = new Apideck({
    apiKey: process.env.API_KEY ?? '',
    appId: process.env.APP_ID ?? '',
    consumerId: 'test-consumer'
  })

  const { data } = await apideck.vault.sessions.create({
    session: {}
  })

  res.json(data)
}

export default createSession
```

The returned `data` object will include the `session_token` that you can use pass as the `token` prop to the `FilePicker` component.

## Step 3: Add the File Picker

### Package

```sh
npm install @apideck/file-picker-js
```

### Script

If you don't want to set up a build environment, you can get `@apideck/file-picker-js` from a CDN like unpkg.com and it will be globally available through the `window.FilePicker` object.

```html
<script src="https://unpkg.com/@apideck/file-picker-js"></script>
```

### Usage

Pass the JWT you got from the Vault session to `@apideck/file-picker-js` and provide an `onSelect` function that acts upon selection of a file:

```js
import { FilePicker } from '@apideck/file-picker-js'

FilePicker.open({
  token: 'REPLACE_WITH_SESSION_TOKEN',
  onSelect: (file) => console.log(file)
})
```

If you want to get notified when the modal opens and closes, you can provide the `onReady` and `onClose` options. You could also get notified when the consumer switches from integration by using the `onConnectionSelect` option.

```jsx
import { FilePicker } from '@apideck/file-picker-js'

FilePicker.open({
  token: 'REPLACE_WITH_SESSION_TOKEN',
  onSelect: (file) => console.log(file),
  onClose: () => {
    console.log('closed!')
  },
  onReady: () => {
    console.log('ready!')
  },
  onConnectionSelect: (connection) => {
    console.log(connection)
  }
})
```

You can also provide a file through the `fileToSave` options that will force the FilePicker to go into "Upload" mode. This will allow the user to select the connector and folder that the file needs to get saved to.

```jsx
import { FilePicker } from '@apideck/file-picker-js'

FilePicker.open({
  token: 'REPLACE_WITH_SESSION_TOKEN',
  fileToSave: '<add-file-here>'
})
```

### Demo

This demo uses the `@apideck/file-picker-js` package, which works in any JavaScript application. Click the button to run the code shown below.

### Properties

| Property           | Type    | Required | Default             | Description                                                           |
| ------------------ | ------- | -------- | ------------------- | --------------------------------------------------------------------- |
| token              | string  | true     | -                   | The JSON Web Token returned from the Create Session call              |
| open               | boolean | false    | false               | Opens the file picker if set to true                                  |
| onClose            | event   | false    | -                   | Function that gets called when the modal is closed                    |
| onSelect           | event   | false    | -                   | The function that gets called when a file is selected                 |
| onConnectionSelect | event   | false    | -                   | The function that gets called when a connection is selected           |
| fileToSave         | file    | false    | -                   | Forces "Upload" mode to select the folder to upload the provided file |
| title              | string  | false    | Apideck File Picker | Title shown in the modal                                              |
| subTitle           | string  | false    | Select a file       | Subtitle shown in the modal                                           |
| showAttribution    | boolean | false    | true                | Show "Powered by Apideck" in the backdrop of the modal backdrop       |
