Skip to content

Commit

Permalink
Custom upload provider to fix the EXDEV error.
Browse files Browse the repository at this point in the history
  • Loading branch information
mitkonikov committed Feb 9, 2024
1 parent 284277a commit 7faee8c
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 27 deletions.
42 changes: 42 additions & 0 deletions backend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"eslint-plugin-prettier": "^5.0.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"fs-extra": "^11.2.0",
"prettier": "^3.1.0",
"tslib": "^2.5.0",
"typescript": "^5.0.4"
Expand Down
29 changes: 29 additions & 0 deletions backend/src/admin/upload-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import fs from 'fs';
import path from 'path';

import { move } from 'fs-extra';
import { UploadedFile } from 'adminjs';
import { BaseProvider } from '@adminjs/upload';

export default class UploadProvider extends BaseProvider {
// * Fixed this method because original does rename instead of move and it doesn't work with docker volume
public async upload(file: UploadedFile, key: string): Promise<any> {
// adjusting file path according to OS
const filePath = process.platform === 'win32' ? this.path(key) : this.path(key).slice(1);
await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
await move(file.path, filePath, { overwrite: true });
}

public async delete(key: string, bucket: string): Promise<any> {
// adjusting file path according to OS
await fs.promises.unlink(process.platform === 'win32' ? this.path(key, bucket) : this.path(key, bucket).slice(1));
}

// eslint-disable-next-line class-methods-use-this
public path(key: string, bucket?: string): string {
// Windows doesn't requires the '/' in path, while UNIX system does
return process.platform === 'win32'
? `${path.join(bucket || this.bucket, key)}`
: `/${path.join(bucket || this.bucket, key)}`;
}
}
14 changes: 5 additions & 9 deletions backend/src/resources/files.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import uploadFeature, { LocalUploadOptions } from '@adminjs/upload';
import uploadFeature from '@adminjs/upload';

import { componentLoader } from '../admin/component-loader.js';
import File from '../models/file.js';

const localProvider: LocalUploadOptions = {
bucket: 'public/files',
opts: {
baseUrl: '/files',
},
};
import UploadProvider from '../admin/upload-provider.js';

export const files = {
resource: File,
Expand All @@ -35,7 +29,9 @@ export const files = {
features: [
uploadFeature({
componentLoader,
provider: { local: localProvider },
provider: new UploadProvider('public/files', {
baseUrl: '/files',
}),
validation: {
mimeTypes: [
'video/mp4',
Expand Down
14 changes: 5 additions & 9 deletions backend/src/resources/thumbnail.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
import uploadFeature, { LocalUploadOptions } from '@adminjs/upload';
import uploadFeature from '@adminjs/upload';

import { componentLoader } from '../admin/component-loader.js';
import Thumbnail from '../models/thumbnail.js';

const localProvider: LocalUploadOptions = {
bucket: 'public/thumbs',
opts: {
baseUrl: '/thumbs',
},
};
import UploadProvider from '../admin/upload-provider.js';

export const thumbnails = {
resource: Thumbnail,
options: {},
features: [
uploadFeature({
componentLoader,
provider: { local: localProvider },
provider: new UploadProvider('public/thumbs', {
baseUrl: '/thumbs',
}),
validation: {
mimeTypes: [
'image/jpeg',
Expand Down
14 changes: 5 additions & 9 deletions backend/src/resources/trailer.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import uploadFeature, { LocalUploadOptions } from '@adminjs/upload';
import uploadFeature from '@adminjs/upload';

import { componentLoader } from '../admin/component-loader.js';
import Trailer from '../models/trailer.js';

const localProvider: LocalUploadOptions = {
bucket: 'public/trailers',
opts: {
baseUrl: '/trailers',
},
};
import UploadProvider from '../admin/upload-provider.js';

export const trailers = {
resource: Trailer,
Expand All @@ -26,7 +20,9 @@ export const trailers = {
features: [
uploadFeature({
componentLoader,
provider: { local: localProvider },
provider: new UploadProvider('public/trailers', {
baseUrl: '/trailers',
}),
validation: {
mimeTypes: [
'video/mp4',
Expand Down

0 comments on commit 7faee8c

Please sign in to comment.