foal icon indicating copy to clipboard operation
foal copied to clipboard

Simplify `ValidateMultipartFormDataBody` and support optional fields

Open LoicPoullain opened this issue 2 years ago • 1 comments

Issue

  • The hooks does not support optional fields (issue: #1008).
  • There is no error returned to the client when multiple files are uploaded whereas we expect a single one.
  • The parameters passed to the hook are verbose even when uploading a simple file.
  • We have a very large number of nested objects to access the files and fields in ctx: ctx.request.body.fields.name and ctx.request.body.files.avatar.
  • The typing is not great in the controller method body because we have to "cast" variables: ctx.request.body.files.avatar as File|undefined.
  • The name ValidateMultipartFormDataBody is not meaningful to someone reading the code: it shows the type of requests that are made but does not describe the really purpose of the hook.

New features

  • Context.files is an instance of FileList which is a class to list Files(s). It has mainly two methods: ctx.files.push('avatar', file') and ctx.files.get('avatar') which always returns an array of Files(s) (that might be empty).
  • New error MULTIPLE_FILES_NOT_ALLOWED (the value files.x is not replaced anymore).
  • The interface of the hook has changed and accepts optional fields:
    @ParseAndValidateFiles(
      {
        profile: { required: true }
      },
      {
        type: 'object',
        properties: {
          description: { type: 'string' }
        },
        required: ['description'],
        additionalProperties: false
      }
    )
    
  • ctx.files which is properly typed

Breaking changes

  • ValidateMultipartFormDataBody is renamed ParseAndValidateFiles
  • Code is compiled to es2019 which are supported by Node 14 and 16.
  • File is exported from @foal/core and not @foal/storage anymore.
  • ctx.request.body.fields becomes ctx.request.body.
  • ctx.request.body.files.avatar as File becomes ctx.files.get('avatar')[0]
  • ctx.request.body.files.avatars as File[] becomes ctx.files.get('avatars')
  • The parameters of the hook have changed.
  • Context.state and Context.request are readonly: they cannot be re-assigned.
  • Previously saveTo: '' was regarded as an upload with buffer.

Dependencies

Checklist

  • [x] Add/update/check docs (code comments and docs/ folder).
  • [x] Add/update/check tests.
  • [x] Update/check the cli generators.

LoicPoullain avatar Feb 26 '22 08:02 LoicPoullain

Codecov Report

Merging #1048 (dad85c6) into v3-0-0 (120a7e0) will increase coverage by 0.01%. The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           v3-0-0    #1048      +/-   ##
==========================================
+ Coverage   98.84%   98.86%   +0.01%     
==========================================
  Files          92       95       +3     
  Lines        1736     1763      +27     
  Branches      418      422       +4     
==========================================
+ Hits         1716     1743      +27     
  Misses         20       20              
Impacted Files Coverage Δ
packages/core/src/common/file/file.ts 100.00% <ø> (ø)
packages/core/src/index.ts 0.00% <ø> (ø)
packages/core/src/common/file/file-list.ts 100.00% <100.00%> (ø)
packages/core/src/common/file/index.ts 100.00% <100.00%> (ø)
packages/core/src/common/index.ts 100.00% <100.00%> (ø)
packages/core/src/core/http/context.ts 100.00% <100.00%> (ø)

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

codecov-commenter avatar Feb 26 '22 09:02 codecov-commenter