Uploading to s3 using nuxt 3: __dirname is not defined
helixion opened this issue · comments
Using the example, but I keep getting the same error. In the example there is no reference to setting __dirname.
I'm using:
node v16.16.0
Nuxt 3.2.0
Nitro 2.2.0
Formidable ^2.1.1
My composable:
import formidable, {
File,
Files,
Part,
Fields,
Options,
errors as FormidableErrors,
} from "formidable";
import path from "node:path";
import { PassThrough } from "node:stream";
import AWS from "aws-sdk";
import isUndefined from "lodash/isUndefined";
import { nanoid } from "nanoid";
interface FileUploadOptions
extends Omit<Options, "filter" | "fileWriteStreamHandler"> {
dest?: string;
overwrite?: boolean;
overWriteFilename?: string;
bucket: string;
}
const s3Client = new AWS.S3({
credentials: {
},
});
const isValidFile = (file: Part) => {
const types = /jpe?g|png|webp|svg|gif/;
const ext = types.test(
path.extname(file.originalFilename as string).toLowerCase()
);
const mimetype = types.test(file.mimetype as string);
if (mimetype && ext) return true;
return false;
};
export const useFiles = (
files: any,
opts: FileUploadOptions
): Promise<{ fields: Fields; files: Files }> => {
if (isUndefined(opts.bucket)) {
throw new Error(
"'opts.bucket' is required. Please input your AWS S3 bucket name."
);
}
const dest = opts?.dest ? opts.dest : "uploads/";
const overwrite = opts?.dest ? opts.overwrite : false;
const maxFields = opts.maxFields || 10;
const maxFiles = opts.maxFiles || 10;
const maxFileSize = opts.maxFileSize || 120000;
const maxTotalFileSize = 1 * 1000 * 1000; //1mb total file size.
let s3Data: AWS.S3.ManagedUpload.SendData[] = [];
const uploadStream = (file: File) => {
const pass = new PassThrough();
s3Client.upload(
{
Bucket: opts.bucket,
Key: file.newFilename,
Body: pass,
},
(err, data) => {
console.log(err, data);
}
);
return pass;
};
const form = formidable({
fileWriteStreamHandler: uploadStream as any,
maxFields,
maxFiles,
maxFileSize,
allowEmptyFiles: false,
filter: isValidFile,
filename: (name, ext, part) => {
const _name = !overwrite
? dest + nanoid() + ext
: dest + opts?.overWriteFilename
? (opts!.overWriteFilename as string)
: name + ext;
return _name;
},
});
return new Promise((resolve, reject) => {
form.parse(files, (err: typeof FormidableErrors, fields, files) => {
console.log({ fields, files });
if (err) reject(err);
return resolve({ fields, files });
});
});
};
my route:
import { useFiles } from "~~/server/services/useFiles";
import authenticatedEventHandler from "~~/server/utils/authenticatedEventHandler";
export default authenticatedEventHandler(null, null, async (event, user) => {
const identifier = `uploads/${user.username}-${user.id.substring(
user.id.length,
user.id.length - 4
)}`;
console.log("req", event.node.req);
try {
const { files, fields } = await useFiles(event.node.req, {
bucket: "lobucket",
dest: identifier,
});
console.log({ files, fields });
return { status: "ok" };
} catch (err) {
console.log(err);
return createError({
statusCode: 419,
statusMessage: "Encountered an error.",
});
}
});
the error:
ReferenceError: __dirname is not defined 10:40:20
at file:///home/<folder>/Projects/workplaces/nuxtApps/nuxt-bko/.nuxt/dev/index.mjs:2470:42
at Array.forEach (<anonymous>)
at new IncomingForm (file:///home/<folder>/Projects/workplaces/nuxtApps/nuxt-bko/.nuxt/dev/index.mjs:2467:33)
at formidable (file:///home/<folder>/Projects/workplaces/nuxtApps/nuxt-bko/.nuxt/dev/index.mjs:3462:33)
at useFiles (file:///home/<folder>/Projects/workplaces/nuxtApps/nuxt-bko/.nuxt/dev/index.mjs:3532:16)
at file:///home/<folder>/Projects/workplaces/nuxtApps/nuxt-bko/.nuxt/dev/index.mjs:3561:37
at file:///home/<folder>/Projects/workplaces/nuxtApps/nuxt-bko/.nuxt/dev/index.mjs:514:14
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Object.handler (file:///home/<folder>/Projects/workplaces/nuxtApps/nuxt-bko/node_modules/h3/dist/index.mjs:990:19)
at async Server.toNodeHandle (file:///home/<folder>/Projects/workplaces/nuxtApps/nuxt-bko/node_modules/h3/dist/index.mjs:1065:7)
The solution was to use 3.0.