-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
EXDEV: cross-device link not permitted, rename 'C:/.../Temp/upload_xxxx' -> 'D:/projectPath/filename.png' #42
Comments
I think it's just a windows issue where it doesn't allow you to move files from one partition to another |
I have the same issue when using docker |
Same problem using ArchLinux. |
I have the same issue in docker. Anyone solved this? |
i have same problem |
Solution: import fs, { existsSync } from "fs";
import { move } from "fs-extra";
import path from "path";
import { UploadedFile } from "adminjs";
import { BaseProvider } from "@adminjs/upload";
import { UPLOADS_DIR } from "../env";
export default class UploadProvider extends BaseProvider {
constructor() {
super(UPLOADS_DIR);
if (!existsSync(UPLOADS_DIR)) {
throw new Error(`directory: "${UPLOADS_DIR}" does not exists. Create it before running LocalAdapter`);
}
}
// * 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> {
const filePath = process.platform === "win32" ? this.path(key) : this.path(key).slice(1); // adjusting file path according to OS
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> {
await fs.promises.unlink(process.platform === "win32" ? this.path(key, bucket) : this.path(key, bucket).slice(1)); // adjusting file path according to OS
}
// 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)}`;
}
} And I connect it to the resource like this: uploadFeature({
provider: new UploadProvider(),
validation: {
mimeTypes: ["image/jpeg", "image/png"],
},
}) It works fine! |
it works on windows provided that the project is on the same partition as the windows installation, and on linux also it works provided you have the right admin rights and the right distribution: example the code does not work on heroku but works fine on aws ec2 |
The original |
Addition: |
Can I also use this custom uploader for cloudinary? |
@etomarat solution might be even simplified to the shape: import path from 'path';
import fsExtra from 'fs-extra';
import {LocalProvider} from '@adminjs/upload';
import {UploadedFile} from 'adminjs';
class LocalProvider2 extends LocalProvider {
public async upload(file: UploadedFile, key: string): Promise<any> {
const filePath = process.platform === 'win32' ? this.path(key) : this.path(key).slice(1); // adjusting file path according to OS
await fsExtra.mkdir(path.dirname(filePath), {recursive: true});
await fsExtra.move(file.path, filePath, {overwrite: true});
}
} |
Does anyone know about such a problem:
It appeared after replacing the original UploadProvider with the one suggested by @etomarat. I use PostgreSQL with ExpressJS |
Description
I use Sequelize as Orm and postgresql as db. I wanna to store images in json. When I'm trying to upload a file to a resource, it gives an error to the console
Error: EXDEV: cross-device link not permitted, rename 'C:/.../Temp/upload_xxxx' -> 'D:/projectPath/filename.png'
and doesnt save anything to images field in db. It saves random file called upload_${somenumbers} to Temp folder, although I specified folder by
{ bucket: path.join(__dirname, '../public') }
adminRouter.js file
server.js
The text was updated successfully, but these errors were encountered: