How to Properly Pass the Filename in NestJS?

I’ve encountered an issue with the encoding of file names. The Cyrillic characters are getting lost.

I have an Expo application. I can send files when creating a certain item (see the function below):

export const updateTaskApi = async (
  id: string,
  taskData: TTask,
  files: TDataFilePicker[] | null,
) => {
  const headers = await createHeaders();
  headers['Content-Type'] = 'multipart/form-data';
  console.log('headers', headers);
  const formData = new FormData();
  formData.append('taskData', JSON.stringify(taskData));
  if (files) {
    files.forEach((file) => {
      console.log(file);
      formData.append(
        'files',
        {
          uri: file.filePickerUri,
          type: file.filePickerType,
          name: file.filePickerName,
          fileName: file.filePickerName,
        } as any,
      );
    });
  }
  console.log(formData);
  return await axios.put(`${basicUrl}/tasks`, formData, {
    withCredentials: true,
    headers,
  });
};

The files are sent to the backend, but when I decompose them there, instead of names like Аватар.jpg, I get just .jpg and sometimes with empty characters in front.

Here’s the controller:

@Put()
@HttpCode(HttpStatus.OK)
@UseInterceptors(FilesInterceptor('files'))
async updateTask(
  @Body() body: TaskFormData,
  @Req() request: Request,
  @UploadedFiles() files?: Array<Express.Multer.File>,
) {
  await verifyAuthorization(request);
  console.log('Request headers:', request.headers);
  if (!body.taskData) {
    throw new BadRequestException('Task object data is missing');
  }
  console.log('files from general', files);
  const updateTask = plainToInstance(TaskDto, JSON.parse(body.taskData));

  await this.tasksService.validateTaskPreparationData(updateTask);

  return await this.tasksService.updateTask(
    updateTask._id,
    updateTask,
    files,
  );
}

In the array of files, I see something like this:


files from general [
  {
    fieldname: 'files',
    originalname: '.jpg',
    encoding: '7bit',
    mimetype: 'image/jpeg',
    buffer: <Buffer ff d8 ff e2 0b f8 49 43 43 5f 50 52 4f 46 49 4c 45 00 01 01 00 00 0b e8 00 00 00 00 02 00 00 00 6d 6e 74 72 52 47 42 20 58 59 5a 20 07 d9 00 03 00 1b ... 72888 more bytes>,
    size: 72938
  }
]  

It turns out that the originalname field comes with an error and has lost the Cyrillic text. Meanwhile, globally, the only things that could affect the request before it reaches the controller are validation (ValidationPipe) and cookieParser. Nothing else. I’ve racked my brain and can’t figure out what’s happening with the encoding and where it disappears.

I’ve already checked all the documentation, tried to find similar issues from other people, and changed the ways of sending files several times. Nothing helped.