Files
medusa-store/www/apps/resources/references/file/classes/file.AbstractFileProviderService/page.mdx

290 lines
11 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
slug: /references/file-provider-module
---
import { TypeList } from "docs-ui"
# How to Create a File Provider Module
In this document, youll learn how to create a file provider module and the methods you must implement in its main service.
---
## Create Module Provider Directory
Start by creating a new directory for your module provider.
If you're creating the module provider in a Medusa application, create it under the `src/modules` directory. For example, `src/modules/my-file`.
If you're creating the module provider in a plugin, create it under the `src/providers` directory. For example, `src/providers/my-file`.
<Note>
The rest of this guide always uses the `src/modules/my-file` directory as an example.
</Note>
---
## 2. Create the File Provider Service
Create the file `src/modules/my-file/service.ts` that holds the implementation of the module's main service. It must extend the `AbstractFileProviderService` class imported from `@medusajs/framework/utils`:
```ts title="src/modules/my-file/service.ts"
import { AbstractFileProviderService } from "@medusajs/framework/utils"
class MyFileProviderService extends AbstractFileProviderService {
// TODO implement methods
}
export default MyFileProviderService
```
### constructor
The constructor allows you to access resources from the module's container using the first parameter,
and the module's options using the second parameter.
If you're creating a client or establishing a connection with a third-party service, do it in the constructor.
#### Example
```ts
import { Logger } from "@medusajs/framework/types"
import { AbstractFileProviderService } from "@medusajs/framework/utils"
type InjectedDependencies = {
logger: Logger
}
type Options = {
apiKey: string
}
class MyFileProviderService extends AbstractFileProviderService {
protected logger_: Logger
protected options_: Options
static identifier = "my-file"
// assuming you're initializing a client
protected client
constructor (
{ logger }: InjectedDependencies,
options: Options
) {
super()
this.logger_ = logger
this.options_ = options
// assuming you're initializing a client
this.client = new Client(options)
}
}
export default MyFileProviderService
```
### identifier
Each file provider has a unique ID used to identify it. The provider's ID
will be stored as `fs_{identifier}_{id}`, where `{id}` is the provider's `id`
property in the `medusa-config.ts`.
#### Example
```ts
class MyFileProviderService extends AbstractFileProviderService {
static identifier = "my-file"
// ...
}
```
### validateOptions
This method validates the options of the provider set in `medusa-config.ts`.
Implementing this method is optional. It's useful if your provider requires custom validation.
If the options aren't valid, throw an error.
#### Example
```ts
class MyFileProviderService extends AbstractFileProviderService {
static validateOptions(options: Record<any, any>) {
if (!options.apiKey) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"API key is required in the provider's options."
)
}
}
}
```
#### Parameters
<TypeList types={[{"name":"options","type":"`Record<any, any>`","description":"The provider's options.","optional":false,"defaultValue":"","expandable":false,"children":[]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="validateOptions"/>
### upload
This method uploads a file using your provider's custom logic. In this method, you can upload the file
into your provider's storage, and return the uploaded file's details.
This method will be used when uploading product images, CSV files for imports, or other
custom file uploads.
#### Example
```ts
class MyFileProviderService extends AbstractFileProviderService {
// ...
async upload(
file: ProviderUploadFileDTO
): Promise<ProviderFileResultDTO> {
// TODO upload file to third-party provider
// or using custom logic
// for example:
this.client.upload(file)
return {
url: "some-url.com",
key: "file-name-or-id"
}
}
}
```
#### Parameters
<TypeList types={[{"name":"file","type":"[ProviderUploadFileDTO](../../../types/FileTypes/interfaces/types.FileTypes.ProviderUploadFileDTO/page.mdx)","description":"The file to upload.","optional":false,"defaultValue":"","expandable":false,"children":[{"name":"filename","type":"`string`","description":"The filename of the uploaded file","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"mimeType","type":"`string`","description":"The mimetype of the uploaded file","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"content","type":"`string`","description":"The file content as a binary-encoded string","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"access","type":"`\"public\"` \\| `\"private\"`","description":"The access level of the file. Defaults to private if not passed","optional":true,"defaultValue":"","expandable":false,"children":[]}]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="upload"/>
#### Returns
<TypeList types={[{"name":"Promise","type":"Promise&#60;[ProviderFileResultDTO](../../../types/FileTypes/interfaces/types.FileTypes.ProviderFileResultDTO/page.mdx)&#62;","optional":false,"defaultValue":"","description":"The uploaded file's details.","expandable":false,"children":[{"name":"ProviderFileResultDTO","type":"[ProviderFileResultDTO](../../../types/FileTypes/interfaces/types.FileTypes.ProviderFileResultDTO/page.mdx)","optional":false,"defaultValue":"","description":"","expandable":false,"children":[{"name":"url","type":"`string`","description":"The file's URL that users or systems\ncan use to access the file.","optional":false,"defaultValue":"","expandable":false,"children":[]},{"name":"key","type":"`string`","description":"The file's key allowing you to later\nidentify the file in the third-party\nsystem. For example, the S3 Module Provider\nreturns the file's key in S3, whereas the\nLocal File Module Provider returns the file's\npath.","optional":false,"defaultValue":"","expandable":false,"children":[]}]}]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="upload"/>
### delete
This method deletes the file from storage. It's used when an admin user deletes a product image,
or other custom file deletions.
#### Example
```ts
class MyFileProviderService extends AbstractFileProviderService {
// ...
async delete(file: ProviderDeleteFileDTO): Promise<void> {
// TODO logic to remove the file from storage
// Use the `file.fileKey` to delete the file
// for example:
this.client.delete(file.fileKey)
}
}
```
#### Parameters
<TypeList types={[{"name":"file","type":"[ProviderDeleteFileDTO](../../../types/FileTypes/interfaces/types.FileTypes.ProviderDeleteFileDTO/page.mdx)","description":"The details of the file to delete.","optional":false,"defaultValue":"","expandable":false,"children":[{"name":"fileKey","type":"`string`","description":"The file's key. When uploading a file, the\nreturned key is used here.","optional":false,"defaultValue":"","expandable":false,"children":[]}]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="delete"/>
#### Returns
<TypeList types={[{"name":"Promise","type":"Promise&#60;void&#62;","optional":false,"defaultValue":"","description":"Resolves when the file is deleted.","expandable":false,"children":[]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="delete"/>
### getPresignedDownloadUrl
This method is used to retrieve a download URL of the file. For some providers,
such as S3, a presigned URL indicates a temporary URL to get access to a file.
If your provider doesnt perform or offer a similar functionality, you can
return the URL to download the file.
#### Example
```ts
class MyFileProviderService extends AbstractFileProviderService {
// ...
async getPresignedDownloadUrl(
fileData: ProviderGetFileDTO
): Promise<string> {
// TODO logic to get the presigned URL
// Use the `file.fileKey` to delete the file
// for example:
return this.client.getPresignedUrl(fileData.fileKey)
}
}
```
#### Parameters
<TypeList types={[{"name":"fileData","type":"[ProviderGetFileDTO](../../../types/FileTypes/interfaces/types.FileTypes.ProviderGetFileDTO/page.mdx)","description":"The details of the file to get its\npresigned URL.","optional":false,"defaultValue":"","expandable":false,"children":[{"name":"fileKey","type":"`string`","description":"The file's key as returned during upload.","optional":false,"defaultValue":"","expandable":false,"children":[]}]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="getPresignedDownloadUrl"/>
#### Returns
<TypeList types={[{"name":"Promise","type":"Promise&#60;string&#62;","optional":false,"defaultValue":"","description":"The file's presigned URL.","expandable":false,"children":[{"name":"string","type":"`string`","optional":false,"defaultValue":"","description":"","expandable":false,"children":[]}]}]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="getPresignedDownloadUrl"/>
---
## 3. Create Module Definition File
Create the file `src/modules/my-file/index.ts` with the following content:
```ts title="src/modules/my-file/index.ts"
import MyFileProviderService from "./service"
import {
ModuleProvider,
Modules
} from "@medusajs/framework/utils"
export default ModuleProvider(Modules.FILE, {
services: [MyFileProviderService],
})
```
This exports the module's definition, indicating that the `MyFileProviderService` is the module's service.
---
## 4. Use Module
To use your File Module Provider, add it to the `providers` array of the File Module in `medusa-config.ts`:
<Note>
The File Module accepts one provider only.
</Note>
```ts title="medusa-config.ts"
module.exports = defineConfig({
// ...
modules: [
{
resolve: "@medusajs/medusa/file",
options: {
providers: [
// default provider
{
resolve: "@medusajs/medusa/file-local",
id: "local",
},
{
// if module provider is in a plugin, use `plugin-name/providers/my-file`
resolve: "./src/modules/my-file",
id: "my-file",
options: {
// provider options...
},
},
],
},
},
]
})
```
---
## 5. Test it Out
To test out your file provider, use the Medusa Admin or the [Upload API route](https://docs.medusajs.com/v2/api/admin#uploads_postuploads) to upload a file.