Full Code of expressjs/connect-multiparty for AI

master 7c50f097dcc7 cached
11 files
17.2 KB
5.3k tokens
3 symbols
1 requests
Download .txt
Repository: expressjs/connect-multiparty
Branch: master
Commit: 7c50f097dcc7
Files: 11
Total size: 17.2 KB

Directory structure:
gitextract_6_3s62n3/

├── .editorconfig
├── .eslintignore
├── .eslintrc.yml
├── .gitignore
├── .travis.yml
├── HISTORY.md
├── LICENSE
├── README.md
├── index.js
├── package.json
└── test/
    └── multipart.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .editorconfig
================================================
# http://editorconfig.org
root = true

[*]
charset = utf-8
insert_final_newline = true
trim_trailing_whitespace = true

[{*.js,*.json,*.yml}]
indent_size = 2
indent_style = space


================================================
FILE: .eslintignore
================================================
coverage
node_modules


================================================
FILE: .eslintrc.yml
================================================
rules:
  eol-last: error
  indent: ["error", 2, { "SwitchCase": 1 }]
  no-trailing-spaces: error


================================================
FILE: .gitignore
================================================
.nyc_output/
coverage/
node_modules/
npm-debug.log
package-lock.json


================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
  - "0.10"
  - "4.9"
  - "6.17"
  - "8.16"
  - "10.16"
  - "12.11"
sudo: false
cache:
  directories:
    - node_modules
before_install:
  # Configure npm
  - |
    # Skip updating shrinkwrap / lock
    npm config set shrinkwrap false
  # Setup Node.js version-specific dependencies
  - |
    # eslint for linting
    # - remove for Node.js < 8
    if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 8 ]]; then
      npm rm --save-dev eslint
    fi
  - |
    # mocha for testing
    # - use 3.x for Node.js < 4
    # - use 5.x for Node.js < 6
    if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then
      npm install --save-dev mocha@3.5.3
    elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then
      npm install --save-dev mocha@5.2.0
    fi
  - |
    # nyc for coverage
    # - use 10.x for Node.js < 4
    # - use 11.x for Node.js < 6
    if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then
      npm install --save-dev nyc@10.3.2
    elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then
      npm install --save-dev nyc@11.9.0
    fi
  - |
    # supertest for http calls
    # - use 2.0.0 for Node.js < 4
    # - use 3.4.2 for Node.js < 6
    if [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 4 ]]; then
      npm install --save-dev supertest@2.0.0
    elif [[ "$(cut -d. -f1 <<< "$TRAVIS_NODE_VERSION")" -lt 6 ]]; then
      npm install --save-dev supertest@3.4.2
    fi
  # Update Node.js modules
  - |
    # Prune & rebuild node_modules
    if [[ -d node_modules ]]; then
      npm prune
      npm rebuild
    fi

script:
  - |
    # Run test script
    npm run-script test-ci
  - |
    # Run linting
    if npm -ps ls eslint | grep -q eslint; then
      npm run-script lint
    fi
after_script:
  - |
    # Upload coverage to coveralls, if exists
    if [[ -d .nyc_output ]]; then
      npm install --save-dev coveralls@2
      nyc report --reporter=text-lcov | coveralls
    fi


================================================
FILE: HISTORY.md
================================================
unreleased
==========

  * deps: http-errors@~1.7.3
     - Fix error creating objects in some environments
     - deps: inherits@2.0.4
     - deps: setprototypeof@1.1.1
  * deps: qs@~6.7.0
    - Fix parsing array brackets after index
  * deps: safe-buffer@5.2.0
  * deps: type-is@~1.6.18
    - deps: mime-types@~2.1.24
    - perf: prevent internal `throw` on invalid type

2.2.0 / 2018-09-14
==================

  * Fix masking `multiparty` errors as 400
  * deps: multiparty@~4.2.1
    - Use http-errors for raised errors
    - Use uid-safe module to for temp file names
    - Update to fd-slicer 1.1.0
    - perf: remove parameter reassignment

2.1.1 / 2018-06-22
==================

  * deps: multiparty@~4.1.4
    - Enable strict mode
    - Fix file extension filtering stopping on certain whitespace characters
    - Use safe-buffer for improved API safety
  * deps: qs@~6.5.2
  * deps: type-is@~1.6.16
    - deps: mime-types@~2.1.18

2.1.0 / 2017-10-19
==================

  * deps: multiparty@~4.1.3
    - Use `os.tmpdir()` instead of `os.tmpDir()`
    - deps: fd-slicer@~1.0.1
  * deps: qs@~6.5.1
    - Fix array parsing from skipping empty values
    - Fix compacting of nested sparse arrays
    - Fix parsing & compacting very deep objects
  * deps: type-is@~1.6.15
    - Fix type error when given invalid type to match against
    - deps: mime-types@~2.1.15
  * perf: enable strict mode

2.0.0 / 2015-07-13
==================

  * Requires Node.js >= 0.10.0
  * deps: multiparty@~4.1.2
  * deps: on-finished@~2.3.0
  * deps: qs@~4.0.0
  * deps: type-is@~1.6.4

1.2.5 / 2014-10-14
==================

  * Update qs to 2.2.4
  * Update type-is to 1.5.2

1.2.4 / 2014-08-29
==================

  * Update qs to 2.2.2

1.2.3 / 2014-08-28
==================

  * Update qs to 2.2.1

1.2.2 / 2014-08-27
==================

  * Update qs to 2.2.0

1.2.1 / 2014-08-07
==================

  * Update multiparty to 3.3.2
  * Update qs to 1.2.0

1.2.0 / 2014-08-06
==================

  * Update multiparty to 3.3.1
  * Update qs to 1.1.0

1.1.0 / 2014-07-03
==================

  * Update multiparty to 3.3.0
  * Use type-is to check Content-Type

1.0.6 / 2014-07-03
==================

  * Fix callback hang in node.js 0.8 on errors

1.0.5 / 2014-06-01
==================

  * Update multiparty to 3.2.8

1.0.4 / 2014-05-26
==================

  * Fix error causing response to hang
  * Update multiparty to 3.2.6

1.0.3 / 2014-01-20
==================

  * Update multiparty to 3.2

1.0.2 / 2014-01-17
==================

  * Update multiparty to 3.1

1.0.1 / 2013-10-25
==================

  * Update multiparty to 3.0

1.0.0 / 2013-10-25
==================

  * revive


================================================
FILE: LICENSE
================================================
(The MIT License)

Copyright (c) 2010 Sencha Inc.
Copyright (c) 2011 TJ Holowaychuk
Copyright (c) 2013 Andrew Kelley

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README.md
================================================
> [!CAUTION]
> **This repository is archived and no longer actively maintained.**
>
> We are no longer accepting issues, feature requests, or pull requests.
> For additional support or questions, please visit the [Express.js Discussions page](https://github.com/expressjs/express/discussions).

# connect-multiparty

[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Build Status][travis-image]][travis-url]
[![Test Coverage][coveralls-image]][coveralls-url]

[connect](https://github.com/senchalabs/connect/) middleware for
[multiparty](https://github.com/andrewrk/node-multiparty/).

I actually recommend against using this module. It's cleaner to use the
multiparty API directly.

This middleware will create temp files on your server and never clean them
up. Thus you should not add this middleware to all routes; only to the ones
in which you want to accept uploads. And in these endpoints, be sure to
delete all temp files, even the ones that you don't use.

## Usage

```js
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();
app.post('/upload', multipartMiddleware, function(req, resp) {
  console.log(req.body, req.files);
  // don't forget to delete all req.files when done
});
```

If you pass options to `multipart()`, they are passed directly into
multiparty.

## License

[MIT](LICENSE)

[coveralls-image]: https://img.shields.io/coveralls/expressjs/connect-multiparty/master.svg
[coveralls-url]: https://coveralls.io/r/expressjs/connect-multiparty?branch=master
[downloads-image]: https://img.shields.io/npm/dm/connect-multiparty.svg
[downloads-url]: https://npmjs.org/package/connect-multiparty
[npm-image]: https://img.shields.io/npm/v/connect-multiparty.svg
[npm-url]: https://npmjs.org/package/connect-multiparty
[travis-image]: https://img.shields.io/travis/expressjs/connect-multiparty/master.svg
[travis-url]: https://travis-ci.org/expressjs/connect-multiparty


================================================
FILE: index.js
================================================
/*!
 * connect-multiparty
 * Copyright(c) 2010 Sencha Inc.
 * Copyright(c) 2011 TJ Holowaychuk
 * Copyright(c) 2013 Andrew Kelley
 * MIT Licensed
 */

'use strict'

/**
 * Module dependencies.
 * @private
 */

var createError = require('http-errors')
var multiparty = require('multiparty');
var onFinished = require('on-finished');
var qs = require('qs');
var typeis = require('type-is');

/**
 * Module exports.
 * @public
 */

module.exports = multipart

/**
 * Parse multipart/form-data request bodies, providing the parsed
 * object as `req.body` and `req.files`.
 *
 * The options passed are merged with [multiparty](https://github.com/pillarjs/multiparty)'s
 * `Form` object, allowing you to configure the upload directory,
 * size limits, etc. For example if you wish to change the upload
 * dir do the following:
 *
 *     app.use(multipart({ uploadDir: path }))
 *
 * @param {Object} options
 * @return {Function}
 * @public
 */

function multipart (options) {
  options = options || {};

  return function multipart(req, res, next) {
    if (req._body) return next();
    req.body = req.body || {};
    req.files = req.files || {};

    // ignore GET
    if ('GET' === req.method || 'HEAD' === req.method) return next();

    // check Content-Type
    if (!typeis(req, 'multipart/form-data')) return next();

    // flag as parsed
    req._body = true;

    // parse
    var form = new multiparty.Form(options);
    var data = {};
    var files = {};
    var done = false;

    function ondata(name, val, data){
      if (Array.isArray(data[name])) {
        data[name].push(val);
      } else if (data[name]) {
        data[name] = [data[name], val];
      } else {
        data[name] = val;
      }
    }

    form.on('field', function(name, val){
      ondata(name, val, data);
    });

    form.on('file', function(name, val){
      val.name = val.originalFilename;
      val.type = val.headers['content-type'] || null;
      ondata(name, val, files);
    });

    form.on('error', function(err){
      if (done) return;

      done = true;

      // set status code on error
      var error = createError(400, err)

      if (!req.readable) return next(error)

      // read off entire request
      req.resume();
      onFinished(req, function(){
        next(error)
      });
    });

    form.on('close', function() {
      if (done) return;

      done = true;

      // expand names with qs & assign
      req.body = qs.parse(data, { allowDots: true })
      req.files = qs.parse(files, { allowDots: true })

      next()
    });

    form.parse(req);
  }
};


================================================
FILE: package.json
================================================
{
  "name": "connect-multiparty",
  "version": "2.2.0",
  "description": "multipart parsing middleware for connect using multiparty",
  "author": "Andrew Kelley <superjoe30@gmail.com>",
  "contributors": [
    "Douglas Christopher Wilson <doug@somethingdoug.com>"
  ],
  "license": "MIT",
  "repository": "expressjs/connect-multiparty",
  "dependencies": {
    "http-errors": "~1.7.3",
    "multiparty": "~4.2.1",
    "on-finished": "~2.3.0",
    "qs": "~6.7.0",
    "type-is": "~1.6.18"
  },
  "engines": {
    "node": ">=0.10.0"
  },
  "devDependencies": {
    "connect": "3.7.0",
    "deep-equal": "1.0.1",
    "eslint": "6.5.1",
    "mocha": "6.2.1",
    "nyc": "14.1.1",
    "safe-buffer": "5.2.0",
    "supertest": "4.0.2"
  },
  "files": [
    "HISTORY.md",
    "LICENSE",
    "README.md",
    "index.js"
  ],
  "scripts": {
    "lint": "eslint .",
    "test": "mocha --reporter spec",
    "test-ci": "nyc --reporter=text npm test",
    "test-cov": "nyc --reporter=html --reporter=text npm test"
  }
}


================================================
FILE: test/multipart.js
================================================

process.env.NODE_ENV = 'test';

var Buffer = require('safe-buffer').Buffer
var connect = require('connect');
var deepEqual = require('deep-equal')
var multipart = require('..');
var request = require('supertest');

describe('multipart()', function(){
  it('should ignore GET', function(done){
    request(createServer())
      .get('/body')
      .field('user', 'Tobi')
      .expect(200, {}, done)
  })

  describe('with multipart/form-data', function(){
    it('should populate req.body', function(done){
      request(createServer())
        .post('/body')
        .field('user', 'Tobi')
        .expect(200, { user: 'Tobi' }, done)
    })

    it('should handle duplicated middleware', function (done) {
      var app = connect()
        .use(multipart())
        .use(multipart())
        .use(function (req, res) {
          res.setHeader('Content-Type', 'application/json; charset=utf-8')
          res.end(JSON.stringify(req.body))
        })

      request(app)
        .post('/body')
        .field('user', 'Tobi')
        .expect(200, { user: 'Tobi' }, done)
    })

    it('should support files', function(done){
      request(createServer())
        .post('/files')
        .attach('text', Buffer.from('some text here'), 'foo.txt')
        .expect(200)
        .expect(shouldDeepIncludeInBody({
          text: {
            name: 'foo.txt',
            originalFilename: 'foo.txt',
            size: 14,
            type: 'text/plain'
          }
        }))
        .end(done)
    })

    it('should work with multiple fields', function(done){
      request(createServer())
        .post('/body')
        .field('user', 'Tobi')
        .field('age', '1')
        .expect(200, { user: 'Tobi', age: '1' }, done)
    })

    it('should handle duplicated fields', function (done) {
      request(createServer())
        .post('/body')
        .field('user', 'Tobi')
        .field('user', 'Loki')
        .field('user', 'Poki')
        .expect(200, { user: [ 'Tobi', 'Loki', 'Poki' ] }, done)
    })

    it('should support nesting', function(done){
      request(createServer())
        .post('/body')
        .field('user[name][first]', 'tobi')
        .field('user[name][last]', 'holowaychuk')
        .field('user[age]', '1')
        .field('species', 'ferret')
        .expect(200, {
          species: 'ferret',
          user: {
            age: '1',
            name: { first: 'tobi', last: 'holowaychuk' }
          }
        }, done)
    })

    it('should support multiple files of the same name', function(done){
      request(createServer())
        .post('/files')
        .attach('text', Buffer.from('some text here'), 'foo.txt')
        .attach('text', Buffer.from('some more text stuff'), 'bar.txt')
        .expect(200)
        .expect(shouldDeepIncludeInBody({
          text: [
            { name: 'foo.txt' },
            { name: 'bar.txt' }
          ]
        }))
        .end(done)
    })

    it('should support nested files', function(done){
      request(createServer())
        .post('/files')
        .attach('docs[foo]', Buffer.from('some text here'), 'foo.txt')
        .attach('docs[bar]', Buffer.from('some more text stuff'), 'bar.txt')
        .expect(200)
        .expect(shouldDeepIncludeInBody({
          docs: {
            foo: { name: 'foo.txt' },
            bar: { name: 'bar.txt' }
          }
        }))
        .end(done)
    })

    it('should next(err) on multipart failure', function(done){
      var app = createServer()

      var test = request(app).post('/')
      test.set('Content-Type', 'multipart/form-data; boundary=foo');
      test.write('--foo\r\n');
      test.write('Content-filename="foo.txt"\r\n');
      test.write('\r\n');
      test.write('some text here');
      test.write('Content-Disposition: form-data; name="text"; filename="bar.txt"\r\n');
      test.write('\r\n');
      test.write('some more text stuff');
      test.write('\r\n--foo--');
      test.expect(400, 'BadRequestError: Expected alphabetic character, received 61', done)
    })

    it('should not hang request on failure', function(done){
      var app = createServer()
      var buf = Buffer.alloc(1024 * 10, '.')

      var test = request(app).post('/')
      test.set('Content-Type', 'multipart/form-data; boundary=foo');
      test.write('--foo\r\n');
      test.write('Content-filename="foo.txt"\r\n');
      test.write('\r\n');
      test.write('some text here');
      test.write('Content-Disposition: form-data; name="text"; filename="bar.txt"\r\n');
      test.write('\r\n');
      test.write('some more text stuff');
      test.write('\r\n--foo--');
      test.write(buf)
      test.write(buf)
      test.write(buf)
      test.expect(400, 'BadRequestError: Expected alphabetic character, received 61', done)
    })

    it('should default req.files to {}', function(done){
      request(createServer())
        .post('/body')
        .expect(200, {}, done)
    })

    it('should return 413 on maxFilesSize exceeded', function (done) {
      var max = Math.pow(2, 9)

      request(createServer({ maxFilesSize: max }))
        .post('/files')
        .field('user[name]', 'Tobi')
        .attach('text', Buffer.alloc(max + 1, 'x'), 'foo.txt')
        .expect(413, done)
    })
  })
})

function createServer (opts) {
  var app = connect()

  app.use(multipart(opts))

  app.use('/body', function (req, res) {
    res.setHeader('Content-Type', 'application/json; charset=utf-8')
    res.end(JSON.stringify(req.body))
  })

  app.use('/files', function (req, res) {
    res.setHeader('Content-Type', 'application/json; charset=utf-8')
    res.end(JSON.stringify(req.files))
  })

  app.use(function (err, req, res, next) {
    res.statusCode = err.statusCode || err.status || 500
    res.end(err.name + ': ' + err.message)
  })

  return app
}

function shouldDeepIncludeInBody (obj) {
  return function (res) {
    deepEqual(res.body, obj)
  }
}
Download .txt
gitextract_6_3s62n3/

├── .editorconfig
├── .eslintignore
├── .eslintrc.yml
├── .gitignore
├── .travis.yml
├── HISTORY.md
├── LICENSE
├── README.md
├── index.js
├── package.json
└── test/
    └── multipart.js
Download .txt
SYMBOL INDEX (3 symbols across 2 files)

FILE: index.js
  function multipart (line 45) | function multipart (options) {

FILE: test/multipart.js
  function createServer (line 174) | function createServer (opts) {
  function shouldDeepIncludeInBody (line 197) | function shouldDeepIncludeInBody (obj) {
Condensed preview — 11 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (19K chars).
[
  {
    "path": ".editorconfig",
    "chars": 179,
    "preview": "# http://editorconfig.org\nroot = true\n\n[*]\ncharset = utf-8\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n"
  },
  {
    "path": ".eslintignore",
    "chars": 22,
    "preview": "coverage\nnode_modules\n"
  },
  {
    "path": ".eslintrc.yml",
    "chars": 97,
    "preview": "rules:\n  eol-last: error\n  indent: [\"error\", 2, { \"SwitchCase\": 1 }]\n  no-trailing-spaces: error\n"
  },
  {
    "path": ".gitignore",
    "chars": 69,
    "preview": ".nyc_output/\ncoverage/\nnode_modules/\nnpm-debug.log\npackage-lock.json\n"
  },
  {
    "path": ".travis.yml",
    "chars": 1976,
    "preview": "language: node_js\nnode_js:\n  - \"0.10\"\n  - \"4.9\"\n  - \"6.17\"\n  - \"8.16\"\n  - \"10.16\"\n  - \"12.11\"\nsudo: false\ncache:\n  direc"
  },
  {
    "path": "HISTORY.md",
    "chars": 2674,
    "preview": "unreleased\n==========\n\n  * deps: http-errors@~1.7.3\n     - Fix error creating objects in some environments\n     - deps: "
  },
  {
    "path": "LICENSE",
    "chars": 1141,
    "preview": "(The MIT License)\n\nCopyright (c) 2010 Sencha Inc.\nCopyright (c) 2011 TJ Holowaychuk\nCopyright (c) 2013 Andrew Kelley\n\nPe"
  },
  {
    "path": "README.md",
    "chars": 1958,
    "preview": "> [!CAUTION]\n> **This repository is archived and no longer actively maintained.**\n>\n> We are no longer accepting issues,"
  },
  {
    "path": "index.js",
    "chars": 2579,
    "preview": "/*!\n * connect-multiparty\n * Copyright(c) 2010 Sencha Inc.\n * Copyright(c) 2011 TJ Holowaychuk\n * Copyright(c) 2013 Andr"
  },
  {
    "path": "package.json",
    "chars": 1009,
    "preview": "{\n  \"name\": \"connect-multiparty\",\n  \"version\": \"2.2.0\",\n  \"description\": \"multipart parsing middleware for connect using"
  },
  {
    "path": "test/multipart.js",
    "chars": 5906,
    "preview": "\nprocess.env.NODE_ENV = 'test';\n\nvar Buffer = require('safe-buffer').Buffer\nvar connect = require('connect');\nvar deepEq"
  }
]

About this extraction

This page contains the full source code of the expressjs/connect-multiparty GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 11 files (17.2 KB), approximately 5.3k tokens, and a symbol index with 3 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!