diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 510731c1..00000000 --- a/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/* -index.d.ts diff --git a/.eslintrc b/.eslintrc index 63de4775..5667dbe7 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,10 +1,11 @@ { + "root": true, + + "extends": "@ljharb", + "rules": { - "indent": [2, 2, {"SwitchCase": 1}], - "quotes": [2, "single"], - "linebreak-style": [2, "unix"], - "semi": [2, "always"], - "curly": [2, "multi-line"], + "indent": [2, 2, {"SwitchCase": 2}], + // "curly": [2, "multi-line"], "handle-callback-err": [2, "^err"], "valid-jsdoc": [2, { "requireReturn": false, @@ -19,25 +20,35 @@ } }], "no-redeclare": [2, { "builtinGlobals": true }], - "no-shadow": [2, { "builtinGlobals": true, "hoist": "all" }], + "no-shadow": [2, { "builtinGlobals": false, "hoist": "all" }], "no-use-before-define": [2, "nofunc"], "no-shadow-restricted-names": 2, "no-extra-semi": 2, "no-unused-vars": 2, "no-undef": 2, - "no-irregular-whitespace": 2, - "no-console": 2, - "key-spacing": 0, "strict": 0, "dot-notation": 0, - "eol-last": 0, "no-new": 0, - "semi-spacing": 0, - "no-multi-spaces": 0, "eqeqeq": 0, - "no-mixed-requires": 0 + + "no-underscore-dangle": 0, + "camelcase": 0, + "func-style": 0, + "max-lines": 0, + "id-length": 1, + "multiline-comment-style": 0, + + "no-plusplus": 1, + "no-caller": 1, }, + "env": { "node": true - } + }, + + "ignorePatterns": [ + "node_modules/*", + "index.d.ts", + "coverage", + ], } diff --git a/.github/workflows/node-aught.yml b/.github/workflows/node-aught.yml new file mode 100644 index 00000000..d0f17ab9 --- /dev/null +++ b/.github/workflows/node-aught.yml @@ -0,0 +1,14 @@ +name: 'Tests: node.js < 10' + +on: [pull_request, push] + +permissions: + contents: read + +jobs: + tests: + uses: ljharb/actions/.github/workflows/node.yml@main + with: + range: '>= 6 < 10' + type: minors + command: npm run ci-test diff --git a/.github/workflows/node-pretest.yml b/.github/workflows/node-pretest.yml new file mode 100644 index 00000000..88d49f9b --- /dev/null +++ b/.github/workflows/node-pretest.yml @@ -0,0 +1,10 @@ +name: 'Tests: pretest/posttest' + +on: [pull_request, push] + +permissions: + contents: read + +jobs: + tests: + uses: ljharb/actions/.github/workflows/pretest.yml@main diff --git a/.github/workflows/node-tens.yml b/.github/workflows/node-tens.yml new file mode 100644 index 00000000..f39714e0 --- /dev/null +++ b/.github/workflows/node-tens.yml @@ -0,0 +1,14 @@ +name: 'Tests: node.js >= 10' + +on: [pull_request, push] + +permissions: + contents: read + +jobs: + tests: + uses: ljharb/actions/.github/workflows/node.yml@main + with: + range: '>= 10' + type: minors + command: npm run ci-test diff --git a/.github/workflows/rebase.yml b/.github/workflows/rebase.yml new file mode 100644 index 00000000..18181913 --- /dev/null +++ b/.github/workflows/rebase.yml @@ -0,0 +1,22 @@ +name: Automatic Rebase + +on: [pull_request_target] + +permissions: + contents: read + +jobs: + _: + permissions: + contents: write # for ljharb/rebase to push code to rebase + pull-requests: read # for ljharb/rebase to get info about PR + + name: "Automatic Rebase" + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: ljharb/rebase@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/require-allow-edits.yml b/.github/workflows/require-allow-edits.yml new file mode 100644 index 00000000..a685b8ac --- /dev/null +++ b/.github/workflows/require-allow-edits.yml @@ -0,0 +1,18 @@ +name: Require “Allow Edits” + +on: [pull_request_target] + +permissions: + contents: read + +jobs: + _: + permissions: + pull-requests: read # for ljharb/require-allow-edits to check 'allow edits' on PR + + name: "Require “Allow Edits”" + + runs-on: ubuntu-latest + + steps: + - uses: ljharb/require-allow-edits@main diff --git a/.gitignore b/.gitignore index 5790d187..6d8a8023 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,8 @@ package-lock.json coverage/ node_modules/ test/tmp/ + +# Only apps should have lockfiles +npm-shrinkwrap.json +package-lock.json +yarn.lock diff --git a/.npmignore b/.npmignore index 31fcb79e..d55b80c4 100644 --- a/.npmignore +++ b/.npmignore @@ -7,3 +7,6 @@ sftp-config.json coverage/ node_modules/ test/ + +yarn.lock +*.bak diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000..eacea13e --- /dev/null +++ b/.npmrc @@ -0,0 +1,3 @@ +package-lock=false +allow-same-version=true +message=v%s diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f22a5d90..00000000 --- a/.travis.yml +++ /dev/null @@ -1,35 +0,0 @@ -sudo: false - -language: node_js -node_js: - - "6" - - "8" - - "10" - - "12" - -os: -- osx -- linux -- windows - -install: - - travis_retry npm install - -script: - - uname -a - - node --version - - npm --version - - if [ "$TRAVIS_OS_NAME" != "windows" ]; then npm run ci-lint; fi - - if [ "$TRAVIS_OS_NAME" = "windows" ]; then npm run test; else npm run ci-test; fi - - npm run check - -after_success: - - "cat coverage/lcov.info | ./node_modules/.bin/coveralls" - -notifications: - webhooks: - urls: - - "https://webhooks.gitter.im/e/3569d7edff0d38f93cd7" - on_success: always - on_failure: always - on_start: false diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..449dd432 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,601 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v4.0.4](https://github.com/form-data/form-data/compare/v4.0.3...v4.0.4) - 2025-07-16 + +### Commits + +- [meta] add `auto-changelog` [`811f682`](https://github.com/form-data/form-data/commit/811f68282fab0315209d0e2d1c44b6c32ea0d479) +- [Tests] handle predict-v8-randomness failures in node < 17 and node > 23 [`1d11a76`](https://github.com/form-data/form-data/commit/1d11a76434d101f22fdb26b8aef8615f28b98402) +- [Fix] Switch to using `crypto` random for boundary values [`3d17230`](https://github.com/form-data/form-data/commit/3d1723080e6577a66f17f163ecd345a21d8d0fd0) +- [Tests] fix linting errors [`5e34080`](https://github.com/form-data/form-data/commit/5e340800b5f8914213e4e0378c084aae71cfd73a) +- [meta] actually ensure the readme backup isn’t published [`316c82b`](https://github.com/form-data/form-data/commit/316c82ba93fd4985af757b771b9a1f26d3b709ef) +- [Dev Deps] update `@ljharb/eslint-config` [`58c25d7`](https://github.com/form-data/form-data/commit/58c25d76406a5b0dfdf54045cf252563f2bbda8d) +- [meta] fix readme capitalization [`2300ca1`](https://github.com/form-data/form-data/commit/2300ca19595b0ee96431e868fe2a40db79e41c61) + +## [v4.0.3](https://github.com/form-data/form-data/compare/v4.0.2...v4.0.3) - 2025-06-05 + +### Fixed + +- [Fix] `append`: avoid a crash on nullish values [`#577`](https://github.com/form-data/form-data/issues/577) + +### Commits + +- [eslint] use a shared config [`426ba9a`](https://github.com/form-data/form-data/commit/426ba9ac440f95d1998dac9a5cd8d738043b048f) +- [eslint] fix some spacing issues [`2094191`](https://github.com/form-data/form-data/commit/20941917f0e9487e68c564ebc3157e23609e2939) +- [Refactor] use `hasown` [`81ab41b`](https://github.com/form-data/form-data/commit/81ab41b46fdf34f5d89d7ff30b513b0925febfaa) +- [Fix] validate boundary type in `setBoundary()` method [`8d8e469`](https://github.com/form-data/form-data/commit/8d8e4693093519f7f18e3c597d1e8df8c493de9e) +- [Tests] add tests to check the behavior of `getBoundary` with non-strings [`837b8a1`](https://github.com/form-data/form-data/commit/837b8a1f7562bfb8bda74f3fc538adb7a5858995) +- [Dev Deps] remove unused deps [`870e4e6`](https://github.com/form-data/form-data/commit/870e4e665935e701bf983a051244ab928e62d58e) +- [meta] remove local commit hooks [`e6e83cc`](https://github.com/form-data/form-data/commit/e6e83ccb545a5619ed6cd04f31d5c2f655eb633e) +- [Dev Deps] update `eslint` [`4066fd6`](https://github.com/form-data/form-data/commit/4066fd6f65992b62fa324a6474a9292a4f88c916) +- [meta] fix scripts to use prepublishOnly [`c4bbb13`](https://github.com/form-data/form-data/commit/c4bbb13c0ef669916657bc129341301b1d331d75) + +## [v4.0.2](https://github.com/form-data/form-data/compare/v4.0.1...v4.0.2) - 2025-02-14 + +### Merged + +- [Fix] set `Symbol.toStringTag` when available [`#573`](https://github.com/form-data/form-data/pull/573) +- [Fix] set `Symbol.toStringTag` when available [`#573`](https://github.com/form-data/form-data/pull/573) +- fix (npmignore): ignore temporary build files [`#532`](https://github.com/form-data/form-data/pull/532) +- fix (npmignore): ignore temporary build files [`#532`](https://github.com/form-data/form-data/pull/532) + +### Fixed + +- [Fix] set `Symbol.toStringTag` when available (#573) [`#396`](https://github.com/form-data/form-data/issues/396) +- [Fix] set `Symbol.toStringTag` when available (#573) [`#396`](https://github.com/form-data/form-data/issues/396) +- [Fix] set `Symbol.toStringTag` when available [`#396`](https://github.com/form-data/form-data/issues/396) + +### Commits + +- Merge tags v2.5.3 and v3.0.3 [`92613b9`](https://github.com/form-data/form-data/commit/92613b9208556eb4ebc482fdf599fae111626fb6) +- [Tests] migrate from travis to GHA [`806eda7`](https://github.com/form-data/form-data/commit/806eda77740e6e3c67c7815afb216f2e1f187ba5) +- [Tests] migrate from travis to GHA [`8fdb3bc`](https://github.com/form-data/form-data/commit/8fdb3bc6b5d001f8909a9fca391d1d1d97ef1d79) +- [Refactor] use `Object.prototype.hasOwnProperty.call` [`7fecefe`](https://github.com/form-data/form-data/commit/7fecefe4ba8f775634aff86a698776ad95ecffb5) +- [Refactor] use `Object.prototype.hasOwnProperty.call` [`6e682d4`](https://github.com/form-data/form-data/commit/6e682d4bd41de7e80de41e3c4ee10f23fcc3dd00) +- [Refactor] use `Object.prototype.hasOwnProperty.call` [`df3c1e6`](https://github.com/form-data/form-data/commit/df3c1e6f0937f47a782dc4573756a54987f31dde) +- [Dev Deps] update `@types/node`, `browserify`, `coveralls`, `cross-spawn`, `eslint`, `formidable`, `in-publish`, `pkgfiles`, `pre-commit`, `puppeteer`, `request`, `tape`, `typescript` [`8261fcb`](https://github.com/form-data/form-data/commit/8261fcb8bf5944d30ae3bd04b91b71d6a9932ef4) +- [Dev Deps] update `@types/node`, `browserify`, `coveralls`, `cross-spawn`, `eslint`, `formidable`, `in-publish`, `pkgfiles`, `pre-commit`, `puppeteer`, `request`, `tape`, `typescript` [`fb66cb7`](https://github.com/form-data/form-data/commit/fb66cb740e29fb170eee947d4be6fdf82d6659af) +- [Dev Deps] update `@types/node`, `browserify`, `coveralls`, `eslint`, `formidable`, `in-publish`, `phantomjs-prebuilt`, `pkgfiles`, `pre-commit`, `request`, `tape`, `typescript` [`819f6b7`](https://github.com/form-data/form-data/commit/819f6b7a543306a891fca37c3a06d0ff4a734422) +- [eslint] clean up ignores [`3217b3d`](https://github.com/form-data/form-data/commit/3217b3ded8e382e51171d5c74c6038a21cc54440) +- [eslint] clean up ignores [`3a9d480`](https://github.com/form-data/form-data/commit/3a9d480232dbcbc07260ad84c3da4975d9a3ae9e) +- [Fix] `Buffer.from` and `Buffer.alloc` require node 4+ [`c499f76`](https://github.com/form-data/form-data/commit/c499f76f1faac1ddbf210c45217038e4c1e02337) +- Only apps should have lockfiles [`b82f590`](https://github.com/form-data/form-data/commit/b82f59093cdbadb4b7ec0922d33ae7ab048b82ff) +- Only apps should have lockfiles [`b170ee2`](https://github.com/form-data/form-data/commit/b170ee2b22b4c695c363b811c0c553d2fb1bbd79) +- [Deps] update `combined-stream`, `mime-types` [`6b1ca1d`](https://github.com/form-data/form-data/commit/6b1ca1dc7362a1b1c3a99a885516cca4b7eb817f) +- [Dev Deps] pin `request` which via `tough-cookie` ^2.4 depends on `psl` [`e5df7f2`](https://github.com/form-data/form-data/commit/e5df7f24383342264bd73dee3274818a40d04065) +- [Deps] update `mime-types` [`5a5bafe`](https://github.com/form-data/form-data/commit/5a5bafee894fead10da49e1fa2b084e17f2e1034) +- Bumped version 2.5.3 [`9457283`](https://github.com/form-data/form-data/commit/9457283e1dce6122adc908fdd7442cfc54cabe7a) +- [Dev Deps] pin `request` which via `tough-cookie` ^2.4 depends on `psl` [`9dbe192`](https://github.com/form-data/form-data/commit/9dbe192be3db215eac4d9c0b980470a5c2c030c6) +- Merge tags v2.5.2 and v3.0.2 [`d53265d`](https://github.com/form-data/form-data/commit/d53265d86c5153f535ec68eb107548b1b2883576) +- Bumped version 2.5.2 [`7020dd4`](https://github.com/form-data/form-data/commit/7020dd4c1260370abc40e86e3dfe49c5d576fbda) +- [Dev Deps] downgrade `cross-spawn` [`3fc1a9b`](https://github.com/form-data/form-data/commit/3fc1a9b62ddf1fe77a2bd6bd3476e4c0a9e01a88) +- fix: move util.isArray to Array.isArray (#564) [`edb555a`](https://github.com/form-data/form-data/commit/edb555a811f6f7e4668db4831551cf41c1de1cac) +- fix: move util.isArray to Array.isArray (#564) [`10418d1`](https://github.com/form-data/form-data/commit/10418d1fe4b0d65fe020eafe3911feb5ad5e2bd6) + +## [v4.0.1](https://github.com/form-data/form-data/compare/v4.0.0...v4.0.1) - 2024-10-10 + +### Commits + +- [Tests] migrate from travis to GHA [`757b4e3`](https://github.com/form-data/form-data/commit/757b4e32e95726aec9bdcc771fb5a3b564d88034) +- [eslint] clean up ignores [`e8f0d80`](https://github.com/form-data/form-data/commit/e8f0d80cd7cd424d1488532621ec40a33218b30b) +- fix (npmignore): ignore temporary build files [`335ad19`](https://github.com/form-data/form-data/commit/335ad19c6e17dc2d7298ffe0e9b37ba63600e94b) +- fix: move util.isArray to Array.isArray [`440d3be`](https://github.com/form-data/form-data/commit/440d3bed752ac2f9213b4c2229dbccefe140e5fa) + +## [v4.0.0](https://github.com/form-data/form-data/compare/v3.0.3...v4.0.0) - 2021-02-15 + +### Merged + +- Handle custom stream [`#382`](https://github.com/form-data/form-data/pull/382) + +### Commits + +- Fix typo [`e705c0a`](https://github.com/form-data/form-data/commit/e705c0a1fdaf90d21501f56460b93e43a18bd435) +- Update README for custom stream behavior [`6dd8624`](https://github.com/form-data/form-data/commit/6dd8624b2999e32768d62752c9aae5845a803b0d) + +## [v3.0.3](https://github.com/form-data/form-data/compare/v3.0.2...v3.0.3) - 2025-02-14 + +### Merged + +- [Fix] set `Symbol.toStringTag` when available [`#573`](https://github.com/form-data/form-data/pull/573) + +### Fixed + +- [Fix] set `Symbol.toStringTag` when available (#573) [`#396`](https://github.com/form-data/form-data/issues/396) + +### Commits + +- [Refactor] use `Object.prototype.hasOwnProperty.call` [`7fecefe`](https://github.com/form-data/form-data/commit/7fecefe4ba8f775634aff86a698776ad95ecffb5) +- [Dev Deps] update `@types/node`, `browserify`, `coveralls`, `cross-spawn`, `eslint`, `formidable`, `in-publish`, `pkgfiles`, `pre-commit`, `puppeteer`, `request`, `tape`, `typescript` [`8261fcb`](https://github.com/form-data/form-data/commit/8261fcb8bf5944d30ae3bd04b91b71d6a9932ef4) +- Only apps should have lockfiles [`b82f590`](https://github.com/form-data/form-data/commit/b82f59093cdbadb4b7ec0922d33ae7ab048b82ff) +- [Dev Deps] pin `request` which via `tough-cookie` ^2.4 depends on `psl` [`e5df7f2`](https://github.com/form-data/form-data/commit/e5df7f24383342264bd73dee3274818a40d04065) +- [Deps] update `mime-types` [`5a5bafe`](https://github.com/form-data/form-data/commit/5a5bafee894fead10da49e1fa2b084e17f2e1034) + +## [v3.0.2](https://github.com/form-data/form-data/compare/v3.0.1...v3.0.2) - 2024-10-10 + +### Merged + +- fix (npmignore): ignore temporary build files [`#532`](https://github.com/form-data/form-data/pull/532) + +### Commits + +- [Tests] migrate from travis to GHA [`8fdb3bc`](https://github.com/form-data/form-data/commit/8fdb3bc6b5d001f8909a9fca391d1d1d97ef1d79) +- [eslint] clean up ignores [`3217b3d`](https://github.com/form-data/form-data/commit/3217b3ded8e382e51171d5c74c6038a21cc54440) +- fix: move util.isArray to Array.isArray (#564) [`edb555a`](https://github.com/form-data/form-data/commit/edb555a811f6f7e4668db4831551cf41c1de1cac) + +## [v3.0.1](https://github.com/form-data/form-data/compare/v3.0.0...v3.0.1) - 2021-02-15 + +### Merged + +- Fix typo: ads -> adds [`#451`](https://github.com/form-data/form-data/pull/451) + +### Commits + +- feat: add setBoundary method [`55d90ce`](https://github.com/form-data/form-data/commit/55d90ce4a4c22b0ea0647991d85cb946dfb7395b) + +## [v3.0.0](https://github.com/form-data/form-data/compare/v2.5.3...v3.0.0) - 2019-11-05 + +### Merged + +- Update Readme.md [`#449`](https://github.com/form-data/form-data/pull/449) +- Update package.json [`#448`](https://github.com/form-data/form-data/pull/448) +- fix memory leak [`#447`](https://github.com/form-data/form-data/pull/447) +- form-data: Replaced PhantomJS Dependency [`#442`](https://github.com/form-data/form-data/pull/442) +- Fix constructor options in Typescript definitions [`#446`](https://github.com/form-data/form-data/pull/446) +- Fix the getHeaders method signatures [`#434`](https://github.com/form-data/form-data/pull/434) +- Update combined-stream (fixes #422) [`#424`](https://github.com/form-data/form-data/pull/424) + +### Fixed + +- Merge pull request #424 from botgram/update-combined-stream [`#422`](https://github.com/form-data/form-data/issues/422) +- Update combined-stream (fixes #422) [`#422`](https://github.com/form-data/form-data/issues/422) + +### Commits + +- Add readable stream options to constructor type [`80c8f74`](https://github.com/form-data/form-data/commit/80c8f746bcf4c0418ae35fbedde12fb8c01e2748) +- Fixed: getHeaders method signatures [`f4ca7f8`](https://github.com/form-data/form-data/commit/f4ca7f8e31f7e07df22c1aeb8e0a32a7055a64ca) +- Pass options to constructor if not used with new [`4bde68e`](https://github.com/form-data/form-data/commit/4bde68e12de1ba90fefad2e7e643f6375b902763) +- Make userHeaders optional [`2b4e478`](https://github.com/form-data/form-data/commit/2b4e4787031490942f2d1ee55c56b85a250875a7) + +## [v2.5.3](https://github.com/form-data/form-data/compare/v2.5.2...v2.5.3) - 2025-02-14 + +### Merged + +- [Fix] set `Symbol.toStringTag` when available [`#573`](https://github.com/form-data/form-data/pull/573) + +### Fixed + +- [Fix] set `Symbol.toStringTag` when available (#573) [`#396`](https://github.com/form-data/form-data/issues/396) + +### Commits + +- [Refactor] use `Object.prototype.hasOwnProperty.call` [`6e682d4`](https://github.com/form-data/form-data/commit/6e682d4bd41de7e80de41e3c4ee10f23fcc3dd00) +- [Dev Deps] update `@types/node`, `browserify`, `coveralls`, `eslint`, `formidable`, `in-publish`, `phantomjs-prebuilt`, `pkgfiles`, `pre-commit`, `request`, `tape`, `typescript` [`819f6b7`](https://github.com/form-data/form-data/commit/819f6b7a543306a891fca37c3a06d0ff4a734422) +- Only apps should have lockfiles [`b170ee2`](https://github.com/form-data/form-data/commit/b170ee2b22b4c695c363b811c0c553d2fb1bbd79) +- [Deps] update `combined-stream`, `mime-types` [`6b1ca1d`](https://github.com/form-data/form-data/commit/6b1ca1dc7362a1b1c3a99a885516cca4b7eb817f) +- Bumped version 2.5.3 [`9457283`](https://github.com/form-data/form-data/commit/9457283e1dce6122adc908fdd7442cfc54cabe7a) +- [Dev Deps] pin `request` which via `tough-cookie` ^2.4 depends on `psl` [`9dbe192`](https://github.com/form-data/form-data/commit/9dbe192be3db215eac4d9c0b980470a5c2c030c6) + +## [v2.5.2](https://github.com/form-data/form-data/compare/v2.5.1...v2.5.2) - 2024-10-10 + +### Merged + +- fix (npmignore): ignore temporary build files [`#532`](https://github.com/form-data/form-data/pull/532) + +### Commits + +- [Tests] migrate from travis to GHA [`806eda7`](https://github.com/form-data/form-data/commit/806eda77740e6e3c67c7815afb216f2e1f187ba5) +- [eslint] clean up ignores [`3a9d480`](https://github.com/form-data/form-data/commit/3a9d480232dbcbc07260ad84c3da4975d9a3ae9e) +- [Fix] `Buffer.from` and `Buffer.alloc` require node 4+ [`c499f76`](https://github.com/form-data/form-data/commit/c499f76f1faac1ddbf210c45217038e4c1e02337) +- Bumped version 2.5.2 [`7020dd4`](https://github.com/form-data/form-data/commit/7020dd4c1260370abc40e86e3dfe49c5d576fbda) +- [Dev Deps] downgrade `cross-spawn` [`3fc1a9b`](https://github.com/form-data/form-data/commit/3fc1a9b62ddf1fe77a2bd6bd3476e4c0a9e01a88) +- fix: move util.isArray to Array.isArray (#564) [`10418d1`](https://github.com/form-data/form-data/commit/10418d1fe4b0d65fe020eafe3911feb5ad5e2bd6) + +## [v2.5.1](https://github.com/form-data/form-data/compare/v2.5.0...v2.5.1) - 2019-08-28 + +### Merged + +- Fix error in callback signatures [`#435`](https://github.com/form-data/form-data/pull/435) +- -Fixed: Eerror in the documentations as indicated in #439 [`#440`](https://github.com/form-data/form-data/pull/440) +- Add constructor options to TypeScript defs [`#437`](https://github.com/form-data/form-data/pull/437) + +### Commits + +- Add remaining combined-stream options to typedef [`4d41a32`](https://github.com/form-data/form-data/commit/4d41a32c0b3f85f8bbc9cf17df43befd2d5fc305) +- Bumped version 2.5.1 [`8ce81f5`](https://github.com/form-data/form-data/commit/8ce81f56cccf5466363a5eff135ad394a929f59b) +- Bump rimraf to 2.7.1 [`a6bc2d4`](https://github.com/form-data/form-data/commit/a6bc2d4296dbdee5d84cbab7c69bcd0eea7a12e2) + +## [v2.5.0](https://github.com/form-data/form-data/compare/v2.4.0...v2.5.0) - 2019-07-03 + +### Merged + +- - Added: public methods with information and examples to readme [`#429`](https://github.com/form-data/form-data/pull/429) +- chore: move @types/node to devDep [`#431`](https://github.com/form-data/form-data/pull/431) +- Switched windows tests from AppVeyor to Travis [`#430`](https://github.com/form-data/form-data/pull/430) +- feat(typings): migrate TS typings #427 [`#428`](https://github.com/form-data/form-data/pull/428) +- enhance the method of path.basename, handle undefined case [`#421`](https://github.com/form-data/form-data/pull/421) + +### Commits + +- - Added: public methods with information and examples to the readme file. [`21323f3`](https://github.com/form-data/form-data/commit/21323f3b4043a167046a4a2554c5f2825356c423) +- feat(typings): migrate TS typings [`a3c0142`](https://github.com/form-data/form-data/commit/a3c0142ed91b0c7dcaf89c4f618776708f1f70a9) +- - Fixed: Typos [`37350fa`](https://github.com/form-data/form-data/commit/37350fa250782f156a998ec1fa9671866d40ac49) +- Switched to Travis Windows from Appveyor [`fc61c73`](https://github.com/form-data/form-data/commit/fc61c7381fad12662df16dbc3e7621c91b886f03) +- - Fixed: rendering of subheaders [`e93ed8d`](https://github.com/form-data/form-data/commit/e93ed8df9d7f22078bc3a2c24889e9dfa11e192d) +- Updated deps and readme [`e3d8628`](https://github.com/form-data/form-data/commit/e3d8628728f6e4817ab97deeed92f0c822661b89) +- Updated dependencies [`19add50`](https://github.com/form-data/form-data/commit/19add50afb7de66c70d189f422d16f1b886616e2) +- Bumped version to 2.5.0 [`905f173`](https://github.com/form-data/form-data/commit/905f173a3f785e8d312998e765634ee451ca5f42) +- - Fixed: filesize is not a valid option? knownLength should be used for streams [`d88f912`](https://github.com/form-data/form-data/commit/d88f912b75b666b47f8674467516eade69d2d5be) +- Bump notion of modern node to node8 [`508b626`](https://github.com/form-data/form-data/commit/508b626bf1b460d3733d3420dc1cfd001617f6ac) +- enhance the method of path.basename [`faaa68a`](https://github.com/form-data/form-data/commit/faaa68a297be7d4fca0ac4709d5b93afc1f78b5c) + +## [v2.4.0](https://github.com/form-data/form-data/compare/v2.3.2...v2.4.0) - 2019-06-19 + +### Merged + +- Added "getBuffer" method and updated certificates [`#419`](https://github.com/form-data/form-data/pull/419) +- docs(readme): add axios integration document [`#425`](https://github.com/form-data/form-data/pull/425) +- Allow newer versions of combined-stream [`#402`](https://github.com/form-data/form-data/pull/402) + +### Commits + +- Updated: Certificate [`e90a76a`](https://github.com/form-data/form-data/commit/e90a76ab3dcaa63a6f3045f8255bfbb9c25a3e4e) +- Updated build/test/badges [`8512eef`](https://github.com/form-data/form-data/commit/8512eef436e28372f5bc88de3ca76a9cb46e6847) +- Bumped version 2.4.0 [`0f8da06`](https://github.com/form-data/form-data/commit/0f8da06c0b4c997bd2f6b09d78290d339616a950) +- docs(readme): remove unnecessary bracket [`4e3954d`](https://github.com/form-data/form-data/commit/4e3954dde304d27e3b95371d8c78002f3af5d5b2) +- Bumped version to 2.3.3 [`b16916a`](https://github.com/form-data/form-data/commit/b16916a568a0d06f3f8a16c31f9a8b89b7844094) + +## [v2.3.2](https://github.com/form-data/form-data/compare/v2.3.1...v2.3.2) - 2018-02-13 + +### Merged + +- Pulling in fixed combined-stream [`#379`](https://github.com/form-data/form-data/pull/379) + +### Commits + +- All the dev dependencies are breaking in old versions of node :'( [`c7dba6a`](https://github.com/form-data/form-data/commit/c7dba6a139d872d173454845e25e1850ed6b72b4) +- Updated badges [`19b6c7a`](https://github.com/form-data/form-data/commit/19b6c7a8a5c40f47f91c8a8da3e5e4dc3c449fa3) +- Try tests in node@4 [`872a326`](https://github.com/form-data/form-data/commit/872a326ab13e2740b660ff589b75232c3a85fcc9) +- Pull in final version [`9d44871`](https://github.com/form-data/form-data/commit/9d44871073d647995270b19dbc26f65671ce15c7) + +## [v2.3.1](https://github.com/form-data/form-data/compare/v2.3.0...v2.3.1) - 2017-08-24 + +### Commits + +- Updated readme with custom options example [`8e0a569`](https://github.com/form-data/form-data/commit/8e0a5697026016fe171e93bec43c2205279e23ca) +- Added support (tests) for node 8 [`d1d6f4a`](https://github.com/form-data/form-data/commit/d1d6f4ad4670d8ba84cc85b28e522ca0e93eb362) + +## [v2.3.0](https://github.com/form-data/form-data/compare/v2.2.0...v2.3.0) - 2017-08-24 + +### Merged + +- Added custom `options` support [`#368`](https://github.com/form-data/form-data/pull/368) +- Allow form.submit with url string param to use https [`#249`](https://github.com/form-data/form-data/pull/249) +- Proper header production [`#357`](https://github.com/form-data/form-data/pull/357) +- Fix wrong MIME type in example [`#285`](https://github.com/form-data/form-data/pull/285) + +### Commits + +- allow form.submit with url string param to use https [`c0390dc`](https://github.com/form-data/form-data/commit/c0390dcc623e15215308fa2bb0225aa431d9381e) +- update tests for url parsing [`eec0e80`](https://github.com/form-data/form-data/commit/eec0e807889d46697abd39a89ad9bf39996ba787) +- Uses for in to assign properties instead of Object.assign [`f6854ed`](https://github.com/form-data/form-data/commit/f6854edd85c708191bb9c89615a09fd0a9afe518) +- Adds test to check for option override [`61762f2`](https://github.com/form-data/form-data/commit/61762f2c5262e576d6a7f778b4ebab6546ef8582) +- Removes the 2mb maxDataSize limitation [`dc171c3`](https://github.com/form-data/form-data/commit/dc171c3ba49ac9b8813636fd4159d139b812315b) +- Ignore .DS_Store [`e8a05d3`](https://github.com/form-data/form-data/commit/e8a05d33361f7dca8927fe1d96433d049843de24) + +## [v2.2.0](https://github.com/form-data/form-data/compare/v2.1.4...v2.2.0) - 2017-06-11 + +### Merged + +- Filename can be a nested path [`#355`](https://github.com/form-data/form-data/pull/355) + +### Commits + +- Bumped version number. [`d7398c3`](https://github.com/form-data/form-data/commit/d7398c3e7cd81ed12ecc0b84363721bae467db02) + +## [v2.1.4](https://github.com/form-data/form-data/compare/2.1.3...v2.1.4) - 2017-04-08 + +## [2.1.3](https://github.com/form-data/form-data/compare/v2.1.3...2.1.3) - 2017-04-08 + +## [v2.1.3](https://github.com/form-data/form-data/compare/v2.1.2...v2.1.3) - 2017-04-08 + +### Merged + +- toString should output '[object FormData]' [`#346`](https://github.com/form-data/form-data/pull/346) + +## [v2.1.2](https://github.com/form-data/form-data/compare/v2.1.1...v2.1.2) - 2016-11-07 + +### Merged + +- #271 Added check for self and window objects + tests [`#282`](https://github.com/form-data/form-data/pull/282) + +### Commits + +- Added check for self and window objects + tests [`c99e4ec`](https://github.com/form-data/form-data/commit/c99e4ec32cd14d83776f2bdcc5a4e7384131c1b1) + +## [v2.1.1](https://github.com/form-data/form-data/compare/v2.1.0...v2.1.1) - 2016-10-03 + +### Merged + +- Bumped dependencies. [`#270`](https://github.com/form-data/form-data/pull/270) +- Update browser.js shim to use self instead of window [`#267`](https://github.com/form-data/form-data/pull/267) +- Boilerplate code rediction [`#265`](https://github.com/form-data/form-data/pull/265) +- eslint@3.7.0 [`#266`](https://github.com/form-data/form-data/pull/266) + +### Commits + +- code duplicates removed [`e9239fb`](https://github.com/form-data/form-data/commit/e9239fbe7d3c897b29fe3bde857d772469541c01) +- Changed according to requests [`aa99246`](https://github.com/form-data/form-data/commit/aa9924626bd9168334d73fea568c0ad9d8fbaa96) +- chore(package): update eslint to version 3.7.0 [`090a859`](https://github.com/form-data/form-data/commit/090a859835016cab0de49629140499e418db9c3a) + +## [v2.1.0](https://github.com/form-data/form-data/compare/v2.0.0...v2.1.0) - 2016-09-25 + +### Merged + +- Added `hasKnownLength` public method [`#263`](https://github.com/form-data/form-data/pull/263) + +### Commits + +- Added hasKnownLength public method [`655b959`](https://github.com/form-data/form-data/commit/655b95988ef2ed3399f8796b29b2a8673c1df11c) + +## [v2.0.0](https://github.com/form-data/form-data/compare/v1.0.0...v2.0.0) - 2016-09-16 + +### Merged + +- Replaced async with asynckit [`#258`](https://github.com/form-data/form-data/pull/258) +- Pre-release house cleaning [`#247`](https://github.com/form-data/form-data/pull/247) + +### Commits + +- Replaced async with asynckit. Modernized [`1749b78`](https://github.com/form-data/form-data/commit/1749b78d50580fbd080e65c1eb9702ad4f4fc0c0) +- Ignore .bak files [`c08190a`](https://github.com/form-data/form-data/commit/c08190a87d3e22a528b6e32b622193742a4c2672) +- Trying to be more chatty. :) [`c79eabb`](https://github.com/form-data/form-data/commit/c79eabb24eaf761069255a44abf4f540cfd47d40) + +## [v1.0.0](https://github.com/form-data/form-data/compare/v1.0.0-rc4...v1.0.0) - 2016-08-26 + +### Merged + +- Allow custom header fields to be set as an object. [`#190`](https://github.com/form-data/form-data/pull/190) +- v1.0.0-rc4 [`#182`](https://github.com/form-data/form-data/pull/182) +- Avoid undefined variable reference in older browsers [`#176`](https://github.com/form-data/form-data/pull/176) +- More housecleaning [`#164`](https://github.com/form-data/form-data/pull/164) +- More cleanup [`#159`](https://github.com/form-data/form-data/pull/159) +- Added windows testing. Some cleanup. [`#158`](https://github.com/form-data/form-data/pull/158) +- Housecleaning. Added test coverage. [`#156`](https://github.com/form-data/form-data/pull/156) +- Second iteration of cleanup. [`#145`](https://github.com/form-data/form-data/pull/145) + +### Commits + +- Pre-release house cleaning [`440d72b`](https://github.com/form-data/form-data/commit/440d72b5fd44dd132f42598c3183d46e5f35ce71) +- Updated deps, updated docs [`54b6114`](https://github.com/form-data/form-data/commit/54b61143e9ce66a656dd537a1e7b31319a4991be) +- make docs up-to-date [`5e383d7`](https://github.com/form-data/form-data/commit/5e383d7f1466713f7fcef58a6817e0cb466c8ba7) +- Added missing deps [`fe04862`](https://github.com/form-data/form-data/commit/fe04862000b2762245e2db69d5207696a08c1174) + +## [v1.0.0-rc4](https://github.com/form-data/form-data/compare/v1.0.0-rc3...v1.0.0-rc4) - 2016-03-15 + +### Merged + +- Housecleaning, preparing for the release [`#144`](https://github.com/form-data/form-data/pull/144) +- lib: emit error when failing to get length [`#127`](https://github.com/form-data/form-data/pull/127) +- Cleaning up for Codacity 2. [`#143`](https://github.com/form-data/form-data/pull/143) +- Cleaned up codacity concerns. [`#142`](https://github.com/form-data/form-data/pull/142) +- Should throw type error without new operator. [`#129`](https://github.com/form-data/form-data/pull/129) + +### Commits + +- More cleanup [`94b6565`](https://github.com/form-data/form-data/commit/94b6565bb98a387335c72feff5ed5c10da0a7f6f) +- Shuffling things around [`3c2f172`](https://github.com/form-data/form-data/commit/3c2f172eaddf0979b3eef5c73985d1a6fd3eee4a) +- Second iteration of cleanup. [`347c88e`](https://github.com/form-data/form-data/commit/347c88ef9a99a66b9bcf4278497425db2f0182b2) +- Housecleaning [`c335610`](https://github.com/form-data/form-data/commit/c3356100c054a4695e4dec8ed7072775cd745616) +- More housecleaning [`f573321`](https://github.com/form-data/form-data/commit/f573321824aae37ba2052a92cc889d533d9f8fb8) +- Trying to make far run on windows. + cleanup [`e426dfc`](https://github.com/form-data/form-data/commit/e426dfcefb07ee307d8a15dec04044cce62413e6) +- Playing with appveyor [`c9458a7`](https://github.com/form-data/form-data/commit/c9458a7c328782b19859bc1745e7d6b2005ede86) +- Updated dev dependencies. [`ceebe88`](https://github.com/form-data/form-data/commit/ceebe88872bb22da0a5a98daf384e3cc232928d3) +- Replaced win-spawn with cross-spawn [`405a69e`](https://github.com/form-data/form-data/commit/405a69ee34e235ee6561b5ff0140b561be40d1cc) +- Updated readme badges. [`12f282a`](https://github.com/form-data/form-data/commit/12f282a1310fcc2f70cc5669782283929c32a63d) +- Making paths windows friendly. [`f4bddc5`](https://github.com/form-data/form-data/commit/f4bddc5955e2472f8e23c892c9b4d7a08fcb85a3) +- [WIP] trying things for greater sanity [`8ad1f02`](https://github.com/form-data/form-data/commit/8ad1f02b0b3db4a0b00c5d6145ed69bcb7558213) +- Bending under Codacy [`bfff3bb`](https://github.com/form-data/form-data/commit/bfff3bb36052dc83f429949b4e6f9b146a49d996) +- Another attempt to make windows friendly [`f3eb628`](https://github.com/form-data/form-data/commit/f3eb628974ccb91ba0020f41df490207eeed77f6) +- Updated dependencies. [`f73996e`](https://github.com/form-data/form-data/commit/f73996e0508ee2d4b2b376276adfac1de4188ac2) +- Missed travis changes. [`67ee79f`](https://github.com/form-data/form-data/commit/67ee79f964fdabaf300bd41b0af0c1cfaca07687) +- Restructured badges. [`48444a1`](https://github.com/form-data/form-data/commit/48444a1ff156ba2c2c3cfd11047c2f2fd92d4474) +- Add similar type error as the browser for attempting to use form-data without new. [`5711320`](https://github.com/form-data/form-data/commit/5711320fb7c8cc620cfc79b24c7721526e23e539) +- Took out codeclimate-test-reporter [`a7e0c65`](https://github.com/form-data/form-data/commit/a7e0c6522afe85ca9974b0b4e1fca9c77c3e52b1) +- One more [`8e84cff`](https://github.com/form-data/form-data/commit/8e84cff3370526ecd3e175fd98e966242d81993c) + +## [v1.0.0-rc3](https://github.com/form-data/form-data/compare/v1.0.0-rc2...v1.0.0-rc3) - 2015-07-29 + +### Merged + +- House cleaning. Added `pre-commit`. [`#140`](https://github.com/form-data/form-data/pull/140) +- Allow custom content-type without setting a filename. [`#138`](https://github.com/form-data/form-data/pull/138) +- Add node-fetch to alternative submission methods. [`#132`](https://github.com/form-data/form-data/pull/132) +- Update dependencies [`#130`](https://github.com/form-data/form-data/pull/130) +- Switching to container based TravisCI [`#136`](https://github.com/form-data/form-data/pull/136) +- Default content-type to 'application/octect-stream' [`#128`](https://github.com/form-data/form-data/pull/128) +- Allow filename as third option of .append [`#125`](https://github.com/form-data/form-data/pull/125) + +### Commits + +- Allow custom content-type without setting a filename [`c8a77cc`](https://github.com/form-data/form-data/commit/c8a77cc0cf16d15f1ebf25272beaab639ce89f76) +- Fixed ranged test. [`a5ac58c`](https://github.com/form-data/form-data/commit/a5ac58cbafd0909f32fe8301998f689314fd4859) +- Allow filename as third option of #append [`d081005`](https://github.com/form-data/form-data/commit/d0810058c84764b3c463a18b15ebb37864de9260) +- Allow custom content-type without setting a filename [`8cb9709`](https://github.com/form-data/form-data/commit/8cb9709e5f1809cfde0cd707dbabf277138cd771) + +## [v1.0.0-rc2](https://github.com/form-data/form-data/compare/v1.0.0-rc1...v1.0.0-rc2) - 2015-07-21 + +### Merged + +- #109 Append proper line break [`#123`](https://github.com/form-data/form-data/pull/123) +- Add shim for browser (browserify/webpack). [`#122`](https://github.com/form-data/form-data/pull/122) +- Update license field [`#115`](https://github.com/form-data/form-data/pull/115) + +### Commits + +- Add shim for browser. [`87c33f4`](https://github.com/form-data/form-data/commit/87c33f4269a2211938f80ab3e53835362b1afee8) +- Bump version [`a3f5d88`](https://github.com/form-data/form-data/commit/a3f5d8872c810ce240c7d3838c69c3c9fcecc111) + +## [v1.0.0-rc1](https://github.com/form-data/form-data/compare/0.2...v1.0.0-rc1) - 2015-06-13 + +### Merged + +- v1.0.0-rc1 [`#114`](https://github.com/form-data/form-data/pull/114) +- Updated test targets [`#102`](https://github.com/form-data/form-data/pull/102) +- Remove duplicate plus sign [`#94`](https://github.com/form-data/form-data/pull/94) + +### Commits + +- Made https test local. Updated deps. [`afe1959`](https://github.com/form-data/form-data/commit/afe1959ec711f23e57038ab5cb20fedd86271f29) +- Proper self-signed ssl [`4d5ec50`](https://github.com/form-data/form-data/commit/4d5ec50e81109ad2addf3dbb56dc7c134df5ff87) +- Update HTTPS handling for modern days [`2c11b01`](https://github.com/form-data/form-data/commit/2c11b01ce2c06e205c84d7154fa2f27b66c94f3b) +- Made tests more local [`09633fa`](https://github.com/form-data/form-data/commit/09633fa249e7ce3ac581543aafe16ee9039a823b) +- Auto create tmp folder for Formidable [`28714b7`](https://github.com/form-data/form-data/commit/28714b7f71ad556064cdff88fabe6b92bd407ddd) +- remove duplicate plus sign [`36e09c6`](https://github.com/form-data/form-data/commit/36e09c695b0514d91a23f5cd64e6805404776fc7) + +## [0.2](https://github.com/form-data/form-data/compare/0.1.4...0.2) - 2014-12-06 + +### Merged + +- Bumped version [`#96`](https://github.com/form-data/form-data/pull/96) +- Replace mime library. [`#95`](https://github.com/form-data/form-data/pull/95) +- #71 Respect bytes range in a read stream. [`#73`](https://github.com/form-data/form-data/pull/73) + +## [0.1.4](https://github.com/form-data/form-data/compare/0.1.3...0.1.4) - 2014-06-23 + +### Merged + +- Updated version. [`#76`](https://github.com/form-data/form-data/pull/76) +- #71 Respect bytes range in a read stream. [`#75`](https://github.com/form-data/form-data/pull/75) + +## [0.1.3](https://github.com/form-data/form-data/compare/0.1.2...0.1.3) - 2014-06-17 + +### Merged + +- Updated versions. [`#69`](https://github.com/form-data/form-data/pull/69) +- Added custom headers support [`#60`](https://github.com/form-data/form-data/pull/60) +- Added test for Request. Small fixes. [`#56`](https://github.com/form-data/form-data/pull/56) + +### Commits + +- Added test for the custom header functionality [`bd50685`](https://github.com/form-data/form-data/commit/bd506855af62daf728ef1718cae88ed23bb732f3) +- Documented custom headers option [`77a024a`](https://github.com/form-data/form-data/commit/77a024a9375f93c246c35513d80f37d5e11d35ff) +- Removed 0.6 support. [`aee8dce`](https://github.com/form-data/form-data/commit/aee8dce604c595cfaacfc6efb12453d1691ac0d6) + +## [0.1.2](https://github.com/form-data/form-data/compare/0.1.1...0.1.2) - 2013-10-02 + +### Merged + +- Fixed default https port assignment, added tests. [`#52`](https://github.com/form-data/form-data/pull/52) +- #45 Added tests for multi-submit. Updated readme. [`#49`](https://github.com/form-data/form-data/pull/49) +- #47 return request from .submit() [`#48`](https://github.com/form-data/form-data/pull/48) + +### Commits + +- Bumped version. [`2b761b2`](https://github.com/form-data/form-data/commit/2b761b256ae607fc2121621f12c2e1042be26baf) + +## [0.1.1](https://github.com/form-data/form-data/compare/0.1.0...0.1.1) - 2013-08-21 + +### Merged + +- Added license type and reference to package.json [`#46`](https://github.com/form-data/form-data/pull/46) + +### Commits + +- #47 return request from .submit() [`1d61c2d`](https://github.com/form-data/form-data/commit/1d61c2da518bd5e136550faa3b5235bb540f1e06) +- #47 Updated readme. [`e3dae15`](https://github.com/form-data/form-data/commit/e3dae1526bd3c3b9d7aff6075abdaac12c3cc60f) + +## [0.1.0](https://github.com/form-data/form-data/compare/0.0.10...0.1.0) - 2013-07-08 + +### Merged + +- Update master to 0.1.0 [`#44`](https://github.com/form-data/form-data/pull/44) +- 0.1.0 - Added error handling. Streamlined edge cases behavior. [`#43`](https://github.com/form-data/form-data/pull/43) +- Pointed badges back to mothership. [`#39`](https://github.com/form-data/form-data/pull/39) +- Updated node-fake to support 0.11 tests. [`#37`](https://github.com/form-data/form-data/pull/37) +- Updated tests to play nice with 0.10 [`#36`](https://github.com/form-data/form-data/pull/36) +- #32 Added .npmignore [`#34`](https://github.com/form-data/form-data/pull/34) +- Spring cleaning [`#30`](https://github.com/form-data/form-data/pull/30) + +### Commits + +- Added error handling. Streamlined edge cases behavior. [`4da496e`](https://github.com/form-data/form-data/commit/4da496e577cb9bc0fd6c94cbf9333a0082ce353a) +- Made tests more deterministic. [`7fc009b`](https://github.com/form-data/form-data/commit/7fc009b8a2cc9232514a44b2808b9f89ce68f7d2) +- Fixed styling. [`d373b41`](https://github.com/form-data/form-data/commit/d373b417e779024bc3326073e176383cd08c0b18) +- #40 Updated Readme.md regarding getLengthSync() [`efb373f`](https://github.com/form-data/form-data/commit/efb373fd63814d977960e0299d23c92cd876cfef) +- Updated readme. [`527e3a6`](https://github.com/form-data/form-data/commit/527e3a63b032cb6f576f597ad7ff2ebcf8a0b9b4) + +## [0.0.10](https://github.com/form-data/form-data/compare/0.0.9...0.0.10) - 2013-05-08 + +### Commits + +- Updated tests to play nice with 0.10. [`932b39b`](https://github.com/form-data/form-data/commit/932b39b773e49edcb2c5d2e58fe389ab6c42f47c) +- Added dependency tracking. [`3131d7f`](https://github.com/form-data/form-data/commit/3131d7f6996cd519d50547e4de1587fd80d0fa07) + +## 0.0.9 - 2013-04-29 + +### Merged + +- Custom params for form.submit() should cover most edge cases. [`#22`](https://github.com/form-data/form-data/pull/22) +- Updated Readme and version number. [`#20`](https://github.com/form-data/form-data/pull/20) +- Allow custom headers and pre-known length in parts [`#17`](https://github.com/form-data/form-data/pull/17) +- Bumped version number. [`#12`](https://github.com/form-data/form-data/pull/12) +- Fix for #10 [`#11`](https://github.com/form-data/form-data/pull/11) +- Bumped version number. [`#8`](https://github.com/form-data/form-data/pull/8) +- Added support for https destination, http-response and mikeal's request streams. [`#7`](https://github.com/form-data/form-data/pull/7) +- Updated git url. [`#6`](https://github.com/form-data/form-data/pull/6) +- Version bump. [`#5`](https://github.com/form-data/form-data/pull/5) +- Changes to support custom content-type and getLengthSync. [`#4`](https://github.com/form-data/form-data/pull/4) +- make .submit(url) use host from url, not 'localhost' [`#2`](https://github.com/form-data/form-data/pull/2) +- Make package.json JSON [`#1`](https://github.com/form-data/form-data/pull/1) + +### Fixed + +- Add MIT license [`#14`](https://github.com/form-data/form-data/issues/14) + +### Commits + +- Spring cleaning. [`850ba1b`](https://github.com/form-data/form-data/commit/850ba1b649b6856b0fa87bbcb04bc70ece0137a6) +- Added custom request params to form.submit(). Made tests more stable. [`de3502f`](https://github.com/form-data/form-data/commit/de3502f6c4a509f6ed12a7dd9dc2ce9c2e0a8d23) +- Basic form (no files) working [`6ffdc34`](https://github.com/form-data/form-data/commit/6ffdc343e8594cfc2efe1e27653ea39d8980a14e) +- Got initial test to pass [`9a59d08`](https://github.com/form-data/form-data/commit/9a59d08c024479fd3c9d99ba2f0893a47b3980f0) +- Implement initial getLength [`9060c91`](https://github.com/form-data/form-data/commit/9060c91b861a6573b73beddd11e866db422b5830) +- Make getLength work with file streams [`6f6b1e9`](https://github.com/form-data/form-data/commit/6f6b1e9b65951e6314167db33b446351702f5558) +- Implemented a simplistic submit() function [`41e9cc1`](https://github.com/form-data/form-data/commit/41e9cc124124721e53bc1d1459d45db1410c44e6) +- added test for custom headers and content-length in parts (felixge/node-form-data/17) [`b16d14e`](https://github.com/form-data/form-data/commit/b16d14e693670f5d52babec32cdedd1aa07c1aa4) +- Fixed code styling. [`5847424`](https://github.com/form-data/form-data/commit/5847424c666970fc2060acd619e8a78678888a82) +- #29 Added custom filename and content-type options to support identity-less streams. [`adf8b4a`](https://github.com/form-data/form-data/commit/adf8b4a41530795682cd3e35ffaf26b30288ccda) +- Initial Readme and package.json [`8c744e5`](https://github.com/form-data/form-data/commit/8c744e58be4014bdf432e11b718ed87f03e217af) +- allow append() to completely override header and boundary [`3fb2ad4`](https://github.com/form-data/form-data/commit/3fb2ad491f66e4b4ff16130be25b462820b8c972) +- Syntax highlighting [`ab3a6a5`](https://github.com/form-data/form-data/commit/ab3a6a5ed1ab77a2943ce3befcb2bb3cd9ff0330) +- Updated Readme.md [`de8f441`](https://github.com/form-data/form-data/commit/de8f44122ca754cbfedc0d2748e84add5ff0b669) +- Added examples to Readme file. [`c406ac9`](https://github.com/form-data/form-data/commit/c406ac921d299cbc130464ed19338a9ef97cb650) +- pass options.knownLength to set length at beginning, w/o waiting for async size calculation [`e2ac039`](https://github.com/form-data/form-data/commit/e2ac0397ff7c37c3dca74fa9925b55f832e4fa0b) +- Updated dependencies and added test command. [`09bd7cd`](https://github.com/form-data/form-data/commit/09bd7cd86f1ad7a58df1b135eb6eef0d290894b4) +- Bumped version. Updated readme. [`4581140`](https://github.com/form-data/form-data/commit/4581140f322758c6fc92019d342c7d7d6c94af5c) +- Test runner [`1707ebb`](https://github.com/form-data/form-data/commit/1707ebbd180856e6ed44e80c46b02557e2425762) +- Added .npmignore, bumped version. [`2e033e0`](https://github.com/form-data/form-data/commit/2e033e0e4be7c1457be090cd9b2996f19d8fb665) +- FormData.prototype.append takes and passes along options (for header) [`b519203`](https://github.com/form-data/form-data/commit/b51920387ed4da7b4e106fc07b9459f26b5ae2f0) +- Make package.json JSON [`bf1b58d`](https://github.com/form-data/form-data/commit/bf1b58df794b10fda86ed013eb9237b1e5032085) +- Add dependencies to package.json [`7413d0b`](https://github.com/form-data/form-data/commit/7413d0b4cf5546312d47ea426db8180619083974) +- Add convenient submit() interface [`55855e4`](https://github.com/form-data/form-data/commit/55855e4bea14585d4a3faf9e7318a56696adbc7d) +- Fix content type [`08b6ae3`](https://github.com/form-data/form-data/commit/08b6ae337b23ef1ba457ead72c9b133047df213c) +- Combatting travis rvm calls. [`409adfd`](https://github.com/form-data/form-data/commit/409adfd100a3cf4968a632c05ba58d92d262d144) +- Fixed Issue #2 [`b3a5d66`](https://github.com/form-data/form-data/commit/b3a5d661739dcd6921b444b81d5cb3c32fab655d) +- Fix for #10. [`bab70b9`](https://github.com/form-data/form-data/commit/bab70b9e803e17287632762073d227d6c59989e0) +- Trying workarounds for formidable - 0.6 "love". [`25782a3`](https://github.com/form-data/form-data/commit/25782a3f183d9c30668ec2bca6247ed83f10611c) +- change whitespace to conform with felixge's style guide [`9fa34f4`](https://github.com/form-data/form-data/commit/9fa34f433bece85ef73086a874c6f0164ab7f1f6) +- Add async to deps [`b7d1a6b`](https://github.com/form-data/form-data/commit/b7d1a6b10ee74be831de24ed76843e5a6935f155) +- typo [`7860a9c`](https://github.com/form-data/form-data/commit/7860a9c8a582f0745ce0e4a0549f4bffc29c0b50) +- Bumped version. [`fa36c1b`](https://github.com/form-data/form-data/commit/fa36c1b4229c34b85d7efd41908429b6d1da3bfc) +- Updated .gitignore [`de567bd`](https://github.com/form-data/form-data/commit/de567bde620e53b8e9b0ed3506e79491525ec558) +- Don't rely on resume() being called by pipe [`1deae47`](https://github.com/form-data/form-data/commit/1deae47e042bcd170bd5dbe2b4a4fa5356bb8aa2) +- One more wrong content type [`28f166d`](https://github.com/form-data/form-data/commit/28f166d443e2eb77f2559324014670674b97e46e) +- Another typo [`b959b6a`](https://github.com/form-data/form-data/commit/b959b6a2be061cac17f8d329b89cea109f0f32be) +- Typo [`698fa0a`](https://github.com/form-data/form-data/commit/698fa0aa5dbf4eeb77377415acc202a6fbe3f4a2) +- Being simply dumb. [`b614db8`](https://github.com/form-data/form-data/commit/b614db85702061149fbd98418605106975e72ade) +- Fixed typo in the filename. [`30af6be`](https://github.com/form-data/form-data/commit/30af6be13fb0c9e92b32e935317680b9d7599928) diff --git a/Readme.md b/README.md similarity index 87% rename from Readme.md rename to README.md index b09df6a4..262ccf50 100644 --- a/Readme.md +++ b/README.md @@ -42,7 +42,7 @@ var http = require('http'); var form = new FormData(); -http.request('http://nodejs.org/images/logo.png', function(response) { +http.request('http://nodejs.org/images/logo.png', function (response) { form.append('my_field', 'my value'); form.append('my_buffer', new Buffer(10)); form.append('my_logo', response); @@ -65,7 +65,7 @@ form.append('my_logo', request('http://nodejs.org/images/logo.png')); In order to submit this form to a web application, call ```submit(url, [callback])``` method: ``` javascript -form.submit('http://example.org/', function(err, res) { +form.submit('http://example.org/', function (err, res) { // res – response object (http.IncomingMessage) // res.resume(); }); @@ -104,7 +104,7 @@ var request = http.request({ form.pipe(request); -request.on('response', function(res) { +request.on('response', function (res) { console.log(res.statusCode); }); ``` @@ -112,7 +112,7 @@ request.on('response', function(res) { Or if you would prefer the `'Content-Length'` header to be set for you: ``` javascript -form.submit('example.org/upload', function(err, res) { +form.submit('example.org/upload', function (err, res) { console.log(res.statusCode); }); ``` @@ -130,7 +130,7 @@ var options = { form.append('my_buffer', buffer, options); -form.submit('http://example.com/', function(err, res) { +form.submit('http://example.com/', function (err, res) { if (err) throw err; console.log('Done'); }); @@ -139,7 +139,7 @@ form.submit('http://example.com/', function(err, res) { Form-Data can recognize and fetch all the required information from common types of streams (```fs.readStream```, ```http.response``` and ```mikeal's request```), for some other types of streams you'd need to provide "file"-related information manually: ``` javascript -someModule.stream(function(err, stdout, stderr) { +someModule.stream(function (err, stdout, stderr) { if (err) throw err; var form = new FormData(); @@ -151,7 +151,7 @@ someModule.stream(function(err, stdout, stderr) { knownLength: 19806 }); - form.submit('http://example.com/', function(err, res) { + form.submit('http://example.com/', function (err, res) { if (err) throw err; console.log('Done'); }); @@ -167,7 +167,7 @@ form.submit({ host: 'example.com', path: '/probably.php?extra=params', auth: 'username:password' -}, function(err, res) { +}, function (err, res) { console.log(res.statusCode); }); ``` @@ -178,8 +178,8 @@ In case you need to also send custom HTTP headers with the POST request, you can form.submit({ host: 'example.com', path: '/surelynot.php', - headers: {'x-test-header': 'test-header-value'} -}, function(err, res) { + headers: { 'x-test-header': 'test-header-value' } +}, function (err, res) { console.log(res.statusCode); }); ``` @@ -201,20 +201,20 @@ form.submit({ Append data to the form. You can submit about any format (string, integer, boolean, buffer, etc.). However, Arrays are not supported and need to be turned into strings by the user. ```javascript var form = new FormData(); -form.append( 'my_string', 'my value' ); -form.append( 'my_integer', 1 ); -form.append( 'my_boolean', true ); -form.append( 'my_buffer', new Buffer(10) ); -form.append( 'my_array_as_json', JSON.stringify( ['bird','cute'] ) ) +form.append('my_string', 'my value'); +form.append('my_integer', 1); +form.append('my_boolean', true); +form.append('my_buffer', new Buffer(10)); +form.append('my_array_as_json', JSON.stringify(['bird', 'cute'])); ``` You may provide a string for options, or an object. ```javascript // Set filename by providing a string for options -form.append( 'my_file', fs.createReadStream('/foo/bar.jpg'), 'bar.jpg' ); +form.append('my_file', fs.createReadStream('/foo/bar.jpg'), 'bar.jpg'); // provide an object. -form.append( 'my_file', fs.createReadStream('/foo/bar.jpg'), {filename: 'bar.jpg', contentType: 'image/jpeg', knownLength: 19806} ); +form.append('my_file', fs.createReadStream('/foo/bar.jpg'), { filename: 'bar.jpg', contentType: 'image/jpeg', knownLength: 19806 }); ``` #### _Headers_ getHeaders( [**Headers** _userHeaders_] ) @@ -236,13 +236,10 @@ _Note: The boundary must be unique and may not appear in the data._ Return the full formdata request package, as a Buffer. You can insert this Buffer in e.g. Axios to send multipart data. ```javascript var form = new FormData(); -form.append( 'my_buffer', Buffer.from([0x4a,0x42,0x20,0x52,0x6f,0x63,0x6b,0x73]) ); -form.append( 'my_file', fs.readFileSync('/foo/bar.jpg') ); +form.append('my_buffer', Buffer.from([0x4a,0x42,0x20,0x52,0x6f,0x63,0x6b,0x73])); +form.append('my_file', fs.readFileSync('/foo/bar.jpg')); -axios.post( 'https://example.com/path/to/api', - form.getBuffer(), - form.getHeaders() - ) +axios.post('https://example.com/path/to/api', form.getBuffer(), form.getHeaders()); ``` **Note:** Because the output is of type Buffer, you can only append types that are accepted by Buffer: *string, Buffer, ArrayBuffer, Array, or Array-like Object*. A ReadStream for example will result in an error. @@ -251,10 +248,10 @@ Same as `getLength` but synchronous. _Note: getLengthSync __doesn't__ calculate streams length._ -#### _Integer_ getLength( **function** _callback_ ) +#### _Integer_ getLength(**function** _callback_ ) Returns the `Content-Length` async. The callback is used to handle errors and continue once the length has been calculated ```javascript -this.getLength(function(err, length) { +this.getLength(function (err, length) { if (err) { this._error(err); return; @@ -270,13 +267,13 @@ this.getLength(function(err, length) { #### _Boolean_ hasKnownLength() Checks if the length of added values is known. -#### _Request_ submit( _params_, **function** _callback_ ) +#### _Request_ submit(_params_, **function** _callback_ ) Submit the form to a web application. ```javascript var form = new FormData(); -form.append( 'my_string', 'Hello World' ); +form.append('my_string', 'Hello World'); -form.submit( 'http://example.com/', function(err, res) { +form.submit('http://example.com/', function (err, res) { // res – response object (http.IncomingMessage) // res.resume(); } ); @@ -297,7 +294,7 @@ var formData = { my_file: fs.createReadStream(__dirname + '/unicycle.jpg'), }; -request.post({url:'http://service.com/upload', formData: formData}, function(err, httpResponse, body) { +request.post({url:'http://service.com/upload', formData: formData}, function (err, httpResponse, body) { if (err) { return console.error('upload failed:', err); } @@ -317,9 +314,9 @@ var form = new FormData(); form.append('a', 1); fetch('http://example.com', { method: 'POST', body: form }) - .then(function(res) { + .then(function (res) { return res.json(); - }).then(function(json) { + }).then(function (json) { console.log(json); }); ``` @@ -341,8 +338,8 @@ axios.post('http://example.com', form, { ...formHeaders, }, }) -.then(response => response) -.catch(error => error) + .then(response => response) + .catch(error => error) ``` ## Notes diff --git a/lib/browser.js b/lib/browser.js index 09e7c70e..8950a913 100644 --- a/lib/browser.js +++ b/lib/browser.js @@ -1,2 +1,4 @@ +'use strict'; + /* eslint-env browser */ -module.exports = typeof self == 'object' ? self.FormData : window.FormData; +module.exports = typeof self === 'object' ? self.FormData : window.FormData; diff --git a/lib/form_data.js b/lib/form_data.js index 18dc819c..8f5f4b5d 100644 --- a/lib/form_data.js +++ b/lib/form_data.js @@ -1,3 +1,5 @@ +'use strict'; + var CombinedStream = require('combined-stream'); var util = require('util'); var path = require('path'); @@ -6,23 +8,20 @@ var https = require('https'); var parseUrl = require('url').parse; var fs = require('fs'); var Stream = require('stream').Stream; +var crypto = require('crypto'); var mime = require('mime-types'); var asynckit = require('asynckit'); +var setToStringTag = require('es-set-tostringtag'); +var hasOwn = require('hasown'); var populate = require('./populate.js'); -// Public API -module.exports = FormData; - -// make it a Stream -util.inherits(FormData, CombinedStream); - /** * Create readable "multipart/form-data" streams. * Can be used to submit forms * and file uploads to other web applications. * * @constructor - * @param {Object} options - Properties to be added/overriden for FormData and CombinedStream + * @param {object} options - Properties to be added/overriden for FormData and CombinedStream */ function FormData(options) { if (!(this instanceof FormData)) { @@ -35,35 +34,39 @@ function FormData(options) { CombinedStream.call(this); - options = options || {}; - for (var option in options) { + options = options || {}; // eslint-disable-line no-param-reassign + for (var option in options) { // eslint-disable-line no-restricted-syntax this[option] = options[option]; } } +// make it a Stream +util.inherits(FormData, CombinedStream); + FormData.LINE_BREAK = '\r\n'; FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream'; -FormData.prototype.append = function(field, value, options) { - - options = options || {}; +FormData.prototype.append = function (field, value, options) { + options = options || {}; // eslint-disable-line no-param-reassign // allow filename as single option - if (typeof options == 'string') { - options = {filename: options}; + if (typeof options === 'string') { + options = { filename: options }; // eslint-disable-line no-param-reassign } var append = CombinedStream.prototype.append.bind(this); // all that streamy business can't handle numbers - if (typeof value == 'number') { - value = '' + value; + if (typeof value === 'number' || value == null) { + value = String(value); // eslint-disable-line no-param-reassign } // https://github.com/felixge/node-form-data/issues/38 - if (util.isArray(value)) { - // Please convert your array into string - // the way web server expects it + if (Array.isArray(value)) { + /* + * Please convert your array into string + * the way web server expects it + */ this._error(new Error('Arrays are not supported.')); return; } @@ -79,15 +82,17 @@ FormData.prototype.append = function(field, value, options) { this._trackLength(header, value, options); }; -FormData.prototype._trackLength = function(header, value, options) { +FormData.prototype._trackLength = function (header, value, options) { var valueLength = 0; - // used w/ getLengthSync(), when length is known. - // e.g. for streaming directly from a remote server, - // w/ a known file a size, and not wanting to wait for - // incoming file to finish to get its size. + /* + * used w/ getLengthSync(), when length is known. + * e.g. for streaming directly from a remote server, + * w/ a known file a size, and not wanting to wait for + * incoming file to finish to get its size. + */ if (options.knownLength != null) { - valueLength += +options.knownLength; + valueLength += Number(options.knownLength); } else if (Buffer.isBuffer(value)) { valueLength = value.length; } else if (typeof value === 'string') { @@ -97,12 +102,10 @@ FormData.prototype._trackLength = function(header, value, options) { this._valueLength += valueLength; // @check why add CRLF? does this account for custom/multiple CRLFs? - this._overheadLength += - Buffer.byteLength(header) + - FormData.LINE_BREAK.length; + this._overheadLength += Buffer.byteLength(header) + FormData.LINE_BREAK.length; // empty or either doesn't have path or not an http response or not a stream - if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) && !(value instanceof Stream))) { + if (!value || (!value.path && !(value.readable && hasOwn(value, 'httpVersion')) && !(value instanceof Stream))) { return; } @@ -112,10 +115,8 @@ FormData.prototype._trackLength = function(header, value, options) { } }; -FormData.prototype._lengthRetriever = function(value, callback) { - - if (value.hasOwnProperty('fd')) { - +FormData.prototype._lengthRetriever = function (value, callback) { + if (hasOwn(value, 'fd')) { // take read range into a account // `end` = Infinity –> read file till the end // @@ -124,54 +125,52 @@ FormData.prototype._lengthRetriever = function(value, callback) { // Fix it when node fixes it. // https://github.com/joyent/node/issues/7819 if (value.end != undefined && value.end != Infinity && value.start != undefined) { - // when end specified // no need to calculate range // inclusive, starts with 0 - callback(null, value.end + 1 - (value.start ? value.start : 0)); + callback(null, value.end + 1 - (value.start ? value.start : 0)); // eslint-disable-line callback-return - // not that fast snoopy + // not that fast snoopy } else { // still need to fetch file size from fs - fs.stat(value.path, function(err, stat) { - - var fileSize; - + fs.stat(value.path, function (err, stat) { if (err) { callback(err); return; } // update final size based on the range options - fileSize = stat.size - (value.start ? value.start : 0); + var fileSize = stat.size - (value.start ? value.start : 0); callback(null, fileSize); }); } - // or http response - } else if (value.hasOwnProperty('httpVersion')) { - callback(null, +value.headers['content-length']); + // or http response + } else if (hasOwn(value, 'httpVersion')) { + callback(null, Number(value.headers['content-length'])); // eslint-disable-line callback-return - // or request stream http://github.com/mikeal/request - } else if (value.hasOwnProperty('httpModule')) { + // or request stream http://github.com/mikeal/request + } else if (hasOwn(value, 'httpModule')) { // wait till response come back - value.on('response', function(response) { + value.on('response', function (response) { value.pause(); - callback(null, +response.headers['content-length']); + callback(null, Number(response.headers['content-length'])); }); value.resume(); - // something else + // something else } else { - callback('Unknown stream'); + callback('Unknown stream'); // eslint-disable-line callback-return } }; -FormData.prototype._multiPartHeader = function(field, value, options) { - // custom header specified (as string)? - // it becomes responsible for boundary - // (e.g. to handle extra CRLFs on .NET servers) - if (typeof options.header == 'string') { +FormData.prototype._multiPartHeader = function (field, value, options) { + /* + * custom header specified (as string)? + * it becomes responsible for boundary + * (e.g. to handle extra CRLFs on .NET servers) + */ + if (typeof options.header === 'string') { return options.header; } @@ -179,7 +178,7 @@ FormData.prototype._multiPartHeader = function(field, value, options) { var contentType = this._getContentType(value, options); var contents = ''; - var headers = { + var headers = { // add custom disposition as third element or keep it two elements if not 'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []), // if no content type. allow it to be empty array @@ -187,77 +186,74 @@ FormData.prototype._multiPartHeader = function(field, value, options) { }; // allow custom headers. - if (typeof options.header == 'object') { + if (typeof options.header === 'object') { populate(headers, options.header); } var header; - for (var prop in headers) { - if (!headers.hasOwnProperty(prop)) continue; - header = headers[prop]; + for (var prop in headers) { // eslint-disable-line no-restricted-syntax + if (hasOwn(headers, prop)) { + header = headers[prop]; - // skip nullish headers. - if (header == null) { - continue; - } + // skip nullish headers. + if (header == null) { + continue; // eslint-disable-line no-restricted-syntax, no-continue + } - // convert all headers to arrays. - if (!Array.isArray(header)) { - header = [header]; - } + // convert all headers to arrays. + if (!Array.isArray(header)) { + header = [header]; + } - // add non-empty headers. - if (header.length) { - contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK; + // add non-empty headers. + if (header.length) { + contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK; + } } } return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK; }; -FormData.prototype._getContentDisposition = function(value, options) { - - var filename - , contentDisposition - ; +FormData.prototype._getContentDisposition = function (value, options) { // eslint-disable-line consistent-return + var filename; if (typeof options.filepath === 'string') { // custom filepath for relative paths filename = path.normalize(options.filepath).replace(/\\/g, '/'); - } else if (options.filename || value.name || value.path) { - // custom filename take precedence - // formidable and the browser add a name property - // fs- and request- streams have path property - filename = path.basename(options.filename || value.name || value.path); - } else if (value.readable && value.hasOwnProperty('httpVersion')) { + } else if (options.filename || (value && (value.name || value.path))) { + /* + * custom filename take precedence + * formidable and the browser add a name property + * fs- and request- streams have path property + */ + filename = path.basename(options.filename || (value && (value.name || value.path))); + } else if (value && value.readable && hasOwn(value, 'httpVersion')) { // or try http response filename = path.basename(value.client._httpMessage.path || ''); } if (filename) { - contentDisposition = 'filename="' + filename + '"'; + return 'filename="' + filename + '"'; } - - return contentDisposition; }; -FormData.prototype._getContentType = function(value, options) { - +FormData.prototype._getContentType = function (value, options) { // use custom content-type above all var contentType = options.contentType; // or try `name` from formidable, browser - if (!contentType && value.name) { + if (!contentType && value && value.name) { contentType = mime.lookup(value.name); } // or try `path` from fs-, request- streams - if (!contentType && value.path) { + if (!contentType && value && value.path) { contentType = mime.lookup(value.path); } // or if it's http-reponse - if (!contentType && value.readable && value.hasOwnProperty('httpVersion')) { + if (!contentType && value && value.readable && hasOwn(value, 'httpVersion')) { contentType = value.headers['content-type']; } @@ -267,18 +263,18 @@ FormData.prototype._getContentType = function(value, options) { } // fallback to the default content type if `value` is not simple value - if (!contentType && typeof value == 'object') { + if (!contentType && value && typeof value === 'object') { contentType = FormData.DEFAULT_CONTENT_TYPE; } return contentType; }; -FormData.prototype._multiPartFooter = function() { - return function(next) { +FormData.prototype._multiPartFooter = function () { + return function (next) { var footer = FormData.LINE_BREAK; - var lastPart = (this._streams.length === 0); + var lastPart = this._streams.length === 0; if (lastPart) { footer += this._lastBoundary(); } @@ -287,18 +283,18 @@ FormData.prototype._multiPartFooter = function() { }.bind(this); }; -FormData.prototype._lastBoundary = function() { +FormData.prototype._lastBoundary = function () { return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK; }; -FormData.prototype.getHeaders = function(userHeaders) { +FormData.prototype.getHeaders = function (userHeaders) { var header; var formHeaders = { 'content-type': 'multipart/form-data; boundary=' + this.getBoundary() }; - for (header in userHeaders) { - if (userHeaders.hasOwnProperty(header)) { + for (header in userHeaders) { // eslint-disable-line no-restricted-syntax + if (hasOwn(userHeaders, header)) { formHeaders[header.toLowerCase()] = userHeaders[header]; } } @@ -306,11 +302,14 @@ FormData.prototype.getHeaders = function(userHeaders) { return formHeaders; }; -FormData.prototype.setBoundary = function(boundary) { +FormData.prototype.setBoundary = function (boundary) { + if (typeof boundary !== 'string') { + throw new TypeError('FormData boundary must be a string'); + } this._boundary = boundary; }; -FormData.prototype.getBoundary = function() { +FormData.prototype.getBoundary = function () { if (!this._boundary) { this._generateBoundary(); } @@ -318,60 +317,55 @@ FormData.prototype.getBoundary = function() { return this._boundary; }; -FormData.prototype.getBuffer = function() { - var dataBuffer = new Buffer.alloc( 0 ); +FormData.prototype.getBuffer = function () { + var dataBuffer = new Buffer.alloc(0); // eslint-disable-line new-cap var boundary = this.getBoundary(); // Create the form content. Add Line breaks to the end of data. for (var i = 0, len = this._streams.length; i < len; i++) { if (typeof this._streams[i] !== 'function') { - // Add content to the buffer. - if(Buffer.isBuffer(this._streams[i])) { - dataBuffer = Buffer.concat( [dataBuffer, this._streams[i]]); - }else { - dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(this._streams[i])]); + if (Buffer.isBuffer(this._streams[i])) { + dataBuffer = Buffer.concat([dataBuffer, this._streams[i]]); + } else { + dataBuffer = Buffer.concat([dataBuffer, Buffer.from(this._streams[i])]); } // Add break after content. - if (typeof this._streams[i] !== 'string' || this._streams[i].substring( 2, boundary.length + 2 ) !== boundary) { - dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(FormData.LINE_BREAK)] ); + if (typeof this._streams[i] !== 'string' || this._streams[i].substring(2, boundary.length + 2) !== boundary) { + dataBuffer = Buffer.concat([dataBuffer, Buffer.from(FormData.LINE_BREAK)]); } } } // Add the footer and return the Buffer object. - return Buffer.concat( [dataBuffer, Buffer.from(this._lastBoundary())] ); + return Buffer.concat([dataBuffer, Buffer.from(this._lastBoundary())]); }; -FormData.prototype._generateBoundary = function() { +FormData.prototype._generateBoundary = function () { // This generates a 50 character boundary similar to those used by Firefox. - // They are optimized for boyer-moore parsing. - var boundary = '--------------------------'; - for (var i = 0; i < 24; i++) { - boundary += Math.floor(Math.random() * 10).toString(16); - } - this._boundary = boundary; + // They are optimized for boyer-moore parsing. + this._boundary = '--------------------------' + crypto.randomBytes(12).toString('hex'); }; // Note: getLengthSync DOESN'T calculate streams length -// As workaround one can calculate file size manually -// and add it as knownLength option -FormData.prototype.getLengthSync = function() { +// As workaround one can calculate file size manually and add it as knownLength option +FormData.prototype.getLengthSync = function () { var knownLength = this._overheadLength + this._valueLength; - // Don't get confused, there are 3 "internal" streams for each keyval pair - // so it basically checks if there is any value added to the form + // Don't get confused, there are 3 "internal" streams for each keyval pair so it basically checks if there is any value added to the form if (this._streams.length) { knownLength += this._lastBoundary().length; } // https://github.com/form-data/form-data/issues/40 if (!this.hasKnownLength()) { - // Some async length retrievers are present - // therefore synchronous length calculation is false. - // Please use getLength(callback) to get proper length + /* + * Some async length retrievers are present + * therefore synchronous length calculation is false. + * Please use getLength(callback) to get proper length + */ this._error(new Error('Cannot calculate proper length in synchronous way.')); } @@ -381,7 +375,7 @@ FormData.prototype.getLengthSync = function() { // Public API to check if length of added values is known // https://github.com/form-data/form-data/issues/196 // https://github.com/form-data/form-data/issues/262 -FormData.prototype.hasKnownLength = function() { +FormData.prototype.hasKnownLength = function () { var hasKnownLength = true; if (this._valuesToMeasure.length) { @@ -391,7 +385,7 @@ FormData.prototype.hasKnownLength = function() { return hasKnownLength; }; -FormData.prototype.getLength = function(cb) { +FormData.prototype.getLength = function (cb) { var knownLength = this._overheadLength + this._valueLength; if (this._streams.length) { @@ -403,13 +397,13 @@ FormData.prototype.getLength = function(cb) { return; } - asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) { + asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function (err, values) { if (err) { cb(err); return; } - values.forEach(function(length) { + values.forEach(function (length) { knownLength += length; }); @@ -417,31 +411,26 @@ FormData.prototype.getLength = function(cb) { }); }; -FormData.prototype.submit = function(params, cb) { - var request - , options - , defaults = {method: 'post'} - ; - - // parse provided url if it's string - // or treat it as options object - if (typeof params == 'string') { +FormData.prototype.submit = function (params, cb) { + var request; + var options; + var defaults = { method: 'post' }; - params = parseUrl(params); + // parse provided url if it's string or treat it as options object + if (typeof params === 'string') { + params = parseUrl(params); // eslint-disable-line no-param-reassign + /* eslint sort-keys: 0 */ options = populate({ port: params.port, path: params.pathname, host: params.hostname, protocol: params.protocol }, defaults); - - // use custom params - } else { - + } else { // use custom params options = populate(params, defaults); // if no port provided use default one if (!options.port) { - options.port = options.protocol == 'https:' ? 443 : 80; + options.port = options.protocol === 'https:' ? 443 : 80; } } @@ -449,14 +438,14 @@ FormData.prototype.submit = function(params, cb) { options.headers = this.getHeaders(params.headers); // https if specified, fallback to http in any other case - if (options.protocol == 'https:') { + if (options.protocol === 'https:') { request = https.request(options); } else { request = http.request(options); } // get content length and fire away - this.getLength(function(err, length) { + this.getLength(function (err, length) { if (err && err !== 'Unknown stream') { this._error(err); return; @@ -475,7 +464,7 @@ FormData.prototype.submit = function(params, cb) { request.removeListener('error', callback); request.removeListener('response', onResponse); - return cb.call(this, error, responce); + return cb.call(this, error, responce); // eslint-disable-line no-invalid-this }; onResponse = callback.bind(this, null); @@ -488,7 +477,7 @@ FormData.prototype.submit = function(params, cb) { return request; }; -FormData.prototype._error = function(err) { +FormData.prototype._error = function (err) { if (!this.error) { this.error = err; this.pause(); @@ -499,3 +488,7 @@ FormData.prototype._error = function(err) { FormData.prototype.toString = function () { return '[object FormData]'; }; +setToStringTag(FormData, 'FormData'); + +// Public API +module.exports = FormData; diff --git a/lib/populate.js b/lib/populate.js index 4d35738d..55ac3bb2 100644 --- a/lib/populate.js +++ b/lib/populate.js @@ -1,9 +1,9 @@ -// populates missing values -module.exports = function(dst, src) { +'use strict'; - Object.keys(src).forEach(function(prop) - { - dst[prop] = dst[prop] || src[prop]; +// populates missing values +module.exports = function (dst, src) { + Object.keys(src).forEach(function (prop) { + dst[prop] = dst[prop] || src[prop]; // eslint-disable-line no-param-reassign }); return dst; diff --git a/package.json b/package.json index 0f20240b..e8d1e7dd 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Felix Geisendörfer (http://debuggable.com/)", "name": "form-data", "description": "A library to create readable \"multipart/form-data\" streams. Can be used to submit forms and file uploads to other web applications.", - "version": "4.0.0", + "version": "4.0.4", "repository": { "type": "git", "url": "git://github.com/form-data/form-data.git" @@ -11,13 +11,16 @@ "browser": "./lib/browser", "typings": "./index.d.ts", "scripts": { - "pretest": "rimraf coverage test/tmp", - "test": "istanbul cover test/run.js", - "posttest": "istanbul report lcov text", - "lint": "eslint lib/*.js test/*.js test/integration/*.js", + "pretest": "npm run lint", + "pretests-only": "rimraf coverage test/tmp", + "tests-only": "istanbul cover test/run.js", + "posttests-only": "istanbul report lcov text", + "test": "npm run tests-only", + "posttest": "npx npm@'>=10.2' audit --production", + "lint": "eslint --ext=js,mjs .", "report": "istanbul report lcov text", "ci-lint": "is-node-modern 8 && npm run lint || is-node-not-modern 8", - "ci-test": "npm run test && npm run browser && npm run report", + "ci-test": "npm run tests-only && npm run browser && npm run report", "predebug": "rimraf coverage test/tmp", "debug": "verbose=1 ./test/run.js", "browser": "browserify -t browserify-istanbul test/run-browser.js | obake --coverage", @@ -25,44 +28,55 @@ "files": "pkgfiles --sort=name", "get-version": "node -e \"console.log(require('./package.json').version)\"", "update-readme": "sed -i.bak 's/\\/master\\.svg/\\/v'$(npm --silent run get-version)'.svg/g' README.md", - "restore-readme": "mv README.md.bak README.md", - "prepublish": "in-publish && npm run update-readme || not-in-publish", - "postpublish": "npm run restore-readme" + "postupdate-readme": "mv README.md.bak READ.ME.md.bak", + "restore-readme": "mv READ.ME.md.bak README.md", + "prepublish": "not-in-publish || npm run prepublishOnly", + "prepack": "npm run update-readme", + "postpack": "npm run restore-readme", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" }, - "pre-commit": [ - "lint", - "ci-test", - "check" - ], "engines": { "node": ">= 6" }, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "devDependencies": { - "@types/node": "^12.0.10", - "browserify": "^13.1.1", + "@ljharb/eslint-config": "^21.2.0", + "auto-changelog": "^2.5.0", + "browserify": "^13.3.0", "browserify-istanbul": "^2.0.0", - "coveralls": "^3.0.4", - "cross-spawn": "^6.0.5", - "eslint": "^6.0.1", + "coveralls": "^3.1.1", + "cross-spawn": "^6.0.6", + "eslint": "=8.8.0", "fake": "^0.2.2", "far": "^0.0.7", - "formidable": "^1.0.17", - "in-publish": "^2.0.0", + "formidable": "^1.2.6", + "in-publish": "^2.0.1", "is-node-modern": "^1.0.0", "istanbul": "^0.4.5", "obake": "^0.1.2", - "puppeteer": "^1.19.0", - "pkgfiles": "^2.3.0", - "pre-commit": "^1.1.3", - "request": "^2.88.0", + "pkgfiles": "^2.3.2", + "pre-commit": "^1.2.2", + "predict-v8-randomness": "^1.0.35", + "puppeteer": "^1.20.0", + "request": "~2.87.0", "rimraf": "^2.7.1", - "tape": "^4.6.2", - "typescript": "^3.5.2" + "semver": "^6.3.1", + "tape": "^5.9.0" }, - "license": "MIT" + "license": "MIT", + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + } } diff --git a/test/common.js b/test/common.js index 7da855c1..53e27c32 100644 --- a/test/common.js +++ b/test/common.js @@ -5,6 +5,7 @@ var fake = require('fake'); var mime = require('mime-types'); var http = require('http'); var IncomingForm = require('formidable').IncomingForm; +var hasOwn = require('hasown'); var common = module.exports; @@ -32,18 +33,16 @@ common.httpsServerKey = fs.readFileSync(path.join(__dirname, './fixture/key.pem' common.httpsServerCert = fs.readFileSync(path.join(__dirname, './fixture/cert.pem')); common.testFields = function (FIELDS, callback) { - var fieldsPassed = Object.keys(FIELDS).length; return http.createServer(function (req, res) { - - var incomingForm = new IncomingForm({uploadDir: common.dir.tmp}); + var incomingForm = new IncomingForm({ uploadDir: common.dir.tmp }); incomingForm.parse(req); - + common.actions.checkForm(incomingForm, FIELDS, function (fieldsChecked) { // keep track of number of the processed fields - callback(fieldsPassed - fieldsChecked); + callback(fieldsPassed - fieldsChecked); // eslint-disable-line callback-return // finish it common.actions.formOnEnd(res); }); @@ -55,26 +54,23 @@ common.testFields = function (FIELDS, callback) { common.actions = {}; // generic form field population -common.actions.populateFields = function(form, fields) -{ +common.actions.populateFields = function (form, fields) { var field; - for (var name in fields) { - if (!fields.hasOwnProperty(name)) { continue; } - - field = fields[name]; - // important to append ReadStreams within the same tick - if ((typeof field.value == 'function')) { - field.value = field.value(); + for (var name in fields) { // eslint-disable-line no-restricted-syntax + if (hasOwn(fields, name)) { + field = fields[name]; + // important to append ReadStreams within the same tick + if (typeof field.value == 'function') { + field.value = field.value(); + } + form.append(name, field.value); } - form.append(name, field.value); } }; // generic form submit -common.actions.submit = function(form, server) -{ - return form.submit('http://localhost:' + common.port + '/', function(err, res) { - +common.actions.submit = function (form, server) { + return form.submit('http://localhost:' + common.port + '/', function (err, res) { if (err) { throw err; } @@ -88,36 +84,35 @@ common.actions.submit = function(form, server) }); }; -common.actions.checkForm = function(form, fields, callback) -{ +common.actions.checkForm = function (form, fields, callback) { var fieldChecked = 0; form - .on('field', function(name, value) { + .on('field', function (name, value) { fieldChecked++; common.actions.formOnField(fields, name, value); }) - .on('file', function(name, file) { + .on('file', function (name, file) { fieldChecked++; common.actions.formOnFile(fields, name, file); }) - .on('end', function() { + .on('end', function () { callback(fieldChecked); }); }; -common.actions.basicFormOnField = function(name, value) { +common.actions.basicFormOnField = function (name, value) { assert.strictEqual(name, 'my_field'); assert.strictEqual(value, 'my_value'); }; -common.actions.formOnField = function(FIELDS, name, value) { +common.actions.formOnField = function (FIELDS, name, value) { assert.ok(name in FIELDS); var field = FIELDS[name]; - assert.strictEqual(value, field.value + ''); + assert.strictEqual(value, String(field.value)); }; -common.actions.formOnFile = function(FIELDS, name, file) { +common.actions.formOnFile = function (FIELDS, name, file) { assert.ok(name in FIELDS); var field = FIELDS[name]; assert.strictEqual(file.name, path.basename(field.value.path || field.name)); @@ -125,7 +120,7 @@ common.actions.formOnFile = function(FIELDS, name, file) { }; // after form has finished parsing -common.actions.formOnEnd = function(res) { +common.actions.formOnEnd = function (res) { res.writeHead(200); res.end('done'); }; diff --git a/test/integration/test-boundary-prediction.js b/test/integration/test-boundary-prediction.js new file mode 100644 index 00000000..8527be0a --- /dev/null +++ b/test/integration/test-boundary-prediction.js @@ -0,0 +1,53 @@ +var common = require('../common'); +var assert = common.assert; +var FormData = require(common.dir.lib + '/form_data'); +var satisfies = require('semver').satisfies; +var predictV8Randomness = satisfies(process.version, '^17 - ^23') && require('predict-v8-randomness'); // eslint-disable-line global-require + +var initialSequence = [ + Math.random(), + Math.random(), + Math.random(), + Math.random() +]; +var predictor = predictV8Randomness && new predictV8Randomness.Predictor(initialSequence); + +if (predictor) { + predictor.predictNext(24).then(function (next24RandomOutputs) { + var predictedBoundary = next24RandomOutputs + .map(function (v) { + return Math.floor(v * 10).toString(16); + }) + .join(''); + + var boundaryIntro = '----------------------------'; + + var payload = 'zzz\r\n' + boundaryIntro + predictedBoundary + '\r\nContent-Disposition: form-data; name="is_admin"\r\n\r\ntrue\r\n' + boundaryIntro + predictedBoundary + '--\r\n'; + + var FIELDS = { + my_field: { + value: payload + } + }; + + // count total + var fieldsPassed = Object.keys(FIELDS).length; + + // prepare form-receiving http server + var server = common.testFields(FIELDS, function (fields) { + fieldsPassed = fields; + }); + + server.listen(common.port, function () { + var form = new FormData(); + + common.actions.populateFields(form, FIELDS); + + common.actions.submit(form, server); + }); + + process.on('exit', function () { + assert.strictEqual(fieldsPassed, 0); + }); + }); +} diff --git a/test/integration/test-custom-content-type.js b/test/integration/test-custom-content-type.js index d8c1b765..ee3c4244 100644 --- a/test/integration/test-custom-content-type.js +++ b/test/integration/test-custom-content-type.js @@ -1,42 +1,48 @@ +'use strict'; + var common = require('../common'); var assert = common.assert; var http = require('http'); var mime = require('mime-types'); var fs = require('fs'); +var hasOwn = require('hasown'); + var FormData = require(common.dir.lib + '/form_data'); -// wrap non simple values into function -// just to deal with ReadStream "autostart" +/* + * wrap non simple values into function + * just to deal with ReadStream "autostart" + */ var FIELDS = { - 'no_type': { + no_type: { value: 'my_value' }, - 'custom_type': { + custom_type: { value: 'my_value', expectedType: 'image/png', options: { contentType: 'image/png' } }, - 'default_type': { + default_type: { expectedType: FormData.DEFAULT_CONTENT_TYPE, value: common.defaultTypeValue }, - 'implicit_type': { + implicit_type: { expectedType: mime.lookup(common.dir.fixture + '/unicycle.jpg'), - value: function() { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } + value: function () { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } }, - 'overridden_type': { + overridden_type: { expectedType: 'image/png', options: { contentType: 'image/png' }, - value: function() { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } + value: function () { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } } }; var fieldsPassed = false; -var server = http.createServer(function(req, res) { +var server = http.createServer(function (req, res) { var body = ''; var boundry = req.headers['content-type'].split('boundary=').pop(); @@ -51,10 +57,10 @@ var server = http.createServer(function(req, res) { for (var i = 0; i < fieldNames.length; i++) { assert.ok(fields[i].indexOf('name="' + fieldNames[i] + '"') > -1); - if (!FIELDS[fieldNames[i]].expectedType) { - assert.equal(fields[i].indexOf('Content-Type'), -1, 'Expecting ' + fieldNames[i] + ' not to have Content-Type'); - } else { + if (FIELDS[fieldNames[i]].expectedType) { assert.ok(fields[i].indexOf('Content-Type: ' + FIELDS[fieldNames[i]].expectedType) > -1, 'Expecting ' + fieldNames[i] + ' to have Content-Type ' + FIELDS[fieldNames[i]].expectedType); + } else { + assert.equal(fields[i].indexOf('Content-Type'), -1, 'Expecting ' + fieldNames[i] + ' not to have Content-Type'); } } @@ -63,26 +69,24 @@ var server = http.createServer(function(req, res) { }); }); -server.listen(common.port, function() { - +server.listen(common.port, function () { var form = new FormData(); - var field; - for (var name in FIELDS) { - if (!FIELDS.hasOwnProperty(name)) { continue; } - - field = FIELDS[name]; - // important to append ReadStreams within the same tick - if ((typeof field.value == 'function')) { - field.value = field.value(); + for (var name in FIELDS) { // eslint-disable-line no-restricted-syntax + if (hasOwn(FIELDS, name)) { + var field = FIELDS[name]; + // important to append ReadStreams within the same tick + if (typeof field.value === 'function') { + field.value = field.value(); + } + form.append(name, field.value, field.options); } - form.append(name, field.value, field.options); } // custom params object passed to submit common.actions.submit(form, server); }); -process.on('exit', function() { +process.on('exit', function () { assert.ok(fieldsPassed); }); diff --git a/test/integration/test-custom-filename.js b/test/integration/test-custom-filename.js index c296eb59..a88b037d 100644 --- a/test/integration/test-custom-filename.js +++ b/test/integration/test-custom-filename.js @@ -1,16 +1,18 @@ +'use strict'; + /* -test custom filename and content-type: -re: https://github.com/felixge/node-form-data/issues/29 -*/ - -var common = require('../common'); -var assert = common.assert; -var mime = require('mime-types'); -var http = require('http'); -var fs = require('fs'); -var path = require('path'); - -var FormData = require(common.dir.lib + '/form_data'); + *test custom filename and content-type: + *re: https://github.com/felixge/node-form-data/issues/29 + */ + +var common = require('../common'); +var assert = common.assert; +var mime = require('mime-types'); +var http = require('http'); +var fs = require('fs'); +var path = require('path'); + +var FormData = require(common.dir.lib + '/form_data'); var IncomingForm = require('formidable').IncomingForm; var knownFile = path.join(common.dir.fixture, 'unicycle.jpg'); @@ -22,47 +24,45 @@ var options = { contentType: 'image/gif' }; -var server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); +var server = http.createServer(function (req, res) { + var form = new IncomingForm({ uploadDir: common.dir.tmp }); form.parse(req, function (err, fields, files) { assert(!err); assert('custom_everything' in files); - assert.strictEqual(files['custom_everything'].name, options.filename, 'Expects custom filename'); - assert.strictEqual(files['custom_everything'].type, options.contentType, 'Expects custom content-type'); + assert.strictEqual(files.custom_everything.name, options.filename, 'Expects custom filename'); + assert.strictEqual(files.custom_everything.type, options.contentType, 'Expects custom content-type'); assert('custom_filename' in files); - assert.strictEqual(files['custom_filename'].name, options.filename, 'Expects custom filename'); - assert.strictEqual(files['custom_filename'].type, mime.lookup(knownFile), 'Expects original content-type'); + assert.strictEqual(files.custom_filename.name, options.filename, 'Expects custom filename'); + assert.strictEqual(files.custom_filename.type, mime.lookup(knownFile), 'Expects original content-type'); assert('custom_filepath' in files); - assert.strictEqual(files['custom_filepath'].name, relativeFile.replace(/\\/g, '/'), 'Expects custom filepath'); - assert.strictEqual(files['custom_filepath'].type, mime.lookup(knownFile), 'Expects original content-type'); + assert.strictEqual(files.custom_filepath.name, relativeFile.replace(/\\/g, '/'), 'Expects custom filepath'); + assert.strictEqual(files.custom_filepath.type, mime.lookup(knownFile), 'Expects original content-type'); assert('unknown_with_filename' in files); - assert.strictEqual(files['unknown_with_filename'].name, options.filename, 'Expects custom filename'); - assert.strictEqual(files['unknown_with_filename'].type, mime.lookup(options.filename), 'Expects filename-derived content-type'); + assert.strictEqual(files.unknown_with_filename.name, options.filename, 'Expects custom filename'); + assert.strictEqual(files.unknown_with_filename.type, mime.lookup(options.filename), 'Expects filename-derived content-type'); assert('unknown_with_filename_as_object' in files); - assert.strictEqual(files['unknown_with_filename_as_object'].name, options.filename, 'Expects custom filename'); - assert.strictEqual(files['unknown_with_filename_as_object'].type, mime.lookup(options.filename), 'Expects filename-derived content-type'); + assert.strictEqual(files.unknown_with_filename_as_object.name, options.filename, 'Expects custom filename'); + assert.strictEqual(files.unknown_with_filename_as_object.type, mime.lookup(options.filename), 'Expects filename-derived content-type'); assert('unknown_with_name_prop' in files); - assert.strictEqual(files['unknown_with_name_prop'].name, options.filename, 'Expects custom filename'); - assert.strictEqual(files['unknown_with_name_prop'].type, mime.lookup(options.filename), 'Expects filename-derived content-type'); + assert.strictEqual(files.unknown_with_name_prop.name, options.filename, 'Expects custom filename'); + assert.strictEqual(files.unknown_with_name_prop.type, mime.lookup(options.filename), 'Expects filename-derived content-type'); assert('unknown_everything' in files); - assert.strictEqual(files['unknown_everything'].type, FormData.DEFAULT_CONTENT_TYPE, 'Expects default content-type'); + assert.strictEqual(files.unknown_everything.type, FormData.DEFAULT_CONTENT_TYPE, 'Expects default content-type'); res.writeHead(200); res.end('done'); }); }); - -server.listen(common.port, function() { +server.listen(common.port, function () { var form = new FormData(); // Explicit contentType and filename. @@ -72,9 +72,9 @@ server.listen(common.port, function() { // Filename only with unknown file form.append('unknown_with_filename', fs.createReadStream(unknownFile), options.filename); // Filename only with unknown file - form.append('unknown_with_filename_as_object', fs.createReadStream(unknownFile), {filename: options.filename}); + form.append('unknown_with_filename_as_object', fs.createReadStream(unknownFile), { filename: options.filename }); // Filename with relative path - form.append('custom_filepath', fs.createReadStream(knownFile), {filepath: relativeFile}); + form.append('custom_filepath', fs.createReadStream(knownFile), { filepath: relativeFile }); // No options or implicit file type from extension on name property. var customNameStream = fs.createReadStream(unknownFile); customNameStream.name = options.filename; diff --git a/test/integration/test-custom-headers-object.js b/test/integration/test-custom-headers-object.js index dd401875..2e0295a4 100644 --- a/test/integration/test-custom-headers-object.js +++ b/test/integration/test-custom-headers-object.js @@ -1,7 +1,7 @@ /* -test custom headers object. -https://github.com/form-data/form-data/issues/133 -*/ + *test custom headers object. + *https://github.com/form-data/form-data/issues/133 + */ var common = require('../common'); var assert = common.assert; @@ -13,9 +13,8 @@ var testHeader = { 'X-Test-Fake': 123 }; var expectedLength; - -var server = http.createServer(function(req, res) { - assert.ok( typeof req.headers['content-length'] !== 'undefined' ); +var server = http.createServer(function (req, res) { + assert.ok(typeof req.headers['content-length'] !== 'undefined'); assert.equal(req.headers['content-length'], expectedLength); req.on('data', function (data) { @@ -29,15 +28,16 @@ var server = http.createServer(function(req, res) { res.end('done'); }); - -server.listen(common.port, function() { +server.listen(common.port, function () { var form = new FormData(); var options = { header: testHeader, - // override content-length, - // much lower than actual buffer size (1000) + /* + * override content-length, + * much lower than actual buffer size (1000) + */ knownLength: 1 }; diff --git a/test/integration/test-custom-headers-string.js b/test/integration/test-custom-headers-string.js index a664a1e5..6dd8252b 100644 --- a/test/integration/test-custom-headers-string.js +++ b/test/integration/test-custom-headers-string.js @@ -1,7 +1,7 @@ /* -test custom headers, added in pull request: -https://github.com/felixge/node-form-data/pull/17 -*/ + *test custom headers, added in pull request: + *https://github.com/felixge/node-form-data/pull/17 + */ var common = require('../common'); var assert = common.assert; @@ -15,9 +15,8 @@ var testHeader = 'X-Test-Fake: 123'; var expectedLength; - -var server = http.createServer(function(req, res) { - assert.ok( typeof req.headers['content-length'] !== 'undefined' ); +var server = http.createServer(function (req, res) { + assert.ok(typeof req.headers['content-length'] !== 'undefined'); assert.equal(req.headers['content-length'], expectedLength); req.on('data', function (data) { @@ -31,18 +30,17 @@ var server = http.createServer(function(req, res) { res.end('done'); }); - -server.listen(common.port, function() { +server.listen(common.port, function () { var form = new FormData(); var options = { header: - CRLF + '--' + form.getBoundary() + CRLF + - testHeader + - CRLF + CRLF, + CRLF + '--' + form.getBoundary() + CRLF + testHeader + CRLF + CRLF, - // override content-length, - // much lower than actual buffer size (1000) + /* + * override content-length, + * much lower than actual buffer size (1000) + */ knownLength: 1 }; diff --git a/test/integration/test-errors.js b/test/integration/test-errors.js index 11292268..f01eed04 100644 --- a/test/integration/test-errors.js +++ b/test/integration/test-errors.js @@ -8,20 +8,18 @@ var http = require('http'); // https://github.com/felixge/node-form-data/issues/38 (function testAppendArray() { - var form = new FormData(); var callback = fake.callback('testAppendArray-onError-append'); fake.expectAnytime(callback, ['Arrays are not supported.']); - form.on('error', function(err) { + form.on('error', function (err) { // workaround for expectAnytime handling objects callback(err.message); }); form.append('my_array', ['bird', 'cute']); -})(); - +}()); (function testGetLengthSync() { var fields = [ @@ -38,7 +36,7 @@ var http = require('http'); var form = new FormData(); var expectedLength = 0; - fields.forEach(function(field) { + fields.forEach(function (field) { form.append(field.name, field.value); if (field.value.path) { var stat = fs.statSync(field.value.path); @@ -49,11 +47,10 @@ var http = require('http'); }); expectedLength += form._overheadLength + form._lastBoundary().length; - var callback = fake.callback('testGetLengthSync-onError-getLengthSync'); fake.expectAnytime(callback, ['Cannot calculate proper length in synchronous way.']); - form.on('error', function(err) { + form.on('error', function (err) { // workaroud for expectAnytime handling objects callback(err.message); }); @@ -62,7 +59,7 @@ var http = require('http'); // getLengthSync DOESN'T calculate streams length assert.ok(expectedLength > calculatedLength); -})(); +}()); (function testStreamError() { var req; @@ -75,14 +72,14 @@ var http = require('http'); form.append('fake-stream', src); - form.on('error', function(err) { + form.on('error', function (err) { assert.equal(err.code, 'ENOENT'); assert.equal(err.path, fakePath); - req.on('error', function() {}); + req.on('error', function () {}); server.close(); }); - server.listen(common.port, function() { + server.listen(common.port, function () { req = form.submit(addr); }); -})(); +}()); diff --git a/test/integration/test-form-get-length-sync.js b/test/integration/test-form-get-length-sync.js index 9901c7ef..bbb9120d 100644 --- a/test/integration/test-form-get-length-sync.js +++ b/test/integration/test-form-get-length-sync.js @@ -1,8 +1,11 @@ +'use strict'; + var common = require('../common'); var assert = common.assert; var FormData = require(common.dir.lib + '/form_data'); var fs = require('fs'); var Readable = require('stream').Readable; +var util = require('util'); (function testGetLengthSync() { var fields = [ @@ -23,17 +26,16 @@ var Readable = require('stream').Readable; var form = new FormData(); var expectedLength = 0; - fields.forEach(function(field) { + fields.forEach(function (field) { form.append(field.name, field.value); - expectedLength += ('' + field.value).length; + expectedLength += String(field.value).length; }); expectedLength += form._overheadLength + form._lastBoundary().length; var calculatedLength = form.getLengthSync(); assert.equal(expectedLength, calculatedLength); -})(); - +}()); (function testGetLengthSyncWithKnownLength() { var fields = [ @@ -59,13 +61,13 @@ var Readable = require('stream').Readable; var form = new FormData(); var expectedLength = 0; - fields.forEach(function(field) { + fields.forEach(function (field) { form.append(field.name, field.value, field.options); if (field.value.path) { var stat = fs.statSync(field.value.path); expectedLength += stat.size; } else { - expectedLength += ('' + field.value).length; + expectedLength += String(field.value).length; } }); expectedLength += form._overheadLength + form._lastBoundary().length; @@ -73,17 +75,14 @@ var Readable = require('stream').Readable; var calculatedLength = form.getLengthSync(); assert.equal(expectedLength, calculatedLength); -})(); +}()); (function testReadableStreamData() { var form = new FormData(); - var util = require('util'); - util.inherits(CustomReadable, Readable); - /** * Custion readable constructor - * @param {Object} opt options + * @param {object} opt options * @constructor */ function CustomReadable(opt) { @@ -92,16 +91,17 @@ var Readable = require('stream').Readable; this._index = 1; } - CustomReadable.prototype._read = function() { + util.inherits(CustomReadable, Readable); + + CustomReadable.prototype._read = function () { var i = this._index++; if (i > this._max) { this.push(null); } else { - this.push('' + i); + this.push(String(i)); } }; form.append('my_txt', new CustomReadable()); - assert.throws(function() { form.getLengthSync(); }, /Cannot calculate proper length in synchronous way/); - -})(); + assert['throws'](function () { form.getLengthSync(); }, /Cannot calculate proper length in synchronous way/); +}()); diff --git a/test/integration/test-form-get-length.js b/test/integration/test-form-get-length.js index 6dabca7d..b5da5761 100644 --- a/test/integration/test-form-get-length.js +++ b/test/integration/test-form-get-length.js @@ -4,6 +4,7 @@ var FormData = require(common.dir.lib + '/form_data'); var fake = require('fake').create(); var fs = require('fs'); var Readable = require('stream').Readable; +var util = require('util'); (function testEmptyForm() { var form = new FormData(); @@ -14,7 +15,7 @@ var Readable = require('stream').Readable; // Make sure our response is async assert.strictEqual(calls.length, 0); -})(); +}()); (function testUtf8String() { var FIELD = 'my_field'; @@ -24,14 +25,11 @@ var Readable = require('stream').Readable; form.append(FIELD, VALUE); var callback = fake.callback('testUtf8String-getLength'); - var expectedLength = - form._overheadLength + - Buffer.byteLength(VALUE) + - form._lastBoundary().length; + var expectedLength = form._overheadLength + Buffer.byteLength(VALUE) + form._lastBoundary().length; fake.expectAnytime(callback, [null, expectedLength]); form.getLength(callback); -})(); +}()); (function testBuffer() { var FIELD = 'my_field'; @@ -41,15 +39,11 @@ var Readable = require('stream').Readable; form.append(FIELD, VALUE); var callback = fake.callback('testBuffer-getLength'); - var expectedLength = - form._overheadLength + - VALUE.length + - form._lastBoundary().length; + var expectedLength = form._overheadLength + VALUE.length + form._lastBoundary().length; fake.expectAnytime(callback, [null, expectedLength]); form.getLength(callback); -})(); - +}()); (function testStringFileBufferFile() { var fields = [ @@ -74,7 +68,7 @@ var Readable = require('stream').Readable; var form = new FormData(); var expectedLength = 0; - fields.forEach(function(field) { + fields.forEach(function (field) { form.append(field.name, field.value); if (field.value.path) { var stat = fs.statSync(field.value.path); @@ -89,18 +83,15 @@ var Readable = require('stream').Readable; var callback = fake.callback('testStringFileBufferFile-getLength'); fake.expectAnytime(callback, [null, expectedLength]); form.getLength(callback); -})(); +}()); (function testReadableStreamData() { var form = new FormData(); // var expectedLength = 0; - var util = require('util'); - util.inherits(CustomReadable, Readable); - /** * Custion readable constructor - * @param {Object} opt options + * @param {object} opt options * @constructor */ function CustomReadable(opt) { @@ -109,12 +100,14 @@ var Readable = require('stream').Readable; this._index = 1; } - CustomReadable.prototype._read = function() { + util.inherits(CustomReadable, Readable); + + CustomReadable.prototype._read = function () { var i = this._index++; if (i > this._max) { this.push(null); } else { - this.push('' + i); + this.push(String(i)); } }; form.append('my_txt', new CustomReadable()); @@ -122,8 +115,7 @@ var Readable = require('stream').Readable; // expectedLength += form._overheadLength + form._lastBoundary().length; // there is no way to determine the length of this readable stream. - var callback = fake.callback(arguments.callee.name + '-getLength'); + var callback = fake.callback(arguments.callee.name + '-getLength'); // eslint-disable-line no-restricted-properties fake.expectAnytime(callback, ['Unknown stream', undefined]); - form.getLength(function(err, len) { callback(err,len); }); - -})(); + form.getLength(function (err, len) { callback(err, len); }); +}()); diff --git a/test/integration/test-get-boundary.js b/test/integration/test-get-boundary.js index 6dc2fb2b..6faa0cec 100644 --- a/test/integration/test-get-boundary.js +++ b/test/integration/test-get-boundary.js @@ -1,3 +1,5 @@ +'use strict'; + var common = require('../common'); var assert = common.assert; @@ -9,10 +11,10 @@ var FormData = require(common.dir.lib + '/form_data'); assert.equal(boundary, form.getBoundary()); assert.equal(boundary.length, 50); -})(); +}()); (function testUniqueBoundaryPerForm() { var formA = new FormData(); var formB = new FormData(); assert.notEqual(formA.getBoundary(), formB.getBoundary()); -})(); +}()); diff --git a/test/integration/test-get-buffer.js b/test/integration/test-get-buffer.js index cca6fa0a..dfbf12f5 100644 --- a/test/integration/test-get-buffer.js +++ b/test/integration/test-get-buffer.js @@ -1,3 +1,5 @@ +'use strict'; + var common = require('../common'); var assert = common.assert; @@ -5,11 +7,11 @@ var FormData = require(common.dir.lib + '/form_data'); (function testTypeIsBuffer() { var form = new FormData(); - form.append( 'String', 'Some random string' ); + form.append('String', 'Some random string'); var buffer = form.getBuffer(); assert.equal(typeof buffer === 'object' && Buffer.isBuffer(buffer), true); -})(); +}()); (function testBufferIsValid() { var form = new FormData(); @@ -19,36 +21,25 @@ var FormData = require(common.dir.lib + '/form_data'); var intName = 'Int'; var intValue = 1549873167987; var bufferName = 'Buffer'; - var bufferValue = Buffer.from([0x00,0x4a,0x45,0x46,0x46,0x52,0x45,0x59,0x255]); + var bufferValue = Buffer.from([0x00, 0x4a, 0x45, 0x46, 0x46, 0x52, 0x45, 0x59, 0x255]); // Fill the formData object - form.append( stringName, stringValue ); - form.append( intName, intValue ); - form.append( bufferName, bufferValue ); + form.append(stringName, stringValue); + form.append(intName, intValue); + form.append(bufferName, bufferValue); // Get the resulting Buffer var buffer = form.getBuffer(); // Generate expected code. var boundary = form.getBoundary(); - var expected = Buffer.concat( [ - Buffer.from( '--' + boundary + FormData.LINE_BREAK + - 'Content-Disposition: form-data; name="' + stringName + '"' + FormData.LINE_BREAK + - FormData.LINE_BREAK + - stringValue + FormData.LINE_BREAK + - '--' + boundary + FormData.LINE_BREAK + - 'Content-Disposition: form-data; name="' + intName + '"' + FormData.LINE_BREAK + - FormData.LINE_BREAK + - intValue + FormData.LINE_BREAK + - '--' + boundary + FormData.LINE_BREAK + - 'Content-Disposition: form-data; name="' + bufferName + '"' + FormData.LINE_BREAK + - 'Content-Type: application/octet-stream' + FormData.LINE_BREAK + - FormData.LINE_BREAK), + var expected = Buffer.concat([ + Buffer.from('--' + boundary + FormData.LINE_BREAK + 'Content-Disposition: form-data; name="' + stringName + '"' + FormData.LINE_BREAK + FormData.LINE_BREAK + stringValue + FormData.LINE_BREAK + '--' + boundary + FormData.LINE_BREAK + 'Content-Disposition: form-data; name="' + intName + '"' + FormData.LINE_BREAK + FormData.LINE_BREAK + intValue + FormData.LINE_BREAK + '--' + boundary + FormData.LINE_BREAK + 'Content-Disposition: form-data; name="' + bufferName + '"' + FormData.LINE_BREAK + 'Content-Type: application/octet-stream' + FormData.LINE_BREAK + FormData.LINE_BREAK), bufferValue, - Buffer.from( FormData.LINE_BREAK + '--' + boundary + '--' + FormData.LINE_BREAK ) - ] ); + Buffer.from(FormData.LINE_BREAK + '--' + boundary + '--' + FormData.LINE_BREAK) + ]); // Test if the buffer content, equals the expected buffer. assert.equal(buffer.length, expected.length); assert.equal(buffer.toString('hex'), expected.toString('hex')); -})(); +}()); diff --git a/test/integration/test-http-response.js b/test/integration/test-http-response.js index bb420c8b..8b06ead0 100644 --- a/test/integration/test-http-response.js +++ b/test/integration/test-http-response.js @@ -1,3 +1,5 @@ +'use strict'; + var common = require('../common'); var assert = common.assert; var http = require('http'); @@ -18,44 +20,41 @@ var options = { }; var FIELDS = { - 'my_field': { + my_field: { value: 'my_value' }, - 'my_buffer': { + my_buffer: { type: FormData.DEFAULT_CONTENT_TYPE, value: common.defaultTypeValue }, - 'remote_file': { + remote_file: { value: 'TBD', name: remoteFile } }; // request static file -http.request(options, function(response) { - +http.request(options, function (response) { var form = new FormData(); // add http response to the form fields - FIELDS['remote_file'].value = response; + FIELDS.remote_file.value = response; common.actions.populateFields(form, FIELDS); - server.listen(common.port, function() { + server.listen(common.port, function () { common.actions.submit(form, server); }); - }).end(); // count total var fieldsPassed = Object.keys(FIELDS).length; // prepare form-receiving http server -server = common.testFields(FIELDS, function(fields){ +server = common.testFields(FIELDS, function (fields) { fieldsPassed = fields; }); - -process.on('exit', function() { +process.on('exit', function () { assert.strictEqual(fieldsPassed, 0); }); diff --git a/test/integration/test-last_boundary-line_break.js b/test/integration/test-last_boundary-line_break.js index 625fefc4..ae4d510d 100644 --- a/test/integration/test-last_boundary-line_break.js +++ b/test/integration/test-last_boundary-line_break.js @@ -1,3 +1,5 @@ +'use strict'; + var http = require('http'); var common = require('../common'); var assert = common.assert; @@ -8,7 +10,6 @@ var server; * Test submission of proper line ending */ function submitForm() { - var form = new FormData(); form.append('field', 'value'); @@ -17,18 +18,17 @@ function submitForm() { } // create https server -server = http.createServer(function(req, res) { - +server = http.createServer(function (req, res) { var body = ''; req.setEncoding('utf8'); // old and simple - req.on('data', function(data) { + req.on('data', function (data) { body += data; }); - req.on('end', function() { + req.on('end', function () { // last character(s) sequence equals predefined line break assert.strictEqual(body.substr(-1 * FormData.LINE_BREAK.length), FormData.LINE_BREAK); diff --git a/test/integration/test-options-override.js b/test/integration/test-options-override.js index 337842e9..fd08804d 100644 --- a/test/integration/test-options-override.js +++ b/test/integration/test-options-override.js @@ -1,6 +1,8 @@ +'use strict'; + var common = require('../common'); var assert = common.assert; var FormData = require(common.dir.lib + '/form_data'); -var form = new FormData({maxDataSize: 20 * 1024 * 1024}); +var form = new FormData({ maxDataSize: 20 * 1024 * 1024 }); assert.strictEqual(form.maxDataSize, 20 * 1024 * 1024); diff --git a/test/integration/test-pipe.js b/test/integration/test-pipe.js index c3360efc..d4a56546 100644 --- a/test/integration/test-pipe.js +++ b/test/integration/test-pipe.js @@ -1,3 +1,5 @@ +'use strict'; + var common = require('../common'); var assert = common.assert; var http = require('http'); @@ -6,38 +8,39 @@ var request = require('request'); var fs = require('fs'); var FormData = require(common.dir.lib + '/form_data'); var IncomingForm = require('formidable').IncomingForm; +var hasOwn = require('hasown'); var remoteFile = 'http://localhost:' + common.staticPort + '/unicycle.jpg'; -// wrap non simple values into function -// just to deal with ReadStream "autostart" +/* + * wrap non simple values into function + * just to deal with ReadStream "autostart" + */ var FIELDS = { - 'my_field': { + my_field: { value: 'my_value' }, - 'my_buffer': { + my_buffer: { type: FormData.DEFAULT_CONTENT_TYPE, value: common.defaultTypeValue }, - 'my_file': { + my_file: { type: mime.lookup(common.dir.fixture + '/unicycle.jpg'), - value: function() { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } + value: function () { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } }, - 'remote_file': { + remote_file: { type: mime.lookup(common.dir.fixture + '/unicycle.jpg'), - value: function() { return request(remoteFile); } + value: function () { return request(remoteFile); } } }; var fieldsPassed = Object.keys(FIELDS).length; -var server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); +var server = http.createServer(function (req, res) { + var form = new IncomingForm({ uploadDir: common.dir.tmp }); form.parse(req); - common.actions.checkForm(form, FIELDS, function(fieldsChecked) - { + common.actions.checkForm(form, FIELDS, function (fieldsChecked) { // keep track of number of the processed fields fieldsPassed = fieldsPassed - fieldsChecked; // finish it @@ -45,20 +48,18 @@ var server = http.createServer(function(req, res) { }); }); -server.listen(common.port, function() { - +server.listen(common.port, function () { var form = new FormData(); - var field; - for (var name in FIELDS) { - if (!FIELDS.hasOwnProperty(name)) { continue; } - - field = FIELDS[name]; - // important to append ReadStreams within the same tick - if ((typeof field.value == 'function')) { - field.value = field.value(); + for (var name in FIELDS) { // eslint-disable-line no-restricted-syntax + if (hasOwn(FIELDS, name)) { + var field = FIELDS[name]; + // important to append ReadStreams within the same tick + if (typeof field.value === 'function') { + field.value = field.value(); + } + form.append(name, field.value); } - form.append(name, field.value); } var req = http.request({ @@ -70,8 +71,7 @@ server.listen(common.port, function() { form.pipe(req); - req.on('response', function(res) { - + req.on('response', function (res) { // unstuck new streams res.resume(); @@ -79,6 +79,6 @@ server.listen(common.port, function() { }); }); -process.on('exit', function() { +process.on('exit', function () { assert.strictEqual(fieldsPassed, 0); }); diff --git a/test/integration/test-ranged-filestream.js b/test/integration/test-ranged-filestream.js index bac1d259..39123cac 100644 --- a/test/integration/test-ranged-filestream.js +++ b/test/integration/test-ranged-filestream.js @@ -1,32 +1,35 @@ +'use strict'; + /* -test ranged fs.createReadStream -re: https://github.com/felixge/node-form-data/issues/71 -*/ + *test ranged fs.createReadStream + *re: https://github.com/felixge/node-form-data/issues/71 + */ -var common = require('../common'); -var assert = common.assert; -var http = require('http'); -var fs = require('fs'); +var common = require('../common'); +var assert = common.assert; +var http = require('http'); +var fs = require('fs'); +var hasOwn = require('hasown'); -var FormData = require(common.dir.lib + '/form_data'); +var FormData = require(common.dir.lib + '/form_data'); var IncomingForm = require('formidable').IncomingForm; var testSubjects = { - 'a_file': { + a_file: { file: 'veggies.txt', start: 8, end: 18 - }, 'b_file': { + }, b_file: { file: 'veggies.txt', start: 6 - }, 'c_file': { + }, c_file: { file: 'veggies.txt', end: 16 - }, 'd_file': { + }, d_file: { file: 'veggies.txt', start: 0, end: 16 - }, 'e_file': { + }, e_file: { file: 'veggies.txt', start: 0, end: 0 @@ -36,67 +39,64 @@ var testSubjects = { /** * Accumulates read data size * - * @param {string} data - chunk of read data + * @param {string} data - chunk of read data */ function readSizeAccumulator(data) { - this.readSize += data.length; + this.readSize += data.length; // eslint-disable-line no-invalid-this } -var server = http.createServer(function(req, res) { +var server = http.createServer(function (req, res) { var requestBodyLength = 0; // calculate actual length of the request body - req.on('data', function(data) { + req.on('data', function (data) { requestBodyLength += data.length; }); - req.on('end', function() { + req.on('end', function () { // make sure total Content-Length is properly calculated assert.equal(req.headers['content-length'], requestBodyLength); // successfully accepted request and it's good res.writeHead(200); }); - var form = new IncomingForm({uploadDir: common.dir.tmp}); + var form = new IncomingForm({ uploadDir: common.dir.tmp }); form.parse(req); form - .on('file', function(name, file) { + .on('file', function (name, file) { // make sure chunks are the same size assert.equal(file.size, testSubjects[name].readSize); // clean up tested subject delete testSubjects[name]; }) - .on('end', function() { + .on('end', function () { // done here res.end(); }); }); - -server.listen(common.port, function() { +server.listen(common.port, function () { var form = new FormData(); var name, options; // add test subjects to the form - for (name in testSubjects) { - if (!testSubjects.hasOwnProperty(name)) { - continue; - } - - options = {encoding: 'utf8'}; + for (name in testSubjects) { // eslint-disable-line no-restricted-syntax + if (hasOwn(testSubjects, name)) { + options = { encoding: 'utf8' }; - if (testSubjects[name].start) { options.start = testSubjects[name].start; } - if (testSubjects[name].end) { options.end = testSubjects[name].end; } + if (testSubjects[name].start) { options.start = testSubjects[name].start; } + if (testSubjects[name].end) { options.end = testSubjects[name].end; } - form.append(name, testSubjects[name].fsStream = fs.createReadStream(common.dir.fixture + '/' + testSubjects[name].file, options)); + form.append(name, testSubjects[name].fsStream = fs.createReadStream(common.dir.fixture + '/' + testSubjects[name].file, options)); - // calculate data size - testSubjects[name].readSize = 0; - testSubjects[name].fsStream.on('data', readSizeAccumulator.bind(testSubjects[name])); + // calculate data size + testSubjects[name].readSize = 0; + testSubjects[name].fsStream.on('data', readSizeAccumulator.bind(testSubjects[name])); + } } - form.submit('http://localhost:' + common.port + '/', function(err, res) { + form.submit('http://localhost:' + common.port + '/', function (err, res) { if (err) { throw err; } @@ -104,7 +104,7 @@ server.listen(common.port, function() { assert.strictEqual(res.statusCode, 200); // wait for server to finish - res.on('end', function() { + res.on('end', function () { // check that all subjects were tested assert.strictEqual(Object.keys(testSubjects).length, 0); server.close(); diff --git a/test/integration/test-request.js b/test/integration/test-request.js index 88ee4bc5..88200d35 100644 --- a/test/integration/test-request.js +++ b/test/integration/test-request.js @@ -1,3 +1,5 @@ +'use strict'; + /** * Show & Test for `mikeal/request` library * as bonus shows progress monitor implementation @@ -13,52 +15,50 @@ var fs = require('fs'); var IncomingForm = require('formidable').IncomingForm; var fileName = common.dir.fixture + '/unicycle.jpg'; -var myFile = function() { return fs.createReadStream(fileName); }; +var myFile = function () { return fs.createReadStream(fileName); }; var numItems = 5; // Make request to use our FormData request.prototype.form = function (form) { var self = this; if (form) { - if (!/^application\/x-www-form-urlencoded\b/.test(self.getHeader('content-type'))) { + if (!(/^application\/x-www-form-urlencoded\b/).test(self.getHeader('content-type'))) { self.setHeader('content-type', 'application/x-www-form-urlencoded'); } - self.body = (typeof form === 'string') + self.body = typeof form === 'string' ? self._qs.rfc3986(form.toString('utf8')) : self._qs.stringify(form).toString('utf8'); return self; } // create form-data object self._form = new FormData(); - self._form.on('error', function(err) { - err.message = 'form-data: ' + err.message; + self._form.on('error', function (err) { + err.message = 'form-data: ' + err.message; // eslint-disable-line no-param-reassign self.emit('error', err); self.abort(); }); return self._form; }; -var server = http.createServer(function(req, res) { - - var form = new IncomingForm({uploadDir: common.dir.tmp}); +var server = http.createServer(function (req, res) { + var form = new IncomingForm({ uploadDir: common.dir.tmp }); form.parse(req); form - .on('file', function(name, file) { - numItems--; + .on('file', function (name, file) { + numItems -= 1; assert.strictEqual(file.name, path.basename(fileName)); assert.strictEqual(file.type, mime.lookup(file.name)); }) .on('end', common.actions.formOnEnd.bind(null, res)); }); -server.listen(common.port, function() { - +server.listen(common.port, function () { var uploadSize = 0; var uploaded = 0; - var r = request.post('http://localhost:' + common.port + '/', function(err, res) { + var r = request.post('http://localhost:' + common.port + '/', function (err, res) { assert.ifError(err); assert.strictEqual(res.statusCode, 200); server.close(); @@ -71,23 +71,23 @@ server.listen(common.port, function() { } // get upload size - form.getLength(function(err, size) { + form.getLength(function (err, size) { assert.equal(err, null); uploadSize = size; assert.ok(uploadSize > 0); }); // calculate uploaded size chunk by chunk - form.on('data', function(data) { + form.on('data', function (data) { uploaded += data.length; }); // done uploading compare sizes - form.on('end', function() { + form.on('end', function () { assert.equal(uploaded, uploadSize); }); }); -process.on('exit', function() { +process.on('exit', function () { assert.strictEqual(numItems, 0); }); diff --git a/test/integration/test-return-http-request.js b/test/integration/test-return-http-request.js index 5074138e..b54cd018 100644 --- a/test/integration/test-return-http-request.js +++ b/test/integration/test-return-http-request.js @@ -1,9 +1,11 @@ -/* -test return http request, added for issue #47: -https://github.com/felixge/node-form-data/issues/47 +'use strict'; -Checking correct length header and request object -*/ +/* + *test return http request, added for issue #47: + *https://github.com/felixge/node-form-data/issues/47 + * + *Checking correct length header and request object + */ var common = require('../common'); var assert = common.assert; @@ -15,17 +17,17 @@ var expectedLength; var dataSize = 1000000; -var server = http.createServer(function(req, res) { +var server = http.createServer(function (req, res) { var uploaded = 0; - assert.ok( typeof req.headers['content-length'] !== 'undefined' ); + assert.ok(typeof req.headers['content-length'] !== 'undefined'); assert.equal(req.headers['content-length'], expectedLength); // check for uploaded body - req.on('data', function(data) { + req.on('data', function (data) { uploaded += data.length; }); - req.on('end', function() { + req.on('end', function () { // compare uploaded total to the expected length assert.equal(uploaded, expectedLength); @@ -35,9 +37,9 @@ var server = http.createServer(function(req, res) { }); - -server.listen(common.port, function() { - var R, oWrite, progress = 0, form = new FormData(); +server.listen(common.port, function () { + var progress = 0; + var form = new FormData(); var bufferData = []; for (var z = 0; z < dataSize; z++) { @@ -50,7 +52,7 @@ server.listen(common.port, function() { // (available to req handler) expectedLength = form._lastBoundary().length + form._overheadLength + dataSize; - R = form.submit('http://localhost:' + common.port + '/', function(err, res) { + var R = form.submit('http://localhost:' + common.port + '/', function (err, res) { if (err) { throw err; } @@ -67,17 +69,16 @@ server.listen(common.port, function() { }); // augment into request - oWrite = R.write; - R.write = function(chunk) { - return oWrite.call(this, chunk, function() { + var oWrite = R.write; + R.write = function (chunk) { + return oWrite.call(this, chunk, function () { form.emit('progress', chunk); }); }; // track progress - form.on('progress', function(chunk) { + form.on('progress', function (chunk) { progress += chunk.length; assert.ok(progress <= expectedLength); }); - }); diff --git a/test/integration/test-set-boundary.js b/test/integration/test-set-boundary.js index f1d88206..7b2fa453 100644 --- a/test/integration/test-set-boundary.js +++ b/test/integration/test-set-boundary.js @@ -1,3 +1,5 @@ +'use strict'; + var common = require('../common'); var assert = common.assert; @@ -9,7 +11,7 @@ var FormData = require(common.dir.lib + '/form_data'); form.setBoundary(userBoundary); assert.equal(form.getBoundary(), userBoundary); -})(); +}()); (function testUniqueBoundaryPerFormAfterSet() { var userBoundary = '---something'; @@ -20,4 +22,16 @@ var FormData = require(common.dir.lib + '/form_data'); assert.equal(formA.getBoundary(), userBoundary); assert.notEqual(formA.getBoundary(), formB.getBoundary()); -})(); +}()); + +(function testSetBoundaryWithNonString() { + var form = new FormData(); + + var invalidValues = [123, null, undefined, { value: 123 }, ['---something']]; + + invalidValues.forEach(function (value) { + assert.throws(function () { + form.setBoundary(value); + }, TypeError); + }); +}()); diff --git a/test/integration/test-set-nonstring.js b/test/integration/test-set-nonstring.js new file mode 100644 index 00000000..c9f0f3bb --- /dev/null +++ b/test/integration/test-set-nonstring.js @@ -0,0 +1,22 @@ +'use strict'; + +var common = require('../common'); +var assert = common.assert; + +var FormData = require(common.dir.lib + '/form_data'); + +(function testSetUndefined() { + var form = new FormData(); + + assert.doesNotThrow(function () { + form.append('key', undefined); + }); + + var buffer = form.getBuffer(); + + assert.deepEqual(buffer.toString().split(form.getBoundary()), [ + '--', + '\r\nContent-Disposition: form-data; name="key"\r\n\r\nundefined\r\n--', + '--\r\n' + ]); +}()); diff --git a/test/integration/test-submit-custom-header.js b/test/integration/test-submit-custom-header.js index 6a6aff55..aa6d79e8 100644 --- a/test/integration/test-submit-custom-header.js +++ b/test/integration/test-submit-custom-header.js @@ -1,3 +1,5 @@ +'use strict'; + var common = require('../common'); var assert = common.assert; var http = require('http'); @@ -9,36 +11,37 @@ var IncomingForm = require('formidable').IncomingForm; var remoteFile = 'http://localhost:' + common.staticPort + '/unicycle.jpg'; -// wrap non simple values into function -// just to deal with ReadStream "autostart" +/* + * wrap non simple values into function + * just to deal with ReadStream "autostart" + */ var FIELDS = { - 'my_field': { + my_field: { value: 'my_value' }, - 'my_buffer': { + my_buffer: { type: FormData.DEFAULT_CONTENT_TYPE, value: common.defaultTypeValue }, - 'my_file': { + my_file: { type: mime.lookup(common.dir.fixture + '/unicycle.jpg'), - value: function() { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } + value: function () { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } }, - 'remote_file': { + remote_file: { type: mime.lookup(common.dir.fixture + '/unicycle.jpg'), - value: function() { return request(remoteFile); } + value: function () { return request(remoteFile); } } }; var fieldsPassed = Object.keys(FIELDS).length; -var server = http.createServer(function(req, res) { +var server = http.createServer(function (req, res) { assert.ok(req.headers['x-test-header'], 'test-header-value'); - var form = new IncomingForm({uploadDir: common.dir.tmp}); + var form = new IncomingForm({ uploadDir: common.dir.tmp }); form.parse(req); - common.actions.checkForm(form, FIELDS, function(fieldsChecked) - { + common.actions.checkForm(form, FIELDS, function (fieldsChecked) { // keep track of number of the processed fields fieldsPassed = fieldsPassed - fieldsChecked; // finish it @@ -46,8 +49,7 @@ var server = http.createServer(function(req, res) { }); }); -server.listen(common.port, function() { - +server.listen(common.port, function () { var form = new FormData(); common.actions.populateFields(form, FIELDS); @@ -59,7 +61,7 @@ server.listen(common.port, function() { headers: { 'x-test-header': 'test-header-value' } - }, function(error, result) { + }, function (error, result) { if (error) { throw error; } @@ -73,6 +75,6 @@ server.listen(common.port, function() { }); -process.on('exit', function() { +process.on('exit', function () { assert.strictEqual(fieldsPassed, 0); }); diff --git a/test/integration/test-submit-custom.js b/test/integration/test-submit-custom.js index acba6eb9..eaf508de 100644 --- a/test/integration/test-submit-custom.js +++ b/test/integration/test-submit-custom.js @@ -1,3 +1,5 @@ +'use strict'; + var common = require('../common'); var assert = common.assert; var mime = require('mime-types'); @@ -7,23 +9,25 @@ var FormData = require(common.dir.lib + '/form_data'); var remoteFile = 'http://localhost:' + common.staticPort + '/unicycle.jpg'; -// wrap non simple values into function -// just to deal with ReadStream "autostart" +/* + * wrap non simple values into function + * just to deal with ReadStream "autostart" + */ var FIELDS = { - 'my_field': { + my_field: { value: 'my_value' }, - 'my_buffer': { + my_buffer: { type: FormData.DEFAULT_CONTENT_TYPE, value: common.defaultTypeValue }, - 'my_file': { + my_file: { type: mime.lookup(common.dir.fixture + '/unicycle.jpg'), - value: function() { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } + value: function () { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } }, - 'remote_file': { + remote_file: { type: mime.lookup(common.dir.fixture + '/unicycle.jpg'), - value: function() { return request(remoteFile); } + value: function () { return request(remoteFile); } } }; @@ -31,12 +35,11 @@ var FIELDS = { var fieldsPassed = Object.keys(FIELDS).length; // prepare form-receiving http server -var server = common.testFields(FIELDS, function(fields){ +var server = common.testFields(FIELDS, function (fields) { fieldsPassed = fields; }); -server.listen(common.port, function() { - +server.listen(common.port, function () { var form = new FormData(); common.actions.populateFields(form, FIELDS); @@ -45,8 +48,7 @@ server.listen(common.port, function() { form.submit({ port: common.port, path: '/' - }, function(err, res) { - + }, function (err, res) { if (err) { throw err; } @@ -59,6 +61,6 @@ server.listen(common.port, function() { }); -process.on('exit', function() { +process.on('exit', function () { assert.strictEqual(fieldsPassed, 0); }); diff --git a/test/integration/test-submit-https.js b/test/integration/test-submit-https.js index 51f0b450..e3904162 100644 --- a/test/integration/test-submit-https.js +++ b/test/integration/test-submit-https.js @@ -1,4 +1,7 @@ +'use strict'; + var https = require('https'); +var constants = require('constants'); var common = require('../common'); var assert = common.assert; var FormData = require(common.dir.lib + '/form_data'); @@ -8,7 +11,6 @@ var server; * Test submission to HTTPS endpoint */ function submitForm() { - var form = new FormData(); form.append('field', 'value'); @@ -19,10 +21,9 @@ function submitForm() { port: common.httpsPort, pathname: '/', // for self-signed certs on localhost - secureOptions: require('constants').SSL_OP_NO_TLSv1_2, + secureOptions: constants.SSL_OP_NO_TLSv1_2, ca: common.httpsServerCert - }, function(err, res) { - + }, function (err, res) { if (err) { throw err; } @@ -41,13 +42,12 @@ function submitForm() { server = https.createServer({ key: common.httpsServerKey, cert: common.httpsServerCert -}, function(req, res) { - +}, function (req, res) { // old and simple - req.on('data', function() {}); + req.on('data', function () {}); - req.on('end', function() { - res.writeHead(200, {'x-success': 'OK'}); + req.on('end', function () { + res.writeHead(200, { 'x-success': 'OK' }); res.end('Great Success'); }); }); diff --git a/test/integration/test-submit-multi-nocallback.js b/test/integration/test-submit-multi-nocallback.js index 5b666fa8..df1199ad 100644 --- a/test/integration/test-submit-multi-nocallback.js +++ b/test/integration/test-submit-multi-nocallback.js @@ -1,3 +1,5 @@ +'use strict'; + var common = require('../common'); var assert = common.assert; var http = require('http'); @@ -6,41 +8,37 @@ var IncomingForm = require('formidable').IncomingForm; var times = 10; -var server = http.createServer(function(req, res) { - +var server = http.createServer(function (req, res) { // no need to have tmp dir here, since no files being uploaded // but formidable would fail in 0.6 otherwise - var form = new IncomingForm({uploadDir: common.dir.tmp}); + var form = new IncomingForm({ uploadDir: common.dir.tmp }); form.parse(req); form .on('field', common.actions.basicFormOnField) - .on('end', function() { + .on('end', function () { res.writeHead(200); res.end('done'); - times--; + times -= 1; - if (times == 0) { + if (times === 0) { server.close(); } }); }); -server.listen(common.port, function() { - var i; - - for (i = 0; i < times; i++) { +server.listen(common.port, function () { + for (var i = 0; i < times; i++) { var form = new FormData(); form.append('my_field', 'my_value'); form.submit('http://localhost:' + common.port + '/'); } - }); -process.on('exit', function() { +process.on('exit', function () { assert.strictEqual(times, 0); }); diff --git a/test/integration/test-submit-multi.js b/test/integration/test-submit-multi.js index a0bc3dcc..b7a21b88 100644 --- a/test/integration/test-submit-multi.js +++ b/test/integration/test-submit-multi.js @@ -1,3 +1,5 @@ +'use strict'; + var common = require('../common'); var assert = common.assert; var http = require('http'); @@ -14,29 +16,30 @@ function submitForm() { form.append('my_field', 'my_value'); - form.submit('http://localhost:' + common.port + '/', function(err, res) { + form.submit('http://localhost:' + common.port + '/', function (err, res) { if (err) { throw err; } assert.strictEqual(res.statusCode, 200); - // Needed for node-0.10.x because Streams2 - // more info: http://nodejs.org/api/stream.html#stream_compatibility_with_older_node_versions + /* + * Needed for node-0.10.x because Streams2 + * more info: http://nodejs.org/api/stream.html#stream_compatibility_with_older_node_versions + */ res.resume(); - times--; - if (times == 0) { + times -= 1; + if (times === 0) { server.close(); } }); } -server = http.createServer(function(req, res) { - +server = http.createServer(function (req, res) { // no need to have tmp dir here, since no files being uploaded // but formidable would fail in 0.6 otherwise - var form = new IncomingForm({uploadDir: common.dir.tmp}); + var form = new IncomingForm({ uploadDir: common.dir.tmp }); form.parse(req); @@ -45,14 +48,12 @@ server = http.createServer(function(req, res) { .on('end', common.actions.formOnEnd.bind(null, res)); }); -server.listen(common.port, function() { - var i; - - for (i = 0; i < times; i++) { +server.listen(common.port, function () { + for (var i = 0; i < times; i++) { submitForm(); } }); -process.on('exit', function() { +process.on('exit', function () { assert.strictEqual(times, 0); }); diff --git a/test/integration/test-submit-readable-stream.js b/test/integration/test-submit-readable-stream.js index 41896a47..3c3cd651 100644 --- a/test/integration/test-submit-readable-stream.js +++ b/test/integration/test-submit-readable-stream.js @@ -1,44 +1,45 @@ +'use strict'; + var common = require('../common'); var assert = common.assert; var http = require('http'); var FormData = require(common.dir.lib + '/form_data'); var Readable = require('stream').Readable; +var util = require('util'); -var server = http.createServer(function(req, res) { +var server = http.createServer(function (req, res) { assert.strictEqual(req.headers['Content-Length'], undefined); res.writeHead(200); res.end('done'); }); -server.listen(common.port, function() { +server.listen(common.port, function () { var form = new FormData(); - var util = require('util'); - util.inherits(CustomReadable, Readable); - /** * Custion readable constructor - * @param {Object} opt options + * @param {object} opt options * @constructor - */ + */ function CustomReadable(opt) { Readable.call(this, opt); this._max = 2; this._index = 1; } + util.inherits(CustomReadable, Readable); - CustomReadable.prototype._read = function() { + CustomReadable.prototype._read = function () { var i = this._index++; // console.error('send back read data'); if (i > this._max) { this.push(null); } else { - this.push('' + i); + this.push(String(i)); } }; form.append('readable', new CustomReadable()); - form.submit('http://localhost:' + common.port + '/', function(err, res) { + form.submit('http://localhost:' + common.port + '/', function (err, res) { if (err) { throw err; } diff --git a/test/integration/test-submit-url-parsing.js b/test/integration/test-submit-url-parsing.js index becc1d70..e9e1b31c 100644 --- a/test/integration/test-submit-url-parsing.js +++ b/test/integration/test-submit-url-parsing.js @@ -1,3 +1,5 @@ +'use strict'; + var http = require('http'); var https = require('https'); var common = require('../common'); @@ -13,21 +15,19 @@ var form = new FormData(); form.append('field', 'value'); // Basic parsing -req = form.submit('http://localhost/path', function() {}); +req = form.submit('http://localhost/path', function () {}); assert.strictEqual(req.path, '/path'); assert.ok(req.agent instanceof http.Agent, 'req.agent instanceof http.Agent'); assert.strictEqual(req.getHeader('Host'), 'localhost'); req.abort(); // Non-default port handling -req = form.submit('http://localhost:' + common.port, function() {}); +req = form.submit('http://localhost:' + common.port, function () {}); assert.strictEqual(req.getHeader('Host'), 'localhost:' + common.port); req.abort(); // HTTPS protocol handling -req = form.submit('https://localhost/path', function() {}); +req = form.submit('https://localhost/path', function () {}); assert.ok(req.agent instanceof https.Agent, 'req.agent instanceof https.Agent'); assert.strictEqual(req.getHeader('Host'), 'localhost'); req.abort(); - - diff --git a/test/integration/test-submit.js b/test/integration/test-submit.js index 09a1e0c1..f0780e46 100644 --- a/test/integration/test-submit.js +++ b/test/integration/test-submit.js @@ -1,3 +1,5 @@ +'use strict'; + var common = require('../common'); var assert = common.assert; var mime = require('mime-types'); @@ -7,23 +9,25 @@ var FormData = require(common.dir.lib + '/form_data'); var remoteFile = 'http://localhost:' + common.staticPort + '/unicycle.jpg'; -// wrap non simple values into function -// just to deal with ReadStream "autostart" +/* + * wrap non simple values into function + * just to deal with ReadStream "autostart" + */ var FIELDS = { - 'my_field': { + my_field: { value: 'my_value' }, - 'my_buffer': { + my_buffer: { type: FormData.DEFAULT_CONTENT_TYPE, value: common.defaultTypeValue }, - 'my_file': { + my_file: { type: mime.lookup(common.dir.fixture + '/unicycle.jpg'), - value: function() { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } + value: function () { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } }, - 'remote_file': { + remote_file: { type: mime.lookup(common.dir.fixture + '/unicycle.jpg'), - value: function() { return request(remoteFile); } + value: function () { return request(remoteFile); } } }; @@ -31,13 +35,11 @@ var FIELDS = { var fieldsPassed = Object.keys(FIELDS).length; // prepare form-receiving http server -var server = common.testFields( FIELDS, function(fields){ +var server = common.testFields(FIELDS, function (fields) { fieldsPassed = fields; }); - -server.listen(common.port, function() { - +server.listen(common.port, function () { var form = new FormData(); common.actions.populateFields(form, FIELDS); @@ -45,6 +47,6 @@ server.listen(common.port, function() { common.actions.submit(form, server); }); -process.on('exit', function() { +process.on('exit', function () { assert.strictEqual(fieldsPassed, 0); }); diff --git a/test/integration/test-to-string.js b/test/integration/test-to-string.js index 877195ed..8c97d9c3 100644 --- a/test/integration/test-to-string.js +++ b/test/integration/test-to-string.js @@ -1,5 +1,7 @@ -var common = require('../common'); -var assert = common.assert; +'use strict'; + +var common = require('../common'); +var assert = common.assert; var FormData = require(common.dir.lib + '/form_data'); -assert(new FormData().toString() === '[object FormData]'); +assert(String(new FormData()) === '[object FormData]'); diff --git a/test/run-browser.js b/test/run-browser.js index 93077cc2..cea7bd4d 100644 --- a/test/run-browser.js +++ b/test/run-browser.js @@ -1,9 +1,10 @@ +'use strict'; + var test = require('tape'); var FormData = require('../lib/browser.js'); var form = new FormData(); -test('being nice to browser-like environments', function(t) -{ +test('being nice to browser-like environments', function (t) { t.plan(3); t.notEqual(typeof FormData, 'undefined', 'FormData should be defined'); t.equal(typeof form, 'object', 'FormData instance should be object'); diff --git a/test/run.js b/test/run.js index 22c804e2..c1091d48 100755 --- a/test/run.js +++ b/test/run.js @@ -1,6 +1,9 @@ #!/usr/bin/env node + +'use strict'; + var path = require('path'); -var static = require('./static'); +var staticS = require('./static'); var far = require('far').create(); var farPaths = require('far/lib/paths'); var spawn = require('cross-spawn'); @@ -9,16 +12,19 @@ var istanbul = path.join(basePath, './node_modules/.bin/istanbul'); // augment Far to support istanbul if (process.env.running_under_istanbul) { - far.constructor.prototype._execute = function(file) { + far.constructor.prototype._execute = function (file) { this._printStatus(file); var node = spawn(istanbul, [ 'cover', - '--report', 'none', - '--print', 'none', + '--report', + 'none', + '--print', + 'none', '--include-all-sources', '--include-pid', - '--root', basePath, + '--root', + basePath, file ]); @@ -32,7 +38,7 @@ if (process.env.running_under_istanbul) { * @param {string} chunk - partial output */ function onOutput(chunk) { - if (this._verbose > 1) { + if (this._verbose > 1) { // eslint-disable-line no-invalid-this process.stderr.write(chunk); } else { output += chunk; @@ -42,7 +48,7 @@ if (process.env.running_under_istanbul) { node.stdout.on('data', onOutput.bind(this)); node.stderr.on('data', onOutput.bind(this)); - node.on('exit', function(code) { + node.on('exit', function (code) { this._index++; this._printTestResult(file, code, output); this._executeNext(); @@ -52,11 +58,11 @@ if (process.env.running_under_istanbul) { // augment far to work on windows -farPaths.expandSync = function(pathList) { +farPaths.expandSync = function (pathList) { var expanded = {}; - pathList.forEach(function(p) { - p = path.resolve(process.cwd(), p); + pathList.forEach(function (p) { + p = path.resolve(process.cwd(), p); // eslint-disable-line no-param-reassign if (!farPaths.isDirectory(p)) { expanded[p] = true; @@ -65,7 +71,7 @@ farPaths.expandSync = function(pathList) { farPaths .findRecursiveSync(p) - .forEach(function(pp) { + .forEach(function (pp) { expanded[pp] = true; }); }); @@ -83,6 +89,6 @@ far.add(__dirname); far.include(/test-.*\.js$/); // start static server for all tests -static(function() { +staticS(function () { far.execute(); }); diff --git a/test/static.js b/test/static.js index 0cdffa88..e03885b7 100644 --- a/test/static.js +++ b/test/static.js @@ -1,3 +1,5 @@ +'use strict'; + // serves static files var http = require('http'); var fs = require('fs'); @@ -10,11 +12,9 @@ if (!fs.existsSync(common.dir.tmp)) { fs.mkdirSync(common.dir.tmp); } -module.exports = function(callback) { - +module.exports = function (callback) { // create http server - var httpServer = http.createServer(function(req, res) { - + var httpServer = http.createServer(function (req, res) { var target = path.join(common.dir.fixture, req.url); var stat = fs.statSync(target); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy