node-formidable / formidable

The most used, flexible, fast and streaming parser for multipart form data. Supports uploading to serverless environments, AWS S3, Azure, GCP or the filesystem. Used in production.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.