varun 2 years ago
commit b8075479b8

268
node_modules/.package-lock.json generated vendored

@ -3208,15 +3208,6 @@
"@types/babel-types": "*"
}
},
"node_modules/@types/body-parser": {
"version": "1.19.2",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
"integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==",
"dependencies": {
"@types/connect": "*",
"@types/node": "*"
}
},
"node_modules/@types/bson": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.5.tgz",
@ -3225,40 +3216,11 @@
"@types/node": "*"
}
},
"node_modules/@types/connect": {
"version": "3.4.35",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
"integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/estree": {
"version": "0.0.39",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw=="
},
"node_modules/@types/express": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.15.tgz",
"integrity": "sha512-Yv0k4bXGOH+8a+7bELd2PqHQsuiANB+A8a4gnQrkRWzrkKlb6KHaVvyXhqs04sVW/OWlbPyYxRgYlIXLfrufMQ==",
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.31",
"@types/qs": "*",
"@types/serve-static": "*"
}
},
"node_modules/@types/express-serve-static-core": {
"version": "4.17.31",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz",
"integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==",
"dependencies": {
"@types/node": "*",
"@types/qs": "*",
"@types/range-parser": "*"
}
},
"node_modules/@types/hoist-non-react-statics": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
@ -3268,11 +3230,6 @@
"hoist-non-react-statics": "^3.3.0"
}
},
"node_modules/@types/mime": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz",
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
},
"node_modules/@types/mongodb": {
"version": "3.6.20",
"resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz",
@ -3282,14 +3239,6 @@
"@types/node": "*"
}
},
"node_modules/@types/multer": {
"version": "1.4.7",
"resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.7.tgz",
"integrity": "sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA==",
"dependencies": {
"@types/express": "*"
}
},
"node_modules/@types/node": {
"version": "18.11.18",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
@ -3305,24 +3254,6 @@
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
},
"node_modules/@types/pump": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@types/pump/-/pump-1.1.1.tgz",
"integrity": "sha512-wpRerjHDxFBQ4r8XNv3xHJZeuqrBBoeQ/fhgkooV2F7KsPIYRROb/+f9ODgZfOEyO5/w2ej4YQdpPPXipT8DAA==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/qs": {
"version": "6.9.7",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
"integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw=="
},
"node_modules/@types/range-parser": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw=="
},
"node_modules/@types/react": {
"version": "18.0.26",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz",
@ -3354,15 +3285,6 @@
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
},
"node_modules/@types/serve-static": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz",
"integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==",
"dependencies": {
"@types/mime": "*",
"@types/node": "*"
}
},
"node_modules/@types/use-sync-external-store": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
@ -4036,42 +3958,16 @@
}
},
"node_modules/busboy": {
"version": "0.2.14",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
"integrity": "sha512-InWFDomvlkEj+xWLBfU3AvnbVYqeTWmQopiW0tWWEy5yehYm2YkGEc59sUmw/4ty5Zj/b0WHGs1LgecuBSBGrg==",
"peer": true,
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
"integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
"dependencies": {
"dicer": "0.2.5",
"readable-stream": "1.1.x"
"streamsearch": "^1.1.0"
},
"engines": {
"node": ">=0.8.0"
"node": ">=10.16.0"
}
},
"node_modules/busboy/node_modules/isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
"peer": true
},
"node_modules/busboy/node_modules/readable-stream": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
"peer": true,
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.1",
"isarray": "0.0.1",
"string_decoder": "~0.10.x"
}
},
"node_modules/busboy/node_modules/string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
"peer": true
},
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@ -4641,43 +4537,6 @@
"node": ">=8"
}
},
"node_modules/dicer": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
"integrity": "sha512-FDvbtnq7dzlPz0wyYlOExifDEZcu8h+rErEXgfxqmLfRfC/kJidEFh4+effJRO3P0xmfqyPbSMG0LveNRfTKVg==",
"peer": true,
"dependencies": {
"readable-stream": "1.1.x",
"streamsearch": "0.1.2"
},
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/dicer/node_modules/isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
"peer": true
},
"node_modules/dicer/node_modules/readable-stream": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
"peer": true,
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.1",
"isarray": "0.0.1",
"string_decoder": "~0.10.x"
}
},
"node_modules/dicer/node_modules/string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
"peer": true
},
"node_modules/digest-header": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/digest-header/-/digest-header-1.0.0.tgz",
@ -5588,6 +5447,11 @@
"node": ">= 0.6"
}
},
"node_modules/fs": {
"version": "0.0.1-security",
"resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
"integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w=="
},
"node_modules/fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
@ -5891,14 +5755,6 @@
"node": ">=8"
}
},
"node_modules/has-own-prop": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz",
"integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==",
"engines": {
"node": ">=8"
}
},
"node_modules/has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
@ -6239,11 +6095,6 @@
"node": ">=8"
}
},
"node_modules/is-generator": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/is-generator/-/is-generator-1.0.3.tgz",
"integrity": "sha512-G56jBpbJeg7ds83HW1LuShNs8J73Fv3CPz/bmROHOHlnKkN8sWb9ujiagjmxxMUywftgq48HlBZELKKqFLk0oA=="
},
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
@ -6304,11 +6155,6 @@
"node": ">=0.10.0"
}
},
"node_modules/is-promise": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
"integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="
},
"node_modules/is-property": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
@ -6594,11 +6440,6 @@
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
},
"node_modules/lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
},
"node_modules/lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@ -6929,14 +6770,6 @@
"node": ">=12"
}
},
"node_modules/mongodb-uri": {
"version": "0.9.7",
"resolved": "https://registry.npmjs.org/mongodb-uri/-/mongodb-uri-0.9.7.tgz",
"integrity": "sha512-s6BdnqNoEYfViPJgkH85X5Nw5NpzxN8hoflKLweNa7vBxt2V7kaS06d74pAtqDxde8fn4r9h4dNdLiFGoNV0KA==",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/mongodb/node_modules/bson": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/bson/-/bson-5.0.1.tgz",
@ -7082,47 +6915,20 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/multer": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.4.tgz",
"integrity": "sha512-2wY2+xD4udX612aMqMcB8Ws2Voq6NIUPEtD1be6m411T4uDH/VtL9i//xvcyFlTVfRdaBsk7hV5tgrGQqhuBiw==",
"deprecated": "Multer 1.x is affected by CVE-2022-24434. This is fixed in v1.4.4-lts.1 which drops support for versions of Node.js before 6. Please upgrade to at least Node.js 6 and version 1.4.4-lts.1 of Multer. If you need support for older versions of Node.js, we are open to accepting patches that would fix the CVE on the main 1.x release line, whilst maintaining compatibility with Node.js 0.10.",
"peer": true,
"version": "1.4.5-lts.1",
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz",
"integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==",
"dependencies": {
"append-field": "^1.0.0",
"busboy": "^0.2.11",
"busboy": "^1.0.0",
"concat-stream": "^1.5.2",
"mkdirp": "^0.5.4",
"object-assign": "^4.1.1",
"on-finished": "^2.3.0",
"type-is": "^1.6.4",
"xtend": "^4.0.0"
},
"engines": {
"node": ">= 0.10.0"
}
},
"node_modules/multer-gridfs-storage": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/multer-gridfs-storage/-/multer-gridfs-storage-5.0.2.tgz",
"integrity": "sha512-oYl70i792uyJfgpvOfJrZIru4MsjjAueDHLZXTDGix/yPJuk1/lfqdPHHnv/XVVGfVZb4G9jJqwEFf9JIX1SOQ==",
"dependencies": {
"@types/express": "^4.17.6",
"@types/mongodb": "^3.5.25",
"@types/multer": "^1.4.3",
"@types/pump": "^1.1.0",
"has-own-prop": "^2.0.0",
"is-generator": "^1.0.3",
"is-promise": "^4.0.0",
"lodash.isplainobject": ">=0.8.0",
"mongodb": ">=2",
"mongodb-uri": "^0.9.7",
"pump": "^3.0.0"
},
"engines": {
"node": ">=12"
},
"peerDependencies": {
"multer": "^1.4.2"
"node": ">= 6.0.0"
}
},
"node_modules/multer/node_modules/concat-stream": {
@ -7132,7 +6938,6 @@
"engines": [
"node >= 0.8"
],
"peer": true,
"dependencies": {
"buffer-from": "^1.0.0",
"inherits": "^2.0.3",
@ -7144,7 +6949,6 @@
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
"peer": true,
"dependencies": {
"minimist": "^1.2.6"
},
@ -7153,10 +6957,9 @@
}
},
"node_modules/multer/node_modules/readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"peer": true,
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
@ -7170,14 +6973,12 @@
"node_modules/multer/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"peer": true
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"node_modules/multer/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"peer": true,
"dependencies": {
"safe-buffer": "~5.1.0"
}
@ -7639,6 +7440,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/path": {
"version": "0.12.7",
"resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz",
"integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==",
"dependencies": {
"process": "^0.11.1",
"util": "^0.10.3"
}
},
"node_modules/path-exists": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
@ -9135,12 +8945,11 @@
}
},
"node_modules/streamsearch": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
"integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==",
"peer": true,
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
"integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==",
"engines": {
"node": ">=0.8.0"
"node": ">=10.0.0"
}
},
"node_modules/string_decoder": {
@ -9967,11 +9776,24 @@
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/util": {
"version": "0.10.4",
"resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
"integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
"dependencies": {
"inherits": "2.0.3"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
"node_modules/util/node_modules/inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw=="
},
"node_modules/utility": {
"version": "1.17.0",
"resolved": "https://registry.npmjs.org/utility/-/utility-1.17.0.tgz",

@ -1,21 +0,0 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

@ -1,16 +0,0 @@
# Installation
> `npm install --save @types/body-parser`
# Summary
This package contains type definitions for body-parser (https://github.com/expressjs/body-parser).
# Details
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/body-parser.
### Additional Details
* Last updated: Tue, 16 Nov 2021 18:31:30 GMT
* Dependencies: [@types/connect](https://npmjs.com/package/@types/connect), [@types/node](https://npmjs.com/package/@types/node)
* Global values: none
# Credits
These definitions were written by [Santi Albo](https://github.com/santialbo), [Vilic Vane](https://github.com/vilic), [Jonathan Häberle](https://github.com/dreampulse), [Gevik Babakhani](https://github.com/blendsdk), [Tomasz Łaziuk](https://github.com/tlaziuk), [Jason Walton](https://github.com/jwalton), and [Piotr Błażejewicz](https://github.com/peterblazejewicz).

@ -1,107 +0,0 @@
// Type definitions for body-parser 1.19
// Project: https://github.com/expressjs/body-parser
// Definitions by: Santi Albo <https://github.com/santialbo>
// Vilic Vane <https://github.com/vilic>
// Jonathan Häberle <https://github.com/dreampulse>
// Gevik Babakhani <https://github.com/blendsdk>
// Tomasz Łaziuk <https://github.com/tlaziuk>
// Jason Walton <https://github.com/jwalton>
// Piotr Błażejewicz <https://github.com/peterblazejewicz>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/// <reference types="node" />
import { NextHandleFunction } from 'connect';
import * as http from 'http';
// for docs go to https://github.com/expressjs/body-parser/tree/1.19.0#body-parser
declare namespace bodyParser {
interface BodyParser {
/**
* @deprecated use individual json/urlencoded middlewares
*/
(options?: OptionsJson & OptionsText & OptionsUrlencoded): NextHandleFunction;
/**
* Returns middleware that only parses json and only looks at requests
* where the Content-Type header matches the type option.
*/
json(options?: OptionsJson): NextHandleFunction;
/**
* Returns middleware that parses all bodies as a Buffer and only looks at requests
* where the Content-Type header matches the type option.
*/
raw(options?: Options): NextHandleFunction;
/**
* Returns middleware that parses all bodies as a string and only looks at requests
* where the Content-Type header matches the type option.
*/
text(options?: OptionsText): NextHandleFunction;
/**
* Returns middleware that only parses urlencoded bodies and only looks at requests
* where the Content-Type header matches the type option
*/
urlencoded(options?: OptionsUrlencoded): NextHandleFunction;
}
interface Options {
/** When set to true, then deflated (compressed) bodies will be inflated; when false, deflated bodies are rejected. Defaults to true. */
inflate?: boolean | undefined;
/**
* Controls the maximum request body size. If this is a number,
* then the value specifies the number of bytes; if it is a string,
* the value is passed to the bytes library for parsing. Defaults to '100kb'.
*/
limit?: number | string | undefined;
/**
* The type option is used to determine what media type the middleware will parse
*/
type?: string | string[] | ((req: http.IncomingMessage) => any) | undefined;
/**
* The verify option, if supplied, is called as verify(req, res, buf, encoding),
* where buf is a Buffer of the raw request body and encoding is the encoding of the request.
*/
verify?(req: http.IncomingMessage, res: http.ServerResponse, buf: Buffer, encoding: string): void;
}
interface OptionsJson extends Options {
/**
*
* The reviver option is passed directly to JSON.parse as the second argument.
*/
reviver?(key: string, value: any): any;
/**
* When set to `true`, will only accept arrays and objects;
* when `false` will accept anything JSON.parse accepts. Defaults to `true`.
*/
strict?: boolean | undefined;
}
interface OptionsText extends Options {
/**
* Specify the default character set for the text content if the charset
* is not specified in the Content-Type header of the request.
* Defaults to `utf-8`.
*/
defaultCharset?: string | undefined;
}
interface OptionsUrlencoded extends Options {
/**
* The extended option allows to choose between parsing the URL-encoded data
* with the querystring library (when `false`) or the qs library (when `true`).
*/
extended?: boolean | undefined;
/**
* The parameterLimit option controls the maximum number of parameters
* that are allowed in the URL-encoded data. If a request contains more parameters than this value,
* a 413 will be returned to the client. Defaults to 1000.
*/
parameterLimit?: number | undefined;
}
}
declare const bodyParser: bodyParser.BodyParser;
export = bodyParser;

@ -1,58 +0,0 @@
{
"name": "@types/body-parser",
"version": "1.19.2",
"description": "TypeScript definitions for body-parser",
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/body-parser",
"license": "MIT",
"contributors": [
{
"name": "Santi Albo",
"url": "https://github.com/santialbo",
"githubUsername": "santialbo"
},
{
"name": "Vilic Vane",
"url": "https://github.com/vilic",
"githubUsername": "vilic"
},
{
"name": "Jonathan Häberle",
"url": "https://github.com/dreampulse",
"githubUsername": "dreampulse"
},
{
"name": "Gevik Babakhani",
"url": "https://github.com/blendsdk",
"githubUsername": "blendsdk"
},
{
"name": "Tomasz Łaziuk",
"url": "https://github.com/tlaziuk",
"githubUsername": "tlaziuk"
},
{
"name": "Jason Walton",
"url": "https://github.com/jwalton",
"githubUsername": "jwalton"
},
{
"name": "Piotr Błażejewicz",
"url": "https://github.com/peterblazejewicz",
"githubUsername": "peterblazejewicz"
}
],
"main": "",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
"directory": "types/body-parser"
},
"scripts": {},
"dependencies": {
"@types/connect": "*",
"@types/node": "*"
},
"typesPublisherContentHash": "ad069aa8b9e8a95f66df025de11975c773540e4071000abdb7db565579b013ee",
"typeScriptVersion": "3.7"
}

@ -1,21 +0,0 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

@ -1,16 +0,0 @@
# Installation
> `npm install --save @types/connect`
# Summary
This package contains type definitions for connect (https://github.com/senchalabs/connect).
# Details
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/connect.
### Additional Details
* Last updated: Tue, 06 Jul 2021 20:32:28 GMT
* Dependencies: [@types/node](https://npmjs.com/package/@types/node)
* Global values: none
# Credits
These definitions were written by [Maxime LUCE](https://github.com/SomaticIT), and [Evan Hahn](https://github.com/EvanHahn).

@ -1,93 +0,0 @@
// Type definitions for connect v3.4.0
// Project: https://github.com/senchalabs/connect
// Definitions by: Maxime LUCE <https://github.com/SomaticIT>
// Evan Hahn <https://github.com/EvanHahn>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/// <reference types="node" />
import * as http from "http";
/**
* Create a new connect server.
*/
declare function createServer(): createServer.Server;
declare namespace createServer {
export type ServerHandle = HandleFunction | http.Server;
export class IncomingMessage extends http.IncomingMessage {
originalUrl?: http.IncomingMessage["url"] | undefined;
}
type NextFunction = (err?: any) => void;
export type SimpleHandleFunction = (req: IncomingMessage, res: http.ServerResponse) => void;
export type NextHandleFunction = (req: IncomingMessage, res: http.ServerResponse, next: NextFunction) => void;
export type ErrorHandleFunction = (err: any, req: IncomingMessage, res: http.ServerResponse, next: NextFunction) => void;
export type HandleFunction = SimpleHandleFunction | NextHandleFunction | ErrorHandleFunction;
export interface ServerStackItem {
route: string;
handle: ServerHandle;
}
export interface Server extends NodeJS.EventEmitter {
(req: http.IncomingMessage, res: http.ServerResponse, next?: Function): void;
route: string;
stack: ServerStackItem[];
/**
* Utilize the given middleware `handle` to the given `route`,
* defaulting to _/_. This "route" is the mount-point for the
* middleware, when given a value other than _/_ the middleware
* is only effective when that segment is present in the request's
* pathname.
*
* For example if we were to mount a function at _/admin_, it would
* be invoked on _/admin_, and _/admin/settings_, however it would
* not be invoked for _/_, or _/posts_.
*/
use(fn: NextHandleFunction): Server;
use(fn: HandleFunction): Server;
use(route: string, fn: NextHandleFunction): Server;
use(route: string, fn: HandleFunction): Server;
/**
* Handle server requests, punting them down
* the middleware stack.
*/
handle(req: http.IncomingMessage, res: http.ServerResponse, next: Function): void;
/**
* Listen for connections.
*
* This method takes the same arguments
* as node's `http.Server#listen()`.
*
* HTTP and HTTPS:
*
* If you run your application both as HTTP
* and HTTPS you may wrap them individually,
* since your Connect "server" is really just
* a JavaScript `Function`.
*
* var connect = require('connect')
* , http = require('http')
* , https = require('https');
*
* var app = connect();
*
* http.createServer(app).listen(80);
* https.createServer(options, app).listen(443);
*/
listen(port: number, hostname?: string, backlog?: number, callback?: Function): http.Server;
listen(port: number, hostname?: string, callback?: Function): http.Server;
listen(path: string, callback?: Function): http.Server;
listen(handle: any, listeningListener?: Function): http.Server;
}
}
export = createServer;

@ -1,32 +0,0 @@
{
"name": "@types/connect",
"version": "3.4.35",
"description": "TypeScript definitions for connect",
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/connect",
"license": "MIT",
"contributors": [
{
"name": "Maxime LUCE",
"url": "https://github.com/SomaticIT",
"githubUsername": "SomaticIT"
},
{
"name": "Evan Hahn",
"url": "https://github.com/EvanHahn",
"githubUsername": "EvanHahn"
}
],
"main": "",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
"directory": "types/connect"
},
"scripts": {},
"dependencies": {
"@types/node": "*"
},
"typesPublisherContentHash": "09c0dcec5f675cb2bdd7487a85447955f769ef4ab174294478c4f055b528fecc",
"typeScriptVersion": "3.6"
}

@ -1,21 +0,0 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

@ -1,16 +0,0 @@
# Installation
> `npm install --save @types/express-serve-static-core`
# Summary
This package contains type definitions for Express (http://expressjs.com).
# Details
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/express-serve-static-core.
### Additional Details
* Last updated: Tue, 13 Sep 2022 18:26:26 GMT
* Dependencies: [@types/node](https://npmjs.com/package/@types/node), [@types/qs](https://npmjs.com/package/@types/qs), [@types/range-parser](https://npmjs.com/package/@types/range-parser)
* Global values: none
# Credits
These definitions were written by [Boris Yankov](https://github.com/borisyankov), [Satana Charuwichitratana](https://github.com/micksatana), [Sami Jaber](https://github.com/samijaber), [Jose Luis Leon](https://github.com/JoseLion), [David Stephens](https://github.com/dwrss), and [Shin Ando](https://github.com/andoshin11).

File diff suppressed because it is too large Load Diff

@ -1,54 +0,0 @@
{
"name": "@types/express-serve-static-core",
"version": "4.17.31",
"description": "TypeScript definitions for Express",
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/express-serve-static-core",
"license": "MIT",
"contributors": [
{
"name": "Boris Yankov",
"url": "https://github.com/borisyankov",
"githubUsername": "borisyankov"
},
{
"name": "Satana Charuwichitratana",
"url": "https://github.com/micksatana",
"githubUsername": "micksatana"
},
{
"name": "Sami Jaber",
"url": "https://github.com/samijaber",
"githubUsername": "samijaber"
},
{
"name": "Jose Luis Leon",
"url": "https://github.com/JoseLion",
"githubUsername": "JoseLion"
},
{
"name": "David Stephens",
"url": "https://github.com/dwrss",
"githubUsername": "dwrss"
},
{
"name": "Shin Ando",
"url": "https://github.com/andoshin11",
"githubUsername": "andoshin11"
}
],
"main": "",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
"directory": "types/express-serve-static-core"
},
"scripts": {},
"dependencies": {
"@types/node": "*",
"@types/qs": "*",
"@types/range-parser": "*"
},
"typesPublisherContentHash": "9f714068b422a8e3ba9eac20ddf48fbcaa24a940fcd22920c164887ab8fe2b64",
"typeScriptVersion": "4.1"
}

@ -1,21 +0,0 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

@ -1,16 +0,0 @@
# Installation
> `npm install --save @types/express`
# Summary
This package contains type definitions for Express (http://expressjs.com).
# Details
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/express.
### Additional Details
* Last updated: Tue, 13 Dec 2022 23:33:24 GMT
* Dependencies: [@types/body-parser](https://npmjs.com/package/@types/body-parser), [@types/express-serve-static-core](https://npmjs.com/package/@types/express-serve-static-core), [@types/qs](https://npmjs.com/package/@types/qs), [@types/serve-static](https://npmjs.com/package/@types/serve-static)
* Global values: none
# Credits
These definitions were written by [Boris Yankov](https://github.com/borisyankov), [China Medical University Hospital](https://github.com/CMUH), [Puneet Arora](https://github.com/puneetar), and [Dylan Frankland](https://github.com/dfrankland).

@ -1,133 +0,0 @@
// Type definitions for Express 4.17
// Project: http://expressjs.com
// Definitions by: Boris Yankov <https://github.com/borisyankov>
// China Medical University Hospital <https://github.com/CMUH>
// Puneet Arora <https://github.com/puneetar>
// Dylan Frankland <https://github.com/dfrankland>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/* =================== USAGE ===================
import express = require("express");
var app = express();
=============================================== */
/// <reference types="express-serve-static-core" />
/// <reference types="serve-static" />
import * as bodyParser from 'body-parser';
import * as serveStatic from 'serve-static';
import * as core from 'express-serve-static-core';
import * as qs from 'qs';
/**
* Creates an Express application. The express() function is a top-level function exported by the express module.
*/
declare function e(): core.Express;
declare namespace e {
/**
* This is a built-in middleware function in Express. It parses incoming requests with JSON payloads and is based on body-parser.
* @since 4.16.0
*/
var json: typeof bodyParser.json;
/**
* This is a built-in middleware function in Express. It parses incoming requests with Buffer payloads and is based on body-parser.
* @since 4.17.0
*/
var raw: typeof bodyParser.raw;
/**
* This is a built-in middleware function in Express. It parses incoming requests with text payloads and is based on body-parser.
* @since 4.17.0
*/
var text: typeof bodyParser.text;
/**
* These are the exposed prototypes.
*/
var application: Application;
var request: Request;
var response: Response;
/**
* This is a built-in middleware function in Express. It serves static files and is based on serve-static.
*/
var static: serveStatic.RequestHandlerConstructor<Response>;
/**
* This is a built-in middleware function in Express. It parses incoming requests with urlencoded payloads and is based on body-parser.
* @since 4.16.0
*/
var urlencoded: typeof bodyParser.urlencoded;
/**
* This is a built-in middleware function in Express. It parses incoming request query parameters.
*/
export function query(options: qs.IParseOptions | typeof qs.parse): Handler;
export function Router(options?: RouterOptions): core.Router;
interface RouterOptions {
/**
* Enable case sensitivity.
*/
caseSensitive?: boolean | undefined;
/**
* Preserve the req.params values from the parent router.
* If the parent and the child have conflicting param names, the childs value take precedence.
*
* @default false
* @since 4.5.0
*/
mergeParams?: boolean | undefined;
/**
* Enable strict routing.
*/
strict?: boolean | undefined;
}
interface Application extends core.Application {}
interface CookieOptions extends core.CookieOptions {}
interface Errback extends core.Errback {}
interface ErrorRequestHandler<
P = core.ParamsDictionary,
ResBody = any,
ReqBody = any,
ReqQuery = core.Query,
Locals extends Record<string, any> = Record<string, any>
> extends core.ErrorRequestHandler<P, ResBody, ReqBody, ReqQuery, Locals> {}
interface Express extends core.Express {}
interface Handler extends core.Handler {}
interface IRoute extends core.IRoute {}
interface IRouter extends core.IRouter {}
interface IRouterHandler<T> extends core.IRouterHandler<T> {}
interface IRouterMatcher<T> extends core.IRouterMatcher<T> {}
interface MediaType extends core.MediaType {}
interface NextFunction extends core.NextFunction {}
interface Request<
P = core.ParamsDictionary,
ResBody = any,
ReqBody = any,
ReqQuery = core.Query,
Locals extends Record<string, any> = Record<string, any>
> extends core.Request<P, ResBody, ReqBody, ReqQuery, Locals> {}
interface RequestHandler<
P = core.ParamsDictionary,
ResBody = any,
ReqBody = any,
ReqQuery = core.Query,
Locals extends Record<string, any> = Record<string, any>
> extends core.RequestHandler<P, ResBody, ReqBody, ReqQuery, Locals> {}
interface RequestParamHandler extends core.RequestParamHandler {}
export interface Response<ResBody = any, Locals extends Record<string, any> = Record<string, any>>
extends core.Response<ResBody, Locals> {}
interface Router extends core.Router {}
interface Send extends core.Send {}
}
export = e;

@ -1,45 +0,0 @@
{
"name": "@types/express",
"version": "4.17.15",
"description": "TypeScript definitions for Express",
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/express",
"license": "MIT",
"contributors": [
{
"name": "Boris Yankov",
"url": "https://github.com/borisyankov",
"githubUsername": "borisyankov"
},
{
"name": "China Medical University Hospital",
"url": "https://github.com/CMUH",
"githubUsername": "CMUH"
},
{
"name": "Puneet Arora",
"url": "https://github.com/puneetar",
"githubUsername": "puneetar"
},
{
"name": "Dylan Frankland",
"url": "https://github.com/dfrankland",
"githubUsername": "dfrankland"
}
],
"main": "",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
"directory": "types/express"
},
"scripts": {},
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.31",
"@types/qs": "*",
"@types/serve-static": "*"
},
"typesPublisherContentHash": "a3b86a7c7eb6f9cd2c24e3ecba223a93a983155d3c2e3bdd1a9d006150af8455",
"typeScriptVersion": "4.2"
}

21
node_modules/@types/mime/LICENSE generated vendored

@ -1,21 +0,0 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

@ -1,11 +0,0 @@
import type { TypeMap } from './index';
declare class Mime {
constructor(typeMap: TypeMap, ...mimes: TypeMap[]);
getType(path: string): string | null;
getExtension(mime: string): string | null;
define(typeMap: TypeMap, force?: boolean): void;
}
export = Mime;

@ -1,16 +0,0 @@
# Installation
> `npm install --save @types/mime`
# Summary
This package contains type definitions for mime (https://github.com/broofa/node-mime).
# Details
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/mime.
### Additional Details
* Last updated: Thu, 04 Aug 2022 21:02:19 GMT
* Dependencies: none
* Global values: `mime`, `mimelite`
# Credits
These definitions were written by [Jeff Goddard](https://github.com/jedigo), and [Daniel Hritzkiv](https://github.com/dhritzkiv).

@ -1,21 +0,0 @@
// Type definitions for mime 3.0
// Project: https://github.com/broofa/node-mime
// Definitions by: Jeff Goddard <https://github.com/jedigo>
// Daniel Hritzkiv <https://github.com/dhritzkiv>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// Originally imported from: https://github.com/soywiz/typescript-node-definitions/mime.d.ts
import Mime = require('./Mime');
export as namespace mime;
declare namespace mime {
interface TypeMap {
[key: string]: string[];
}
}
declare const mime: Mime;
export = mime;

@ -1,7 +0,0 @@
import Mime = require('./Mime');
declare const mimelite: Mime;
export as namespace mimelite;
export = mimelite;

@ -1,30 +0,0 @@
{
"name": "@types/mime",
"version": "3.0.1",
"description": "TypeScript definitions for mime",
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/mime",
"license": "MIT",
"contributors": [
{
"name": "Jeff Goddard",
"url": "https://github.com/jedigo",
"githubUsername": "jedigo"
},
{
"name": "Daniel Hritzkiv",
"url": "https://github.com/dhritzkiv",
"githubUsername": "dhritzkiv"
}
],
"main": "",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
"directory": "types/mime"
},
"scripts": {},
"dependencies": {},
"typesPublisherContentHash": "594e1e4777af908b69119d71c37be0a70e63c840095dcdb0881343b51b7286f3",
"typeScriptVersion": "4.0"
}

@ -1,21 +0,0 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

@ -1,16 +0,0 @@
# Installation
> `npm install --save @types/multer`
# Summary
This package contains type definitions for multer (https://github.com/expressjs/multer).
# Details
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/multer.
### Additional Details
* Last updated: Wed, 07 Jul 2021 00:01:45 GMT
* Dependencies: [@types/express](https://npmjs.com/package/@types/express)
* Global values: none
# Credits
These definitions were written by [jt000](https://github.com/jt000), [vilicvane](https://github.com/vilic), [David Broder-Rodgers](https://github.com/DavidBR-SW), [Michael Ledin](https://github.com/mxl), [HyunSeob Lee](https://github.com/hyunseob), [Pierre Tchuente](https://github.com/PierreTchuente), [Oliver Emery](https://github.com/thrymgjol), and [Piotr Błażejewicz](https://github.com/peterblazejewicz).

@ -1,321 +0,0 @@
// Type definitions for multer 1.4
// Project: https://github.com/expressjs/multer
// Definitions by: jt000 <https://github.com/jt000>
// vilicvane <https://github.com/vilic>
// David Broder-Rodgers <https://github.com/DavidBR-SW>
// Michael Ledin <https://github.com/mxl>
// HyunSeob Lee <https://github.com/hyunseob>
// Pierre Tchuente <https://github.com/PierreTchuente>
// Oliver Emery <https://github.com/thrymgjol>
// Piotr Błażejewicz <https://github.com/peterblazejewicz>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
import { Request, RequestHandler } from 'express';
import { Readable } from 'stream';
declare global {
namespace Express {
namespace Multer {
/** Object containing file metadata and access information. */
interface File {
/** Name of the form field associated with this file. */
fieldname: string;
/** Name of the file on the uploader's computer. */
originalname: string;
/**
* Value of the `Content-Transfer-Encoding` header for this file.
* @deprecated since July 2015
* @see RFC 7578, Section 4.7
*/
encoding: string;
/** Value of the `Content-Type` header for this file. */
mimetype: string;
/** Size of the file in bytes. */
size: number;
/**
* A readable stream of this file. Only available to the `_handleFile`
* callback for custom `StorageEngine`s.
*/
stream: Readable;
/** `DiskStorage` only: Directory to which this file has been uploaded. */
destination: string;
/** `DiskStorage` only: Name of this file within `destination`. */
filename: string;
/** `DiskStorage` only: Full path to the uploaded file. */
path: string;
/** `MemoryStorage` only: A Buffer containing the entire file. */
buffer: Buffer;
}
}
interface Request {
/** `Multer.File` object populated by `single()` middleware. */
file?: Multer.File | undefined;
/**
* Array or dictionary of `Multer.File` object populated by `array()`,
* `fields()`, and `any()` middleware.
*/
files?: {
[fieldname: string]: Multer.File[];
} | Multer.File[] | undefined;
}
}
}
/**
* Returns a Multer instance that provides several methods for generating
* middleware that process files uploaded in `multipart/form-data` format.
*
* The `StorageEngine` specified in `storage` will be used to store files. If
* `storage` is not set and `dest` is, files will be stored in `dest` on the
* local file system with random names. If neither are set, files will be stored
* in memory.
*
* In addition to files, all generated middleware process all text fields in
* the request. For each non-file field, the `Request.body` object will be
* populated with an entry mapping the field name to its string value, or array
* of string values if multiple fields share the same name.
*/
declare function multer(options?: multer.Options): multer.Multer;
declare namespace multer {
/**
* @see {@link https://github.com/expressjs/multer#api}
*/
interface Multer {
/**
* Returns middleware that processes a single file associated with the
* given form field.
*
* The `Request` object will be populated with a `file` object containing
* information about the processed file.
*
* @param fieldName Name of the multipart form field to process.
*/
single(fieldName: string): RequestHandler;
/**
* Returns middleware that processes multiple files sharing the same field
* name.
*
* The `Request` object will be populated with a `files` array containing
* an information object for each processed file.
*
* @param fieldName Shared name of the multipart form fields to process.
* @param maxCount Optional. Maximum number of files to process. (default: Infinity)
* @throws `MulterError('LIMIT_UNEXPECTED_FILE')` if more than `maxCount` files are associated with `fieldName`
*/
array(fieldName: string, maxCount?: number): RequestHandler;
/**
* Returns middleware that processes multiple files associated with the
* given form fields.
*
* The `Request` object will be populated with a `files` object which
* maps each field name to an array of the associated file information
* objects.
*
* @param fields Array of `Field` objects describing multipart form fields to process.
* @throws `MulterError('LIMIT_UNEXPECTED_FILE')` if more than `maxCount` files are associated with `fieldName` for any field.
*/
fields(fields: ReadonlyArray<Field>): RequestHandler;
/**
* Returns middleware that processes all files contained in the multipart
* request.
*
* The `Request` object will be populated with a `files` array containing
* an information object for each processed file.
*/
any(): RequestHandler;
/**
* Returns middleware that accepts only non-file multipart form fields.
*
* @throws `MulterError('LIMIT_UNEXPECTED_FILE')` if any file is encountered.
*/
none(): RequestHandler;
}
/**
* Returns a `StorageEngine` implementation configured to store files on
* the local file system.
*
* A string or function may be specified to determine the destination
* directory, and a function to determine filenames. If no options are set,
* files will be stored in the system's temporary directory with random 32
* character filenames.
*/
function diskStorage(options: DiskStorageOptions): StorageEngine;
/**
* Returns a `StorageEngine` implementation configured to store files in
* memory as `Buffer` objects.
*/
function memoryStorage(): StorageEngine;
type ErrorCode =
| 'LIMIT_PART_COUNT'
| 'LIMIT_FILE_SIZE'
| 'LIMIT_FILE_COUNT'
| 'LIMIT_FIELD_KEY'
| 'LIMIT_FIELD_VALUE'
| 'LIMIT_FIELD_COUNT'
| 'LIMIT_UNEXPECTED_FILE';
class MulterError extends Error {
constructor(code: ErrorCode, field?: string);
/** Name of the MulterError constructor. */
name: string;
/** Identifying error code. */
code: ErrorCode;
/** Descriptive error message. */
message: string;
/** Name of the multipart form field associated with this error. */
field?: string | undefined;
}
/**
* a function to control which files should be uploaded and which should be skipped
* pass a boolean to indicate if the file should be accepted
* pass an error if something goes wrong
*/
interface FileFilterCallback {
(error: Error): void;
(error: null, acceptFile: boolean): void;
}
/** Options for initializing a Multer instance. */
interface Options {
/**
* A `StorageEngine` responsible for processing files uploaded via Multer.
* Takes precedence over `dest`.
*/
storage?: StorageEngine | undefined;
/**
* The destination directory for uploaded files. If `storage` is not set
* and `dest` is, Multer will create a `DiskStorage` instance configured
* to store files at `dest` with random filenames.
*
* Ignored if `storage` is set.
*/
dest?: string | undefined;
/**
* An object specifying various limits on incoming data. This object is
* passed to Busboy directly, and the details of properties can be found
* at https://github.com/mscdex/busboy#busboy-methods.
*/
limits?: {
/** Maximum size of each form field name in bytes. (Default: 100) */
fieldNameSize?: number | undefined;
/** Maximum size of each form field value in bytes. (Default: 1048576) */
fieldSize?: number | undefined;
/** Maximum number of non-file form fields. (Default: Infinity) */
fields?: number | undefined;
/** Maximum size of each file in bytes. (Default: Infinity) */
fileSize?: number | undefined;
/** Maximum number of file fields. (Default: Infinity) */
files?: number | undefined;
/** Maximum number of parts (non-file fields + files). (Default: Infinity) */
parts?: number | undefined;
/** Maximum number of headers. (Default: 2000) */
headerPairs?: number | undefined;
} | undefined;
/** Preserve the full path of the original filename rather than the basename. (Default: false) */
preservePath?: boolean | undefined;
/**
* Optional function to control which files are uploaded. This is called
* for every file that is processed.
*
* @param req The Express `Request` object.
* @param file Object containing information about the processed file.
* @param callback a function to control which files should be uploaded and which should be skipped.
*/
fileFilter?(
req: Request,
file: Express.Multer.File,
callback: FileFilterCallback,
): void;
}
/**
* Implementations of this interface are responsible for storing files
* encountered by Multer and returning information on how to access them
* once stored. Implementations must also provide a method for removing
* files in the event that an error occurs.
*/
interface StorageEngine {
/**
* Store the file described by `file`, then invoke the callback with
* information about the stored file.
*
* File contents are available as a stream via `file.stream`. Information
* passed to the callback will be merged with `file` for subsequent
* middleware.
*
* @param req The Express `Request` object.
* @param file Object with `stream`, `fieldname`, `originalname`, `encoding`, and `mimetype` defined.
* @param callback Callback to specify file information.
*/
_handleFile(
req: Request,
file: Express.Multer.File,
callback: (error?: any, info?: Partial<Express.Multer.File>) => void
): void;
/**
* Remove the file described by `file`, then invoke the callback with.
*
* `file` contains all the properties available to `_handleFile`, as
* well as those returned by `_handleFile`.
*
* @param req The Express `Request` object.
* @param file Object containing information about the processed file.
* @param callback Callback to indicate completion.
*/
_removeFile(
req: Request,
file: Express.Multer.File,
callback: (error: Error | null) => void
): void;
}
interface DiskStorageOptions {
/**
* A string or function that determines the destination path for uploaded
* files. If a string is passed and the directory does not exist, Multer
* attempts to create it recursively. If neither a string or a function
* is passed, the destination defaults to `os.tmpdir()`.
*
* @param req The Express `Request` object.
* @param file Object containing information about the processed file.
* @param callback Callback to determine the destination path.
*/
destination?: string | ((
req: Request,
file: Express.Multer.File,
callback: (error: Error | null, destination: string) => void
) => void) | undefined;
/**
* A function that determines the name of the uploaded file. If nothing
* is passed, Multer will generate a 32 character pseudorandom hex string
* with no extension.
*
* @param req The Express `Request` object.
* @param file Object containing information about the processed file.
* @param callback Callback to determine the name of the uploaded file.
*/
filename?(
req: Request,
file: Express.Multer.File,
callback: (error: Error | null, filename: string) => void
): void;
}
/**
* An object describing a field name and the maximum number of files with
* that field name to accept.
*/
interface Field {
/** The field name. */
name: string;
/** Optional maximum number of files per field to accept. (Default: Infinity) */
maxCount?: number | undefined;
}
}
export = multer;

@ -1,62 +0,0 @@
{
"name": "@types/multer",
"version": "1.4.7",
"description": "TypeScript definitions for multer",
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/multer",
"license": "MIT",
"contributors": [
{
"name": "jt000",
"url": "https://github.com/jt000",
"githubUsername": "jt000"
},
{
"name": "vilicvane",
"url": "https://github.com/vilic",
"githubUsername": "vilic"
},
{
"name": "David Broder-Rodgers",
"url": "https://github.com/DavidBR-SW",
"githubUsername": "DavidBR-SW"
},
{
"name": "Michael Ledin",
"url": "https://github.com/mxl",
"githubUsername": "mxl"
},
{
"name": "HyunSeob Lee",
"url": "https://github.com/hyunseob",
"githubUsername": "hyunseob"
},
{
"name": "Pierre Tchuente",
"url": "https://github.com/PierreTchuente",
"githubUsername": "PierreTchuente"
},
{
"name": "Oliver Emery",
"url": "https://github.com/thrymgjol",
"githubUsername": "thrymgjol"
},
{
"name": "Piotr Błażejewicz",
"url": "https://github.com/peterblazejewicz",
"githubUsername": "peterblazejewicz"
}
],
"main": "",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
"directory": "types/multer"
},
"scripts": {},
"dependencies": {
"@types/express": "*"
},
"typesPublisherContentHash": "32b2d0cc5d84f278945858a1be2b00bcdd046da7c6e0886d5afd0d1e002ee95a",
"typeScriptVersion": "3.6"
}

21
node_modules/@types/pump/LICENSE generated vendored

@ -1,21 +0,0 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

@ -1,16 +0,0 @@
# Installation
> `npm install --save @types/pump`
# Summary
This package contains type definitions for pump (https://github.com/mafintosh/pump).
# Details
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/pump.
### Additional Details
* Last updated: Mon, 22 Feb 2021 06:14:03 GMT
* Dependencies: [@types/node](https://npmjs.com/package/@types/node)
* Global values: none
# Credits
These definitions were written by [Tomek Łaziuk](https://github.com/tlaziuk), and [Jason Cordial](https://github.com/jcordial).

@ -1,18 +0,0 @@
// Type definitions for pump 1.1
// Project: https://github.com/mafintosh/pump
// Definitions by: Tomek Łaziuk <https://github.com/tlaziuk>, Jason Cordial <https://github.com/jcordial>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/// <reference types="node" />
declare function pump(streams: pump.Stream[], callback?: pump.Callback): pump.Stream;
// callback have to be passed as last argument
declare function pump(...streams: Array<pump.Stream | pump.Callback>): pump.Stream;
declare namespace pump {
type Callback = (err?: Error) => any;
type Stream = NodeJS.ReadableStream | NodeJS.WritableStream;
}
export = pump;

@ -1,31 +0,0 @@
{
"name": "@types/pump",
"version": "1.1.1",
"description": "TypeScript definitions for pump",
"license": "MIT",
"contributors": [
{
"name": "Tomek Łaziuk",
"url": "https://github.com/tlaziuk",
"githubUsername": "tlaziuk"
},
{
"name": "Jason Cordial",
"url": "https://github.com/jcordial",
"githubUsername": "jcordial"
}
],
"main": "",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
"directory": "types/pump"
},
"scripts": {},
"dependencies": {
"@types/node": "*"
},
"typesPublisherContentHash": "665f733d49c823db4fc1236803a666e08d17591a562d4c988996754f4353894b",
"typeScriptVersion": "3.4"
}

21
node_modules/@types/qs/LICENSE generated vendored

@ -1,21 +0,0 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

16
node_modules/@types/qs/README.md generated vendored

@ -1,16 +0,0 @@
# Installation
> `npm install --save @types/qs`
# Summary
This package contains type definitions for qs (https://github.com/ljharb/qs).
# Details
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/qs.
### Additional Details
* Last updated: Wed, 07 Jul 2021 17:02:42 GMT
* Dependencies: none
* Global values: `qs`
# Credits
These definitions were written by [Roman Korneev](https://github.com/RWander), [Leon Yu](https://github.com/leonyu), [Belinda Teh](https://github.com/tehbelinda), [Melvin Lee](https://github.com/zyml), [Arturs Vonda](https://github.com/artursvonda), [Carlos Bonetti](https://github.com/CarlosBonetti), [Dan Smith](https://github.com/dpsmith3), [Hunter Perrin](https://github.com/hperrin), and [Jordan Harband](https://github.com/ljharb).

62
node_modules/@types/qs/index.d.ts generated vendored

@ -1,62 +0,0 @@
// Type definitions for qs 6.9
// Project: https://github.com/ljharb/qs
// Definitions by: Roman Korneev <https://github.com/RWander>
// Leon Yu <https://github.com/leonyu>
// Belinda Teh <https://github.com/tehbelinda>
// Melvin Lee <https://github.com/zyml>
// Arturs Vonda <https://github.com/artursvonda>
// Carlos Bonetti <https://github.com/CarlosBonetti>
// Dan Smith <https://github.com/dpsmith3>
// Hunter Perrin <https://github.com/hperrin>
// Jordan Harband <https://github.com/ljharb>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
export = QueryString;
export as namespace qs;
declare namespace QueryString {
type defaultEncoder = (str: any, defaultEncoder?: any, charset?: string) => string;
type defaultDecoder = (str: string, decoder?: any, charset?: string) => string;
interface IStringifyOptions {
delimiter?: string | undefined;
strictNullHandling?: boolean | undefined;
skipNulls?: boolean | undefined;
encode?: boolean | undefined;
encoder?: ((str: any, defaultEncoder: defaultEncoder, charset: string, type: 'key' | 'value') => string) | undefined;
filter?: Array<string | number> | ((prefix: string, value: any) => any) | undefined;
arrayFormat?: 'indices' | 'brackets' | 'repeat' | 'comma' | undefined;
indices?: boolean | undefined;
sort?: ((a: any, b: any) => number) | undefined;
serializeDate?: ((d: Date) => string) | undefined;
format?: 'RFC1738' | 'RFC3986' | undefined;
encodeValuesOnly?: boolean | undefined;
addQueryPrefix?: boolean | undefined;
allowDots?: boolean | undefined;
charset?: 'utf-8' | 'iso-8859-1' | undefined;
charsetSentinel?: boolean | undefined;
}
interface IParseOptions {
comma?: boolean | undefined;
delimiter?: string | RegExp | undefined;
depth?: number | false | undefined;
decoder?: ((str: string, defaultDecoder: defaultDecoder, charset: string, type: 'key' | 'value') => any) | undefined;
arrayLimit?: number | undefined;
parseArrays?: boolean | undefined;
allowDots?: boolean | undefined;
plainObjects?: boolean | undefined;
allowPrototypes?: boolean | undefined;
parameterLimit?: number | undefined;
strictNullHandling?: boolean | undefined;
ignoreQueryPrefix?: boolean | undefined;
charset?: 'utf-8' | 'iso-8859-1' | undefined;
charsetSentinel?: boolean | undefined;
interpretNumericEntities?: boolean | undefined;
}
interface ParsedQs { [key: string]: undefined | string | string[] | ParsedQs | ParsedQs[] }
function stringify(obj: any, options?: IStringifyOptions): string;
function parse(str: string, options?: IParseOptions & { decoder?: never | undefined }): ParsedQs;
function parse(str: string | Record<string, string>, options?: IParseOptions): { [key: string]: unknown };
}

@ -1,65 +0,0 @@
{
"name": "@types/qs",
"version": "6.9.7",
"description": "TypeScript definitions for qs",
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/qs",
"license": "MIT",
"contributors": [
{
"name": "Roman Korneev",
"url": "https://github.com/RWander",
"githubUsername": "RWander"
},
{
"name": "Leon Yu",
"url": "https://github.com/leonyu",
"githubUsername": "leonyu"
},
{
"name": "Belinda Teh",
"url": "https://github.com/tehbelinda",
"githubUsername": "tehbelinda"
},
{
"name": "Melvin Lee",
"url": "https://github.com/zyml",
"githubUsername": "zyml"
},
{
"name": "Arturs Vonda",
"url": "https://github.com/artursvonda",
"githubUsername": "artursvonda"
},
{
"name": "Carlos Bonetti",
"url": "https://github.com/CarlosBonetti",
"githubUsername": "CarlosBonetti"
},
{
"name": "Dan Smith",
"url": "https://github.com/dpsmith3",
"githubUsername": "dpsmith3"
},
{
"name": "Hunter Perrin",
"url": "https://github.com/hperrin",
"githubUsername": "hperrin"
},
{
"name": "Jordan Harband",
"url": "https://github.com/ljharb",
"githubUsername": "ljharb"
}
],
"main": "",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
"directory": "types/qs"
},
"scripts": {},
"dependencies": {},
"typesPublisherContentHash": "b33fed3eed022f94c7db53593571f370eaa77aa17b3e302dc1bd77304f03e56c",
"typeScriptVersion": "3.6"
}

@ -1,21 +0,0 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

@ -1,55 +0,0 @@
# Installation
> `npm install --save @types/range-parser`
# Summary
This package contains type definitions for range-parser (https://github.com/jshttp/range-parser).
# Details
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/range-parser.
## [index.d.ts](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/range-parser/index.d.ts)
````ts
// Type definitions for range-parser 1.2
// Project: https://github.com/jshttp/range-parser
// Definitions by: Tomek Łaziuk <https://github.com/tlaziuk>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/**
* When ranges are returned, the array has a "type" property which is the type of
* range that is required (most commonly, "bytes"). Each array element is an object
* with a "start" and "end" property for the portion of the range.
*
* @returns `-1` when unsatisfiable and `-2` when syntactically invalid, ranges otherwise.
*/
declare function RangeParser(size: number, str: string, options?: RangeParser.Options): RangeParser.Result | RangeParser.Ranges;
declare namespace RangeParser {
interface Ranges extends Array<Range> {
type: string;
}
interface Range {
start: number;
end: number;
}
interface Options {
/**
* The "combine" option can be set to `true` and overlapping & adjacent ranges
* will be combined into a single range.
*/
combine?: boolean | undefined;
}
type ResultUnsatisfiable = -1;
type ResultInvalid = -2;
type Result = ResultUnsatisfiable | ResultInvalid;
}
export = RangeParser;
````
### Additional Details
* Last updated: Wed, 07 Jul 2021 17:02:53 GMT
* Dependencies: none
* Global values: none
# Credits
These definitions were written by [Tomek Łaziuk](https://github.com/tlaziuk).

@ -1,35 +0,0 @@
// Type definitions for range-parser 1.2
// Project: https://github.com/jshttp/range-parser
// Definitions by: Tomek Łaziuk <https://github.com/tlaziuk>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/**
* When ranges are returned, the array has a "type" property which is the type of
* range that is required (most commonly, "bytes"). Each array element is an object
* with a "start" and "end" property for the portion of the range.
*
* @returns `-1` when unsatisfiable and `-2` when syntactically invalid, ranges otherwise.
*/
declare function RangeParser(size: number, str: string, options?: RangeParser.Options): RangeParser.Result | RangeParser.Ranges;
declare namespace RangeParser {
interface Ranges extends Array<Range> {
type: string;
}
interface Range {
start: number;
end: number;
}
interface Options {
/**
* The "combine" option can be set to `true` and overlapping & adjacent ranges
* will be combined into a single range.
*/
combine?: boolean | undefined;
}
type ResultUnsatisfiable = -1;
type ResultInvalid = -2;
type Result = ResultUnsatisfiable | ResultInvalid;
}
export = RangeParser;

@ -1,25 +0,0 @@
{
"name": "@types/range-parser",
"version": "1.2.4",
"description": "TypeScript definitions for range-parser",
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/range-parser",
"license": "MIT",
"contributors": [
{
"name": "Tomek Łaziuk",
"url": "https://github.com/tlaziuk",
"githubUsername": "tlaziuk"
}
],
"main": "",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
"directory": "types/range-parser"
},
"scripts": {},
"dependencies": {},
"typesPublisherContentHash": "60a027a88ae9d7c5ae30935c98266f5033af3c38944121c975bf5e136b9053f3",
"typeScriptVersion": "3.6"
}

@ -1,21 +0,0 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

@ -1,16 +0,0 @@
# Installation
> `npm install --save @types/serve-static`
# Summary
This package contains type definitions for serve-static (https://github.com/expressjs/serve-static).
# Details
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/serve-static.
### Additional Details
* Last updated: Fri, 29 Jul 2022 22:02:20 GMT
* Dependencies: [@types/mime](https://npmjs.com/package/@types/mime), [@types/node](https://npmjs.com/package/@types/node)
* Global values: none
# Credits
These definitions were written by [Uros Smolnik](https://github.com/urossmolnik), [Linus Unnebäck](https://github.com/LinusU), and [Devansh Jethmalani](https://github.com/devanshj).

@ -1,107 +0,0 @@
// Type definitions for serve-static 1.15
// Project: https://github.com/expressjs/serve-static
// Definitions by: Uros Smolnik <https://github.com/urossmolnik>
// Linus Unnebäck <https://github.com/LinusU>
// Devansh Jethmalani <https://github.com/devanshj>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/// <reference types="node" />
import * as m from "mime";
import * as http from "http";
/**
* Create a new middleware function to serve files from within a given root directory.
* The file to serve will be determined by combining req.url with the provided root directory.
* When a file is not found, instead of sending a 404 response, this module will instead call next() to move on to the next middleware, allowing for stacking and fall-backs.
*/
declare function serveStatic<R extends http.ServerResponse>(
root: string,
options?: serveStatic.ServeStaticOptions<R>
): serveStatic.RequestHandler<R>;
declare namespace serveStatic {
var mime: typeof m;
interface ServeStaticOptions<R extends http.ServerResponse = http.ServerResponse> {
/**
* Enable or disable setting Cache-Control response header, defaults to true.
* Disabling this will ignore the immutable and maxAge options.
*/
cacheControl?: boolean | undefined;
/**
* Set how "dotfiles" are treated when encountered. A dotfile is a file or directory that begins with a dot (".").
* Note this check is done on the path itself without checking if the path actually exists on the disk.
* If root is specified, only the dotfiles above the root are checked (i.e. the root itself can be within a dotfile when when set to "deny").
* The default value is 'ignore'.
* 'allow' No special treatment for dotfiles
* 'deny' Send a 403 for any request for a dotfile
* 'ignore' Pretend like the dotfile does not exist and call next()
*/
dotfiles?: string | undefined;
/**
* Enable or disable etag generation, defaults to true.
*/
etag?: boolean | undefined;
/**
* Set file extension fallbacks. When set, if a file is not found, the given extensions will be added to the file name and search for.
* The first that exists will be served. Example: ['html', 'htm'].
* The default value is false.
*/
extensions?: string[] | false | undefined;
/**
* Let client errors fall-through as unhandled requests, otherwise forward a client error.
* The default value is true.
*/
fallthrough?: boolean | undefined;
/**
* Enable or disable the immutable directive in the Cache-Control response header.
* If enabled, the maxAge option should also be specified to enable caching. The immutable directive will prevent supported clients from making conditional requests during the life of the maxAge option to check if the file has changed.
*/
immutable?: boolean | undefined;
/**
* By default this module will send "index.html" files in response to a request on a directory.
* To disable this set false or to supply a new index pass a string or an array in preferred order.
*/
index?: boolean | string | string[] | undefined;
/**
* Enable or disable Last-Modified header, defaults to true. Uses the file system's last modified value.
*/
lastModified?: boolean | undefined;
/**
* Provide a max-age in milliseconds for http caching, defaults to 0. This can also be a string accepted by the ms module.
*/
maxAge?: number | string | undefined;
/**
* Redirect to trailing "/" when the pathname is a dir. Defaults to true.
*/
redirect?: boolean | undefined;
/**
* Function to set custom headers on response. Alterations to the headers need to occur synchronously.
* The function is called as fn(res, path, stat), where the arguments are:
* res the response object
* path the file path that is being sent
* stat the stat object of the file that is being sent
*/
setHeaders?: ((res: R, path: string, stat: any) => any) | undefined;
}
interface RequestHandler<R extends http.ServerResponse> {
(request: http.IncomingMessage, response: R, next: () => void): any;
}
interface RequestHandlerConstructor<R extends http.ServerResponse> {
(root: string, options?: ServeStaticOptions<R>): RequestHandler<R>;
mime: typeof m;
}
}
export = serveStatic;

@ -1,38 +0,0 @@
{
"name": "@types/serve-static",
"version": "1.15.0",
"description": "TypeScript definitions for serve-static",
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/serve-static",
"license": "MIT",
"contributors": [
{
"name": "Uros Smolnik",
"url": "https://github.com/urossmolnik",
"githubUsername": "urossmolnik"
},
{
"name": "Linus Unnebäck",
"url": "https://github.com/LinusU",
"githubUsername": "LinusU"
},
{
"name": "Devansh Jethmalani",
"url": "https://github.com/devanshj",
"githubUsername": "devanshj"
}
],
"main": "",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
"directory": "types/serve-static"
},
"scripts": {},
"dependencies": {
"@types/mime": "*",
"@types/node": "*"
},
"typesPublisherContentHash": "23c6a1b5183c0a097f74914c31b60d57b77620f3cbef3be91157347745af24ed",
"typeScriptVersion": "4.0"
}

5
node_modules/busboy/.eslintrc.js generated vendored

@ -0,0 +1,5 @@
'use strict';
module.exports = {
extends: '@mscdex/eslint-config',
};

@ -0,0 +1,24 @@
name: CI
on:
pull_request:
push:
branches: [ master ]
jobs:
tests-linux:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [10.16.0, 10.x, 12.x, 14.x, 16.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install module
run: npm install
- name: Run tests
run: npm test

@ -0,0 +1,23 @@
name: lint
on:
pull_request:
push:
branches: [ master ]
env:
NODE_VERSION: 16.x
jobs:
lint-js:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v1
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install ESLint + ESLint configs/plugins
run: npm install --only=dev
- name: Lint files
run: npm run lint

17
node_modules/busboy/.travis.yml generated vendored

@ -1,17 +0,0 @@
sudo: false
language: cpp
notifications:
email: false
env:
matrix:
- TRAVIS_NODE_VERSION="0.10"
- TRAVIS_NODE_VERSION="0.12"
- TRAVIS_NODE_VERSION="4"
- TRAVIS_NODE_VERSION="6"
- TRAVIS_NODE_VERSION="7"
install:
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION
- node --version
- npm --version
- npm install
script: npm test

248
node_modules/busboy/README.md generated vendored

@ -1,225 +1,191 @@
Description
===========
# Description
A node.js module for parsing incoming HTML form data.
If you've found this module to be useful and wish to support it, you may do so by visiting this pledgie campaign:
<a href='https://pledgie.com/campaigns/28774'><img alt='Click here to support busboy' src='https://pledgie.com/campaigns/28774.png?skin_name=chrome' border='0'></a>
Changes (breaking or otherwise) in v1.0.0 can be found [here](https://github.com/mscdex/busboy/issues/266).
# Requirements
Requirements
============
* [node.js](http://nodejs.org/) -- v10.16.0 or newer
* [node.js](http://nodejs.org/) -- v0.8.0 or newer
Install
=======
# Install
npm install busboy
Examples
========
# Examples
* Parsing (multipart) with default options:
```javascript
var http = require('http'),
inspect = require('util').inspect;
```js
const http = require('http');
var Busboy = require('busboy');
const busboy = require('busboy');
http.createServer(function(req, res) {
http.createServer((req, res) => {
if (req.method === 'POST') {
var busboy = new Busboy({ headers: req.headers });
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
console.log('File [' + fieldname + ']: filename: ' + filename + ', encoding: ' + encoding + ', mimetype: ' + mimetype);
file.on('data', function(data) {
console.log('File [' + fieldname + '] got ' + data.length + ' bytes');
});
file.on('end', function() {
console.log('File [' + fieldname + '] Finished');
console.log('POST request');
const bb = busboy({ headers: req.headers });
bb.on('file', (name, file, info) => {
const { filename, encoding, mimeType } = info;
console.log(
`File [${name}]: filename: %j, encoding: %j, mimeType: %j`,
filename,
encoding,
mimeType
);
file.on('data', (data) => {
console.log(`File [${name}] got ${data.length} bytes`);
}).on('close', () => {
console.log(`File [${name}] done`);
});
});
busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated, encoding, mimetype) {
console.log('Field [' + fieldname + ']: value: ' + inspect(val));
bb.on('field', (name, val, info) => {
console.log(`Field [${name}]: value: %j`, val);
});
busboy.on('finish', function() {
bb.on('close', () => {
console.log('Done parsing form!');
res.writeHead(303, { Connection: 'close', Location: '/' });
res.end();
});
req.pipe(busboy);
req.pipe(bb);
} else if (req.method === 'GET') {
res.writeHead(200, { Connection: 'close' });
res.end('<html><head></head><body>\
<form method="POST" enctype="multipart/form-data">\
<input type="text" name="textfield"><br />\
<input type="file" name="filefield"><br />\
<input type="submit">\
</form>\
</body></html>');
res.end(`
<html>
<head></head>
<body>
<form method="POST" enctype="multipart/form-data">
<input type="file" name="filefield"><br />
<input type="text" name="textfield"><br />
<input type="submit">
</form>
</body>
</html>
`);
}
}).listen(8000, function() {
}).listen(8000, () => {
console.log('Listening for requests');
});
// Example output, using http://nodejs.org/images/ryan-speaker.jpg as the file:
// Example output:
//
// Listening for requests
// File [filefield]: filename: ryan-speaker.jpg, encoding: binary
// File [filefield] got 11971 bytes
// Field [textfield]: value: 'testing! :-)'
// File [filefield] Finished
// < ... form submitted ... >
// POST request
// File [filefield]: filename: "logo.jpg", encoding: "binary", mime: "image/jpeg"
// File [filefield] got 11912 bytes
// Field [textfield]: value: "testing! :-)"
// File [filefield] done
// Done parsing form!
```
* Save all incoming files to disk:
```javascript
var http = require('http'),
path = require('path'),
os = require('os'),
fs = require('fs');
```js
const { randomFillSync } = require('crypto');
const fs = require('fs');
const http = require('http');
const os = require('os');
const path = require('path');
const busboy = require('busboy');
var Busboy = require('busboy');
const random = (() => {
const buf = Buffer.alloc(16);
return () => randomFillSync(buf).toString('hex');
})();
http.createServer(function(req, res) {
http.createServer((req, res) => {
if (req.method === 'POST') {
var busboy = new Busboy({ headers: req.headers });
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
var saveTo = path.join(os.tmpDir(), path.basename(fieldname));
const bb = busboy({ headers: req.headers });
bb.on('file', (name, file, info) => {
const saveTo = path.join(os.tmpdir(), `busboy-upload-${random()}`);
file.pipe(fs.createWriteStream(saveTo));
});
busboy.on('finish', function() {
bb.on('close', () => {
res.writeHead(200, { 'Connection': 'close' });
res.end("That's all folks!");
res.end(`That's all folks!`);
});
return req.pipe(busboy);
req.pipe(bb);
return;
}
res.writeHead(404);
res.end();
}).listen(8000, function() {
}).listen(8000, () => {
console.log('Listening for requests');
});
```
* Parsing (urlencoded) with default options:
```javascript
var http = require('http'),
inspect = require('util').inspect;
# API
var Busboy = require('busboy');
## Exports
http.createServer(function(req, res) {
if (req.method === 'POST') {
var busboy = new Busboy({ headers: req.headers });
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
console.log('File [' + fieldname + ']: filename: ' + filename);
file.on('data', function(data) {
console.log('File [' + fieldname + '] got ' + data.length + ' bytes');
});
file.on('end', function() {
console.log('File [' + fieldname + '] Finished');
});
});
busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated) {
console.log('Field [' + fieldname + ']: value: ' + inspect(val));
});
busboy.on('finish', function() {
console.log('Done parsing form!');
res.writeHead(303, { Connection: 'close', Location: '/' });
res.end();
});
req.pipe(busboy);
} else if (req.method === 'GET') {
res.writeHead(200, { Connection: 'close' });
res.end('<html><head></head><body>\
<form method="POST">\
<input type="text" name="textfield"><br />\
<select name="selectfield">\
<option value="1">1</option>\
<option value="10">10</option>\
<option value="100">100</option>\
<option value="9001">9001</option>\
</select><br />\
<input type="checkbox" name="checkfield">Node.js rules!<br />\
<input type="submit">\
</form>\
</body></html>');
}
}).listen(8000, function() {
console.log('Listening for requests');
});
`busboy` exports a single function:
// Example output:
//
// Listening for requests
// Field [textfield]: value: 'testing! :-)'
// Field [selectfield]: value: '9001'
// Field [checkfield]: value: 'on'
// Done parsing form!
```
**( _function_ )**(< _object_ >config) - Creates and returns a new _Writable_ form parser stream.
* Valid `config` properties:
API
===
* **headers** - _object_ - These are the HTTP headers of the incoming request, which are used by individual parsers.
_Busboy_ is a _Writable_ stream
* **highWaterMark** - _integer_ - highWaterMark to use for the parser stream. **Default:** node's _stream.Writable_ default.
Busboy (special) events
-----------------------
* **fileHwm** - _integer_ - highWaterMark to use for individual file streams. **Default:** node's _stream.Readable_ default.
* **file**(< _string_ >fieldname, < _ReadableStream_ >stream, < _string_ >filename, < _string_ >transferEncoding, < _string_ >mimeType) - Emitted for each new file form field found. `transferEncoding` contains the 'Content-Transfer-Encoding' value for the file stream. `mimeType` contains the 'Content-Type' value for the file stream.
* Note: if you listen for this event, you should always handle the `stream` no matter if you care about the file contents or not (e.g. you can simply just do `stream.resume();` if you want to discard the contents), otherwise the 'finish' event will never fire on the Busboy instance. However, if you don't care about **any** incoming files, you can simply not listen for the 'file' event at all and any/all files will be automatically and safely discarded (these discarded files do still count towards `files` and `parts` limits).
* If a configured file size limit was reached, `stream` will both have a boolean property `truncated` (best checked at the end of the stream) and emit a 'limit' event to notify you when this happens.
* **defCharset** - _string_ - Default character set to use when one isn't defined. **Default:** `'utf8'`.
* **field**(< _string_ >fieldname, < _string_ >value, < _boolean_ >fieldnameTruncated, < _boolean_ >valueTruncated, < _string_ >transferEncoding, < _string_ >mimeType) - Emitted for each new non-file field found.
* **defParamCharset** - _string_ - For multipart forms, the default character set to use for values of part header parameters (e.g. filename) that are not extended parameters (that contain an explicit charset). **Default:** `'latin1'`.
* **partsLimit**() - Emitted when specified `parts` limit has been reached. No more 'file' or 'field' events will be emitted.
* **preservePath** - _boolean_ - If paths in filenames from file parts in a `'multipart/form-data'` request shall be preserved. **Default:** `false`.
* **filesLimit**() - Emitted when specified `files` limit has been reached. No more 'file' events will be emitted.
* **limits** - _object_ - Various limits on incoming data. Valid properties are:
* **fieldsLimit**() - Emitted when specified `fields` limit has been reached. No more 'field' events will be emitted.
* **fieldNameSize** - _integer_ - Max field name size (in bytes). **Default:** `100`.
* **fieldSize** - _integer_ - Max field value size (in bytes). **Default:** `1048576` (1MB).
Busboy methods
--------------
* **fields** - _integer_ - Max number of non-file fields. **Default:** `Infinity`.
* **(constructor)**(< _object_ >config) - Creates and returns a new Busboy instance.
* **fileSize** - _integer_ - For multipart forms, the max file size (in bytes). **Default:** `Infinity`.
* The constructor takes the following valid `config` settings:
* **files** - _integer_ - For multipart forms, the max number of file fields. **Default:** `Infinity`.
* **headers** - _object_ - These are the HTTP headers of the incoming request, which are used by individual parsers.
* **parts** - _integer_ - For multipart forms, the max number of parts (fields + files). **Default:** `Infinity`.
* **highWaterMark** - _integer_ - highWaterMark to use for this Busboy instance (Default: WritableStream default).
* **headerPairs** - _integer_ - For multipart forms, the max number of header key-value pairs to parse. **Default:** `2000` (same as node's http module).
* **fileHwm** - _integer_ - highWaterMark to use for file streams (Default: ReadableStream default).
This function can throw exceptions if there is something wrong with the values in `config`. For example, if the Content-Type in `headers` is missing entirely, is not a supported type, or is missing the boundary for `'multipart/form-data'` requests.
* **defCharset** - _string_ - Default character set to use when one isn't defined (Default: 'utf8').
## (Special) Parser stream events
* **preservePath** - _boolean_ - If paths in the multipart 'filename' field shall be preserved. (Default: false).
* **file**(< _string_ >name, < _Readable_ >stream, < _object_ >info) - Emitted for each new file found. `name` contains the form field name. `stream` is a _Readable_ stream containing the file's data. No transformations/conversions (e.g. base64 to raw binary) are done on the file's data. `info` contains the following properties:
* **limits** - _object_ - Various limits on incoming data. Valid properties are:
* `filename` - _string_ - If supplied, this contains the file's filename. **WARNING:** You should almost _never_ use this value as-is (especially if you are using `preservePath: true` in your `config`) as it could contain malicious input. You are better off generating your own (safe) filenames, or at the very least using a hash of the filename.
* `encoding` - _string_ - The file's `'Content-Transfer-Encoding'` value.
* `mimeType` - _string_ - The file's `'Content-Type'` value.
* **fieldNameSize** - _integer_ - Max field name size (in bytes) (Default: 100 bytes).
**Note:** If you listen for this event, you should always consume the `stream` whether you care about its contents or not (you can simply do `stream.resume();` if you want to discard/skip the contents), otherwise the `'finish'`/`'close'` event will never fire on the busboy parser stream.
However, if you aren't accepting files, you can either simply not listen for the `'file'` event at all or set `limits.files` to `0`, and any/all files will be automatically skipped (these skipped files will still count towards any configured `limits.files` and `limits.parts` limits though).
* **fieldSize** - _integer_ - Max field value size (in bytes) (Default: 1MB).
**Note:** If a configured `limits.fileSize` limit was reached for a file, `stream` will both have a boolean property `truncated` set to `true` (best checked at the end of the stream) and emit a `'limit'` event to notify you when this happens.
* **fields** - _integer_ - Max number of non-file fields (Default: Infinity).
* **field**(< _string_ >name, < _string_ >value, < _object_ >info) - Emitted for each new non-file field found. `name` contains the form field name. `value` contains the string value of the field. `info` contains the following properties:
* **fileSize** - _integer_ - For multipart forms, the max file size (in bytes) (Default: Infinity).
* `nameTruncated` - _boolean_ - Whether `name` was truncated or not (due to a configured `limits.fieldNameSize` limit)
* **files** - _integer_ - For multipart forms, the max number of file fields (Default: Infinity).
* `valueTruncated` - _boolean_ - Whether `value` was truncated or not (due to a configured `limits.fieldSize` limit)
* **parts** - _integer_ - For multipart forms, the max number of parts (fields + files) (Default: Infinity).
* `encoding` - _string_ - The field's `'Content-Transfer-Encoding'` value.
* **headerPairs** - _integer_ - For multipart forms, the max number of header key=>value pairs to parse **Default:** 2000 (same as node's http).
* `mimeType` - _string_ - The field's `'Content-Type'` value.
* The constructor can throw errors:
* **partsLimit**() - Emitted when the configured `limits.parts` limit has been reached. No more `'file'` or `'field'` events will be emitted.
* **Unsupported content type: $type** - The `Content-Type` isn't one Busboy can parse.
* **filesLimit**() - Emitted when the configured `limits.files` limit has been reached. No more `'file'` events will be emitted.
* **Missing Content-Type** - The provided headers don't include `Content-Type` at all.
* **fieldsLimit**() - Emitted when the configured `limits.fields` limit has been reached. No more `'field'` events will be emitted.

@ -0,0 +1,149 @@
'use strict';
function createMultipartBuffers(boundary, sizes) {
const bufs = [];
for (let i = 0; i < sizes.length; ++i) {
const mb = sizes[i] * 1024 * 1024;
bufs.push(Buffer.from([
`--${boundary}`,
`content-disposition: form-data; name="field${i + 1}"`,
'',
'0'.repeat(mb),
'',
].join('\r\n')));
}
bufs.push(Buffer.from([
`--${boundary}--`,
'',
].join('\r\n')));
return bufs;
}
const boundary = '-----------------------------168072824752491622650073';
const buffers = createMultipartBuffers(boundary, [
10,
10,
10,
20,
50,
]);
const calls = {
partBegin: 0,
headerField: 0,
headerValue: 0,
headerEnd: 0,
headersEnd: 0,
partData: 0,
partEnd: 0,
end: 0,
};
const moduleName = process.argv[2];
switch (moduleName) {
case 'busboy': {
const busboy = require('busboy');
const parser = busboy({
limits: {
fieldSizeLimit: Infinity,
},
headers: {
'content-type': `multipart/form-data; boundary=${boundary}`,
},
});
parser.on('field', (name, val, info) => {
++calls.partBegin;
++calls.partData;
++calls.partEnd;
}).on('close', () => {
++calls.end;
console.timeEnd(moduleName);
});
console.time(moduleName);
for (const buf of buffers)
parser.write(buf);
break;
}
case 'formidable': {
const { MultipartParser } = require('formidable');
const parser = new MultipartParser();
parser.initWithBoundary(boundary);
parser.on('data', ({ name }) => {
++calls[name];
if (name === 'end')
console.timeEnd(moduleName);
});
console.time(moduleName);
for (const buf of buffers)
parser.write(buf);
break;
}
case 'multiparty': {
const { Readable } = require('stream');
const { Form } = require('multiparty');
const form = new Form({
maxFieldsSize: Infinity,
maxFields: Infinity,
maxFilesSize: Infinity,
autoFields: false,
autoFiles: false,
});
const req = new Readable({ read: () => {} });
req.headers = {
'content-type': `multipart/form-data; boundary=${boundary}`,
};
function hijack(name, fn) {
const oldFn = form[name];
form[name] = function() {
fn();
return oldFn.apply(this, arguments);
};
}
hijack('onParseHeaderField', () => {
++calls.headerField;
});
hijack('onParseHeaderValue', () => {
++calls.headerValue;
});
hijack('onParsePartBegin', () => {
++calls.partBegin;
});
hijack('onParsePartData', () => {
++calls.partData;
});
hijack('onParsePartEnd', () => {
++calls.partEnd;
});
form.on('close', () => {
++calls.end;
console.timeEnd(moduleName);
}).on('part', (p) => p.resume());
console.time(moduleName);
form.parse(req);
for (const buf of buffers)
req.push(buf);
req.push(null);
break;
}
default:
if (moduleName === undefined)
console.error('Missing parser module name');
else
console.error(`Invalid parser module name: ${moduleName}`);
process.exit(1);
}

@ -0,0 +1,143 @@
'use strict';
function createMultipartBuffers(boundary, sizes) {
const bufs = [];
for (let i = 0; i < sizes.length; ++i) {
const mb = sizes[i] * 1024 * 1024;
bufs.push(Buffer.from([
`--${boundary}`,
`content-disposition: form-data; name="field${i + 1}"`,
'',
'0'.repeat(mb),
'',
].join('\r\n')));
}
bufs.push(Buffer.from([
`--${boundary}--`,
'',
].join('\r\n')));
return bufs;
}
const boundary = '-----------------------------168072824752491622650073';
const buffers = createMultipartBuffers(boundary, (new Array(100)).fill(1));
const calls = {
partBegin: 0,
headerField: 0,
headerValue: 0,
headerEnd: 0,
headersEnd: 0,
partData: 0,
partEnd: 0,
end: 0,
};
const moduleName = process.argv[2];
switch (moduleName) {
case 'busboy': {
const busboy = require('busboy');
const parser = busboy({
limits: {
fieldSizeLimit: Infinity,
},
headers: {
'content-type': `multipart/form-data; boundary=${boundary}`,
},
});
parser.on('field', (name, val, info) => {
++calls.partBegin;
++calls.partData;
++calls.partEnd;
}).on('close', () => {
++calls.end;
console.timeEnd(moduleName);
});
console.time(moduleName);
for (const buf of buffers)
parser.write(buf);
break;
}
case 'formidable': {
const { MultipartParser } = require('formidable');
const parser = new MultipartParser();
parser.initWithBoundary(boundary);
parser.on('data', ({ name }) => {
++calls[name];
if (name === 'end')
console.timeEnd(moduleName);
});
console.time(moduleName);
for (const buf of buffers)
parser.write(buf);
break;
}
case 'multiparty': {
const { Readable } = require('stream');
const { Form } = require('multiparty');
const form = new Form({
maxFieldsSize: Infinity,
maxFields: Infinity,
maxFilesSize: Infinity,
autoFields: false,
autoFiles: false,
});
const req = new Readable({ read: () => {} });
req.headers = {
'content-type': `multipart/form-data; boundary=${boundary}`,
};
function hijack(name, fn) {
const oldFn = form[name];
form[name] = function() {
fn();
return oldFn.apply(this, arguments);
};
}
hijack('onParseHeaderField', () => {
++calls.headerField;
});
hijack('onParseHeaderValue', () => {
++calls.headerValue;
});
hijack('onParsePartBegin', () => {
++calls.partBegin;
});
hijack('onParsePartData', () => {
++calls.partData;
});
hijack('onParsePartEnd', () => {
++calls.partEnd;
});
form.on('close', () => {
++calls.end;
console.timeEnd(moduleName);
}).on('part', (p) => p.resume());
console.time(moduleName);
form.parse(req);
for (const buf of buffers)
req.push(buf);
req.push(null);
break;
}
default:
if (moduleName === undefined)
console.error('Missing parser module name');
else
console.error(`Invalid parser module name: ${moduleName}`);
process.exit(1);
}

@ -0,0 +1,154 @@
'use strict';
function createMultipartBuffers(boundary, sizes) {
const bufs = [];
for (let i = 0; i < sizes.length; ++i) {
const mb = sizes[i] * 1024 * 1024;
bufs.push(Buffer.from([
`--${boundary}`,
`content-disposition: form-data; name="file${i + 1}"; `
+ `filename="random${i + 1}.bin"`,
'content-type: application/octet-stream',
'',
'0'.repeat(mb),
'',
].join('\r\n')));
}
bufs.push(Buffer.from([
`--${boundary}--`,
'',
].join('\r\n')));
return bufs;
}
const boundary = '-----------------------------168072824752491622650073';
const buffers = createMultipartBuffers(boundary, [
10,
10,
10,
20,
50,
]);
const calls = {
partBegin: 0,
headerField: 0,
headerValue: 0,
headerEnd: 0,
headersEnd: 0,
partData: 0,
partEnd: 0,
end: 0,
};
const moduleName = process.argv[2];
switch (moduleName) {
case 'busboy': {
const busboy = require('busboy');
const parser = busboy({
limits: {
fieldSizeLimit: Infinity,
},
headers: {
'content-type': `multipart/form-data; boundary=${boundary}`,
},
});
parser.on('file', (name, stream, info) => {
++calls.partBegin;
stream.on('data', (chunk) => {
++calls.partData;
}).on('end', () => {
++calls.partEnd;
});
}).on('close', () => {
++calls.end;
console.timeEnd(moduleName);
});
console.time(moduleName);
for (const buf of buffers)
parser.write(buf);
break;
}
case 'formidable': {
const { MultipartParser } = require('formidable');
const parser = new MultipartParser();
parser.initWithBoundary(boundary);
parser.on('data', ({ name }) => {
++calls[name];
if (name === 'end')
console.timeEnd(moduleName);
});
console.time(moduleName);
for (const buf of buffers)
parser.write(buf);
break;
}
case 'multiparty': {
const { Readable } = require('stream');
const { Form } = require('multiparty');
const form = new Form({
maxFieldsSize: Infinity,
maxFields: Infinity,
maxFilesSize: Infinity,
autoFields: false,
autoFiles: false,
});
const req = new Readable({ read: () => {} });
req.headers = {
'content-type': `multipart/form-data; boundary=${boundary}`,
};
function hijack(name, fn) {
const oldFn = form[name];
form[name] = function() {
fn();
return oldFn.apply(this, arguments);
};
}
hijack('onParseHeaderField', () => {
++calls.headerField;
});
hijack('onParseHeaderValue', () => {
++calls.headerValue;
});
hijack('onParsePartBegin', () => {
++calls.partBegin;
});
hijack('onParsePartData', () => {
++calls.partData;
});
hijack('onParsePartEnd', () => {
++calls.partEnd;
});
form.on('close', () => {
++calls.end;
console.timeEnd(moduleName);
}).on('part', (p) => p.resume());
console.time(moduleName);
form.parse(req);
for (const buf of buffers)
req.push(buf);
req.push(null);
break;
}
default:
if (moduleName === undefined)
console.error('Missing parser module name');
else
console.error(`Invalid parser module name: ${moduleName}`);
process.exit(1);
}

@ -0,0 +1,148 @@
'use strict';
function createMultipartBuffers(boundary, sizes) {
const bufs = [];
for (let i = 0; i < sizes.length; ++i) {
const mb = sizes[i] * 1024 * 1024;
bufs.push(Buffer.from([
`--${boundary}`,
`content-disposition: form-data; name="file${i + 1}"; `
+ `filename="random${i + 1}.bin"`,
'content-type: application/octet-stream',
'',
'0'.repeat(mb),
'',
].join('\r\n')));
}
bufs.push(Buffer.from([
`--${boundary}--`,
'',
].join('\r\n')));
return bufs;
}
const boundary = '-----------------------------168072824752491622650073';
const buffers = createMultipartBuffers(boundary, (new Array(100)).fill(1));
const calls = {
partBegin: 0,
headerField: 0,
headerValue: 0,
headerEnd: 0,
headersEnd: 0,
partData: 0,
partEnd: 0,
end: 0,
};
const moduleName = process.argv[2];
switch (moduleName) {
case 'busboy': {
const busboy = require('busboy');
const parser = busboy({
limits: {
fieldSizeLimit: Infinity,
},
headers: {
'content-type': `multipart/form-data; boundary=${boundary}`,
},
});
parser.on('file', (name, stream, info) => {
++calls.partBegin;
stream.on('data', (chunk) => {
++calls.partData;
}).on('end', () => {
++calls.partEnd;
});
}).on('close', () => {
++calls.end;
console.timeEnd(moduleName);
});
console.time(moduleName);
for (const buf of buffers)
parser.write(buf);
break;
}
case 'formidable': {
const { MultipartParser } = require('formidable');
const parser = new MultipartParser();
parser.initWithBoundary(boundary);
parser.on('data', ({ name }) => {
++calls[name];
if (name === 'end')
console.timeEnd(moduleName);
});
console.time(moduleName);
for (const buf of buffers)
parser.write(buf);
break;
}
case 'multiparty': {
const { Readable } = require('stream');
const { Form } = require('multiparty');
const form = new Form({
maxFieldsSize: Infinity,
maxFields: Infinity,
maxFilesSize: Infinity,
autoFields: false,
autoFiles: false,
});
const req = new Readable({ read: () => {} });
req.headers = {
'content-type': `multipart/form-data; boundary=${boundary}`,
};
function hijack(name, fn) {
const oldFn = form[name];
form[name] = function() {
fn();
return oldFn.apply(this, arguments);
};
}
hijack('onParseHeaderField', () => {
++calls.headerField;
});
hijack('onParseHeaderValue', () => {
++calls.headerValue;
});
hijack('onParsePartBegin', () => {
++calls.partBegin;
});
hijack('onParsePartData', () => {
++calls.partData;
});
hijack('onParsePartEnd', () => {
++calls.partEnd;
});
form.on('close', () => {
++calls.end;
console.timeEnd(moduleName);
}).on('part', (p) => p.resume());
console.time(moduleName);
form.parse(req);
for (const buf of buffers)
req.push(buf);
req.push(null);
break;
}
default:
if (moduleName === undefined)
console.error('Missing parser module name');
else
console.error(`Invalid parser module name: ${moduleName}`);
process.exit(1);
}

@ -0,0 +1,101 @@
'use strict';
const buffers = [
Buffer.from(
(new Array(100)).fill('').map((_, i) => `key${i}=value${i}`).join('&')
),
];
const calls = {
field: 0,
end: 0,
};
let n = 3e3;
const moduleName = process.argv[2];
switch (moduleName) {
case 'busboy': {
const busboy = require('busboy');
console.time(moduleName);
(function next() {
const parser = busboy({
limits: {
fieldSizeLimit: Infinity,
},
headers: {
'content-type': 'application/x-www-form-urlencoded; charset=utf-8',
},
});
parser.on('field', (name, val, info) => {
++calls.field;
}).on('close', () => {
++calls.end;
if (--n === 0)
console.timeEnd(moduleName);
else
process.nextTick(next);
});
for (const buf of buffers)
parser.write(buf);
parser.end();
})();
break;
}
case 'formidable': {
const QuerystringParser =
require('formidable/src/parsers/Querystring.js');
console.time(moduleName);
(function next() {
const parser = new QuerystringParser();
parser.on('data', (obj) => {
++calls.field;
}).on('end', () => {
++calls.end;
if (--n === 0)
console.timeEnd(moduleName);
else
process.nextTick(next);
});
for (const buf of buffers)
parser.write(buf);
parser.end();
})();
break;
}
case 'formidable-streaming': {
const QuerystringParser =
require('formidable/src/parsers/StreamingQuerystring.js');
console.time(moduleName);
(function next() {
const parser = new QuerystringParser();
parser.on('data', (obj) => {
++calls.field;
}).on('end', () => {
++calls.end;
if (--n === 0)
console.timeEnd(moduleName);
else
process.nextTick(next);
});
for (const buf of buffers)
parser.write(buf);
parser.end();
})();
break;
}
default:
if (moduleName === undefined)
console.error('Missing parser module name');
else
console.error(`Invalid parser module name: ${moduleName}`);
process.exit(1);
}

@ -0,0 +1,84 @@
'use strict';
const buffers = [
Buffer.from(
(new Array(900)).fill('').map((_, i) => `key${i}=value${i}`).join('&')
),
];
const calls = {
field: 0,
end: 0,
};
const moduleName = process.argv[2];
switch (moduleName) {
case 'busboy': {
const busboy = require('busboy');
console.time(moduleName);
const parser = busboy({
limits: {
fieldSizeLimit: Infinity,
},
headers: {
'content-type': 'application/x-www-form-urlencoded; charset=utf-8',
},
});
parser.on('field', (name, val, info) => {
++calls.field;
}).on('close', () => {
++calls.end;
console.timeEnd(moduleName);
});
for (const buf of buffers)
parser.write(buf);
parser.end();
break;
}
case 'formidable': {
const QuerystringParser =
require('formidable/src/parsers/Querystring.js');
console.time(moduleName);
const parser = new QuerystringParser();
parser.on('data', (obj) => {
++calls.field;
}).on('end', () => {
++calls.end;
console.timeEnd(moduleName);
});
for (const buf of buffers)
parser.write(buf);
parser.end();
break;
}
case 'formidable-streaming': {
const QuerystringParser =
require('formidable/src/parsers/StreamingQuerystring.js');
console.time(moduleName);
const parser = new QuerystringParser();
parser.on('data', (obj) => {
++calls.field;
}).on('end', () => {
++calls.end;
console.timeEnd(moduleName);
});
for (const buf of buffers)
parser.write(buf);
parser.end();
break;
}
default:
if (moduleName === undefined)
console.error('Missing parser module name');
else
console.error(`Invalid parser module name: ${moduleName}`);
process.exit(1);
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

57
node_modules/busboy/lib/index.js generated vendored

@ -0,0 +1,57 @@
'use strict';
const { parseContentType } = require('./utils.js');
function getInstance(cfg) {
const headers = cfg.headers;
const conType = parseContentType(headers['content-type']);
if (!conType)
throw new Error('Malformed content type');
for (const type of TYPES) {
const matched = type.detect(conType);
if (!matched)
continue;
const instanceCfg = {
limits: cfg.limits,
headers,
conType,
highWaterMark: undefined,
fileHwm: undefined,
defCharset: undefined,
defParamCharset: undefined,
preservePath: false,
};
if (cfg.highWaterMark)
instanceCfg.highWaterMark = cfg.highWaterMark;
if (cfg.fileHwm)
instanceCfg.fileHwm = cfg.fileHwm;
instanceCfg.defCharset = cfg.defCharset;
instanceCfg.defParamCharset = cfg.defParamCharset;
instanceCfg.preservePath = cfg.preservePath;
return new type(instanceCfg);
}
throw new Error(`Unsupported content type: ${headers['content-type']}`);
}
// Note: types are explicitly listed here for easier bundling
// See: https://github.com/mscdex/busboy/issues/121
const TYPES = [
require('./types/multipart'),
require('./types/urlencoded'),
].filter(function(typemod) { return typeof typemod.detect === 'function'; });
module.exports = (cfg) => {
if (typeof cfg !== 'object' || cfg === null)
cfg = {};
if (typeof cfg.headers !== 'object'
|| cfg.headers === null
|| typeof cfg.headers['content-type'] !== 'string') {
throw new Error('Missing Content-Type');
}
return getInstance(cfg);
};

89
node_modules/busboy/lib/main.js generated vendored

@ -1,89 +0,0 @@
var fs = require('fs'),
WritableStream = require('stream').Writable
|| require('readable-stream').Writable,
inherits = require('util').inherits;
var parseParams = require('./utils').parseParams;
function Busboy(opts) {
if (!(this instanceof Busboy))
return new Busboy(opts);
if (opts.highWaterMark !== undefined)
WritableStream.call(this, { highWaterMark: opts.highWaterMark });
else
WritableStream.call(this);
this._done = false;
this._parser = undefined;
this._finished = false;
this.opts = opts;
if (opts.headers && typeof opts.headers['content-type'] === 'string')
this.parseHeaders(opts.headers);
else
throw new Error('Missing Content-Type');
}
inherits(Busboy, WritableStream);
Busboy.prototype.emit = function(ev) {
if (ev === 'finish') {
if (!this._done) {
this._parser && this._parser.end();
return;
} else if (this._finished) {
return;
}
this._finished = true;
}
WritableStream.prototype.emit.apply(this, arguments);
};
Busboy.prototype.parseHeaders = function(headers) {
this._parser = undefined;
if (headers['content-type']) {
var parsed = parseParams(headers['content-type']),
matched, type;
for (var i = 0; i < TYPES.length; ++i) {
type = TYPES[i];
if (typeof type.detect === 'function')
matched = type.detect(parsed);
else
matched = type.detect.test(parsed[0]);
if (matched)
break;
}
if (matched) {
var cfg = {
limits: this.opts.limits,
headers: headers,
parsedConType: parsed,
highWaterMark: undefined,
fileHwm: undefined,
defCharset: undefined,
preservePath: false
};
if (this.opts.highWaterMark)
cfg.highWaterMark = this.opts.highWaterMark;
if (this.opts.fileHwm)
cfg.fileHwm = this.opts.fileHwm;
cfg.defCharset = this.opts.defCharset;
cfg.preservePath = this.opts.preservePath;
this._parser = type(this, cfg);
return;
}
}
throw new Error('Unsupported content type: ' + headers['content-type']);
};
Busboy.prototype._write = function(chunk, encoding, cb) {
if (!this._parser)
return cb(new Error('Not ready to parse. Missing Content-Type?'));
this._parser.write(chunk, cb);
};
var TYPES = [
require('./types/multipart'),
require('./types/urlencoded'),
];
module.exports = Busboy;

@ -1,324 +1,653 @@
// TODO:
// * support 1 nested multipart level
// (see second multipart example here:
// http://www.w3.org/TR/html401/interact/forms.html#didx-multipartform-data)
// * support limits.fieldNameSize
// -- this will require modifications to utils.parseParams
var ReadableStream = require('stream').Readable || require('readable-stream'),
inherits = require('util').inherits;
var Dicer = require('dicer');
var parseParams = require('../utils').parseParams,
decodeText = require('../utils').decodeText,
basename = require('../utils').basename;
var RE_BOUNDARY = /^boundary$/i,
RE_FIELD = /^form-data$/i,
RE_CHARSET = /^charset$/i,
RE_FILENAME = /^filename$/i,
RE_NAME = /^name$/i;
Multipart.detect = /^multipart\/form-data/i;
function Multipart(boy, cfg) {
if (!(this instanceof Multipart))
return new Multipart(boy, cfg);
var i,
len,
self = this,
boundary,
limits = cfg.limits,
parsedConType = cfg.parsedConType || [],
defCharset = cfg.defCharset || 'utf8',
preservePath = cfg.preservePath,
fileopts = (typeof cfg.fileHwm === 'number'
? { highWaterMark: cfg.fileHwm }
: {});
for (i = 0, len = parsedConType.length; i < len; ++i) {
if (Array.isArray(parsedConType[i])
&& RE_BOUNDARY.test(parsedConType[i][0])) {
boundary = parsedConType[i][1];
'use strict';
const { Readable, Writable } = require('stream');
const StreamSearch = require('streamsearch');
const {
basename,
convertToUTF8,
getDecoder,
parseContentType,
parseDisposition,
} = require('../utils.js');
const BUF_CRLF = Buffer.from('\r\n');
const BUF_CR = Buffer.from('\r');
const BUF_DASH = Buffer.from('-');
function noop() {}
const MAX_HEADER_PAIRS = 2000; // From node
const MAX_HEADER_SIZE = 16 * 1024; // From node (its default value)
const HPARSER_NAME = 0;
const HPARSER_PRE_OWS = 1;
const HPARSER_VALUE = 2;
class HeaderParser {
constructor(cb) {
this.header = Object.create(null);
this.pairCount = 0;
this.byteCount = 0;
this.state = HPARSER_NAME;
this.name = '';
this.value = '';
this.crlf = 0;
this.cb = cb;
}
reset() {
this.header = Object.create(null);
this.pairCount = 0;
this.byteCount = 0;
this.state = HPARSER_NAME;
this.name = '';
this.value = '';
this.crlf = 0;
}
push(chunk, pos, end) {
let start = pos;
while (pos < end) {
switch (this.state) {
case HPARSER_NAME: {
let done = false;
for (; pos < end; ++pos) {
if (this.byteCount === MAX_HEADER_SIZE)
return -1;
++this.byteCount;
const code = chunk[pos];
if (TOKEN[code] !== 1) {
if (code !== 58/* ':' */)
return -1;
this.name += chunk.latin1Slice(start, pos);
if (this.name.length === 0)
return -1;
++pos;
done = true;
this.state = HPARSER_PRE_OWS;
break;
}
}
if (!done) {
this.name += chunk.latin1Slice(start, pos);
break;
}
// FALLTHROUGH
}
case HPARSER_PRE_OWS: {
// Skip optional whitespace
let done = false;
for (; pos < end; ++pos) {
if (this.byteCount === MAX_HEADER_SIZE)
return -1;
++this.byteCount;
const code = chunk[pos];
if (code !== 32/* ' ' */ && code !== 9/* '\t' */) {
start = pos;
done = true;
this.state = HPARSER_VALUE;
break;
}
}
if (!done)
break;
// FALLTHROUGH
}
case HPARSER_VALUE:
switch (this.crlf) {
case 0: // Nothing yet
for (; pos < end; ++pos) {
if (this.byteCount === MAX_HEADER_SIZE)
return -1;
++this.byteCount;
const code = chunk[pos];
if (FIELD_VCHAR[code] !== 1) {
if (code !== 13/* '\r' */)
return -1;
++this.crlf;
break;
}
}
this.value += chunk.latin1Slice(start, pos++);
break;
case 1: // Received CR
if (this.byteCount === MAX_HEADER_SIZE)
return -1;
++this.byteCount;
if (chunk[pos++] !== 10/* '\n' */)
return -1;
++this.crlf;
break;
case 2: { // Received CR LF
if (this.byteCount === MAX_HEADER_SIZE)
return -1;
++this.byteCount;
const code = chunk[pos];
if (code === 32/* ' ' */ || code === 9/* '\t' */) {
// Folded value
start = pos;
this.crlf = 0;
} else {
if (++this.pairCount < MAX_HEADER_PAIRS) {
this.name = this.name.toLowerCase();
if (this.header[this.name] === undefined)
this.header[this.name] = [this.value];
else
this.header[this.name].push(this.value);
}
if (code === 13/* '\r' */) {
++this.crlf;
++pos;
} else {
// Assume start of next header field name
start = pos;
this.crlf = 0;
this.state = HPARSER_NAME;
this.name = '';
this.value = '';
}
}
break;
}
case 3: { // Received CR LF CR
if (this.byteCount === MAX_HEADER_SIZE)
return -1;
++this.byteCount;
if (chunk[pos++] !== 10/* '\n' */)
return -1;
// End of header
const header = this.header;
this.reset();
this.cb(header);
return pos;
}
}
break;
}
}
function checkFinished() {
if (nends === 0 && finished && !boy._done) {
finished = false;
process.nextTick(function() {
boy._done = true;
boy.emit('finish');
return pos;
}
}
class FileStream extends Readable {
constructor(opts, owner) {
super(opts);
this.truncated = false;
this._readcb = null;
this.once('end', () => {
// We need to make sure that we call any outstanding _writecb() that is
// associated with this file so that processing of the rest of the form
// can continue. This may not happen if the file stream ends right after
// backpressure kicks in, so we force it here.
this._read();
if (--owner._fileEndsLeft === 0 && owner._finalcb) {
const cb = owner._finalcb;
owner._finalcb = null;
// Make sure other 'end' event handlers get a chance to be executed
// before busboy's 'finish' event is emitted
process.nextTick(cb);
}
});
}
_read(n) {
const cb = this._readcb;
if (cb) {
this._readcb = null;
cb();
}
}
}
const ignoreData = {
push: (chunk, pos) => {},
destroy: () => {},
};
function callAndUnsetCb(self, err) {
const cb = self._writecb;
self._writecb = null;
if (err)
self.destroy(err);
else if (cb)
cb();
}
if (typeof boundary !== 'string')
function nullDecoder(val, hint) {
return val;
}
class Multipart extends Writable {
constructor(cfg) {
const streamOpts = {
autoDestroy: true,
emitClose: true,
highWaterMark: (typeof cfg.highWaterMark === 'number'
? cfg.highWaterMark
: undefined),
};
super(streamOpts);
if (!cfg.conType.params || typeof cfg.conType.params.boundary !== 'string')
throw new Error('Multipart: Boundary not found');
var fieldSizeLimit = (limits && typeof limits.fieldSize === 'number'
const boundary = cfg.conType.params.boundary;
const paramDecoder = (typeof cfg.defParamCharset === 'string'
&& cfg.defParamCharset
? getDecoder(cfg.defParamCharset)
: nullDecoder);
const defCharset = (cfg.defCharset || 'utf8');
const preservePath = cfg.preservePath;
const fileOpts = {
autoDestroy: true,
emitClose: true,
highWaterMark: (typeof cfg.fileHwm === 'number'
? cfg.fileHwm
: undefined),
};
const limits = cfg.limits;
const fieldSizeLimit = (limits && typeof limits.fieldSize === 'number'
? limits.fieldSize
: 1 * 1024 * 1024),
fileSizeLimit = (limits && typeof limits.fileSize === 'number'
: 1 * 1024 * 1024);
const fileSizeLimit = (limits && typeof limits.fileSize === 'number'
? limits.fileSize
: Infinity),
filesLimit = (limits && typeof limits.files === 'number'
: Infinity);
const filesLimit = (limits && typeof limits.files === 'number'
? limits.files
: Infinity),
fieldsLimit = (limits && typeof limits.fields === 'number'
: Infinity);
const fieldsLimit = (limits && typeof limits.fields === 'number'
? limits.fields
: Infinity),
partsLimit = (limits && typeof limits.parts === 'number'
: Infinity);
const partsLimit = (limits && typeof limits.parts === 'number'
? limits.parts
: Infinity);
var nfiles = 0,
nfields = 0,
nends = 0,
curFile,
curField,
finished = false;
this._needDrain = false;
this._pause = false;
this._cb = undefined;
this._nparts = 0;
this._boy = boy;
var parserCfg = {
boundary: boundary,
maxHeaderPairs: (limits && limits.headerPairs)
};
if (fileopts.highWaterMark)
parserCfg.partHwm = fileopts.highWaterMark;
if (cfg.highWaterMark)
parserCfg.highWaterMark = cfg.highWaterMark;
this.parser = new Dicer(parserCfg);
this.parser.on('drain', function() {
self._needDrain = false;
if (self._cb && !self._pause) {
var cb = self._cb;
self._cb = undefined;
cb();
let parts = -1; // Account for initial boundary
let fields = 0;
let files = 0;
let skipPart = false;
this._fileEndsLeft = 0;
this._fileStream = undefined;
this._complete = false;
let fileSize = 0;
let field;
let fieldSize = 0;
let partCharset;
let partEncoding;
let partType;
let partName;
let partTruncated = false;
let hitFilesLimit = false;
let hitFieldsLimit = false;
this._hparser = null;
const hparser = new HeaderParser((header) => {
this._hparser = null;
skipPart = false;
partType = 'text/plain';
partCharset = defCharset;
partEncoding = '7bit';
partName = undefined;
partTruncated = false;
let filename;
if (!header['content-disposition']) {
skipPart = true;
return;
}
}).on('part', function onPart(part) {
if (++self._nparts > partsLimit) {
self.parser.removeListener('part', onPart);
self.parser.on('part', skipPart);
boy.hitPartsLimit = true;
boy.emit('partsLimit');
return skipPart(part);
}
// hack because streams2 _always_ doesn't emit 'end' until nextTick, so let
// us emit 'end' early since we know the part has ended if we are already
// seeing the next part
if (curField) {
var field = curField;
field.emit('end');
field.removeAllListeners('end');
}
part.on('header', function(header) {
var contype,
fieldname,
parsed,
charset,
encoding,
filename,
nsize = 0;
if (header['content-type']) {
parsed = parseParams(header['content-type'][0]);
if (parsed[0]) {
contype = parsed[0].toLowerCase();
for (i = 0, len = parsed.length; i < len; ++i) {
if (RE_CHARSET.test(parsed[i][0])) {
charset = parsed[i][1].toLowerCase();
break;
}
}
}
const disp = parseDisposition(header['content-disposition'][0],
paramDecoder);
if (!disp || disp.type !== 'form-data') {
skipPart = true;
return;
}
if (contype === undefined)
contype = 'text/plain';
if (charset === undefined)
charset = defCharset;
if (disp.params) {
if (disp.params.name)
partName = disp.params.name;
if (header['content-disposition']) {
parsed = parseParams(header['content-disposition'][0]);
if (!RE_FIELD.test(parsed[0]))
return skipPart(part);
for (i = 0, len = parsed.length; i < len; ++i) {
if (RE_NAME.test(parsed[i][0])) {
fieldname = decodeText(parsed[i][1], 'binary', 'utf8');
} else if (RE_FILENAME.test(parsed[i][0])) {
filename = decodeText(parsed[i][1], 'binary', 'utf8');
if (!preservePath)
if (disp.params['filename*'])
filename = disp.params['filename*'];
else if (disp.params.filename)
filename = disp.params.filename;
if (filename !== undefined && !preservePath)
filename = basename(filename);
}
if (header['content-type']) {
const conType = parseContentType(header['content-type'][0]);
if (conType) {
partType = `${conType.type}/${conType.subtype}`;
if (conType.params && typeof conType.params.charset === 'string')
partCharset = conType.params.charset.toLowerCase();
}
}
} else
return skipPart(part);
if (header['content-transfer-encoding'])
encoding = header['content-transfer-encoding'][0].toLowerCase();
else
encoding = '7bit';
partEncoding = header['content-transfer-encoding'][0].toLowerCase();
if (partType === 'application/octet-stream' || filename !== undefined) {
// File
var onData,
onEnd;
if (contype === 'application/octet-stream' || filename !== undefined) {
// file/binary field
if (nfiles === filesLimit) {
if (!boy.hitFilesLimit) {
boy.hitFilesLimit = true;
boy.emit('filesLimit');
if (files === filesLimit) {
if (!hitFilesLimit) {
hitFilesLimit = true;
this.emit('filesLimit');
}
return skipPart(part);
skipPart = true;
return;
}
++files;
++nfiles;
if (this.listenerCount('file') === 0) {
skipPart = true;
return;
}
fileSize = 0;
this._fileStream = new FileStream(fileOpts, this);
++this._fileEndsLeft;
this.emit(
'file',
partName,
this._fileStream,
{ filename,
encoding: partEncoding,
mimeType: partType }
);
} else {
// Non-file
if (!boy._events.file) {
self.parser._ignore();
if (fields === fieldsLimit) {
if (!hitFieldsLimit) {
hitFieldsLimit = true;
this.emit('fieldsLimit');
}
skipPart = true;
return;
}
++fields;
++nends;
var file = new FileStream(fileopts);
curFile = file;
file.on('end', function() {
--nends;
checkFinished();
if (self._cb && !self._needDrain) {
var cb = self._cb;
self._cb = undefined;
cb();
if (this.listenerCount('field') === 0) {
skipPart = true;
return;
}
field = [];
fieldSize = 0;
}
});
file._read = function(n) {
if (!self._pause)
let matchPostBoundary = 0;
const ssCb = (isMatch, data, start, end, isDataSafe) => {
retrydata:
while (data) {
if (this._hparser !== null) {
const ret = this._hparser.push(data, start, end);
if (ret === -1) {
this._hparser = null;
hparser.reset();
this.emit('error', new Error('Malformed part header'));
break;
}
start = ret;
}
if (start === end)
break;
if (matchPostBoundary !== 0) {
if (matchPostBoundary === 1) {
switch (data[start]) {
case 45: // '-'
// Try matching '--' after boundary
matchPostBoundary = 2;
++start;
break;
case 13: // '\r'
// Try matching CR LF before header
matchPostBoundary = 3;
++start;
break;
default:
matchPostBoundary = 0;
}
if (start === end)
return;
self._pause = false;
if (self._cb && !self._needDrain) {
var cb = self._cb;
self._cb = undefined;
cb();
}
};
boy.emit('file', fieldname, file, filename, encoding, contype);
onData = function(data) {
if ((nsize += data.length) > fileSizeLimit) {
var extralen = (fileSizeLimit - (nsize - data.length));
if (extralen > 0)
file.push(data.slice(0, extralen));
file.emit('limit');
file.truncated = true;
part.removeAllListeners('data');
} else if (!file.push(data))
self._pause = true;
};
onEnd = function() {
curFile = undefined;
file.push(null);
};
if (matchPostBoundary === 2) {
matchPostBoundary = 0;
if (data[start] === 45/* '-' */) {
// End of multipart data
this._complete = true;
this._bparser = ignoreData;
return;
}
// We saw something other than '-', so put the dash we consumed
// "back"
const writecb = this._writecb;
this._writecb = noop;
ssCb(false, BUF_DASH, 0, 1, false);
this._writecb = writecb;
} else if (matchPostBoundary === 3) {
matchPostBoundary = 0;
if (data[start] === 10/* '\n' */) {
++start;
if (parts >= partsLimit)
break;
// Prepare the header parser
this._hparser = hparser;
if (start === end)
break;
// Process the remaining data as a header
continue retrydata;
} else {
// non-file field
if (nfields === fieldsLimit) {
if (!boy.hitFieldsLimit) {
boy.hitFieldsLimit = true;
boy.emit('fieldsLimit');
}
return skipPart(part);
}
++nfields;
++nends;
var buffer = '',
truncated = false;
curField = part;
onData = function(data) {
if ((nsize += data.length) > fieldSizeLimit) {
var extralen = (fieldSizeLimit - (nsize - data.length));
buffer += data.toString('binary', 0, extralen);
truncated = true;
part.removeAllListeners('data');
} else
buffer += data.toString('binary');
};
// We saw something other than LF, so put the CR we consumed
// "back"
const writecb = this._writecb;
this._writecb = noop;
ssCb(false, BUF_CR, 0, 1, false);
this._writecb = writecb;
}
}
}
onEnd = function() {
curField = undefined;
if (buffer.length)
buffer = decodeText(buffer, 'binary', charset);
boy.emit('field', fieldname, buffer, false, truncated, encoding, contype);
--nends;
checkFinished();
};
if (!skipPart) {
if (this._fileStream) {
let chunk;
const actualLen = Math.min(end - start, fileSizeLimit - fileSize);
if (!isDataSafe) {
chunk = Buffer.allocUnsafe(actualLen);
data.copy(chunk, 0, start, start + actualLen);
} else {
chunk = data.slice(start, start + actualLen);
}
/* As of node@2efe4ab761666 (v0.10.29+/v0.11.14+), busboy had become
broken. Streams2/streams3 is a huge black box of confusion, but
somehow overriding the sync state seems to fix things again (and still
seems to work for previous node versions).
*/
part._readableState.sync = false;
fileSize += chunk.length;
if (fileSize === fileSizeLimit) {
if (chunk.length > 0)
this._fileStream.push(chunk);
this._fileStream.emit('limit');
this._fileStream.truncated = true;
skipPart = true;
} else if (!this._fileStream.push(chunk)) {
if (this._writecb)
this._fileStream._readcb = this._writecb;
this._writecb = null;
}
} else if (field !== undefined) {
let chunk;
const actualLen = Math.min(
end - start,
fieldSizeLimit - fieldSize
);
if (!isDataSafe) {
chunk = Buffer.allocUnsafe(actualLen);
data.copy(chunk, 0, start, start + actualLen);
} else {
chunk = data.slice(start, start + actualLen);
}
part.on('data', onData);
part.on('end', onEnd);
}).on('error', function(err) {
if (curFile)
curFile.emit('error', err);
});
}).on('error', function(err) {
boy.emit('error', err);
}).on('finish', function() {
finished = true;
checkFinished();
});
fieldSize += actualLen;
field.push(chunk);
if (fieldSize === fieldSizeLimit) {
skipPart = true;
partTruncated = true;
}
}
}
Multipart.prototype.write = function(chunk, cb) {
var r;
if ((r = this.parser.write(chunk)) && !this._pause)
cb();
else {
this._needDrain = !r;
this._cb = cb;
break;
}
};
Multipart.prototype.end = function() {
var self = this;
if (this._nparts === 0 && !self._boy._done) {
process.nextTick(function() {
self._boy._done = true;
self._boy.emit('finish');
});
} else if (this.parser.writable)
this.parser.end();
if (isMatch) {
matchPostBoundary = 1;
if (this._fileStream) {
// End the active file stream if the previous part was a file
this._fileStream.push(null);
this._fileStream = null;
} else if (field !== undefined) {
let data;
switch (field.length) {
case 0:
data = '';
break;
case 1:
data = convertToUTF8(field[0], partCharset, 0);
break;
default:
data = convertToUTF8(
Buffer.concat(field, fieldSize),
partCharset,
0
);
}
field = undefined;
fieldSize = 0;
this.emit(
'field',
partName,
data,
{ nameTruncated: false,
valueTruncated: partTruncated,
encoding: partEncoding,
mimeType: partType }
);
}
if (++parts === partsLimit)
this.emit('partsLimit');
}
};
this._bparser = new StreamSearch(`\r\n--${boundary}`, ssCb);
this._writecb = null;
this._finalcb = null;
function skipPart(part) {
part.resume();
// Just in case there is no preamble
this.write(BUF_CRLF);
}
function FileStream(opts) {
if (!(this instanceof FileStream))
return new FileStream(opts);
ReadableStream.call(this, opts);
static detect(conType) {
return (conType.type === 'multipart' && conType.subtype === 'form-data');
}
this.truncated = false;
_write(chunk, enc, cb) {
this._writecb = cb;
this._bparser.push(chunk, 0);
if (this._writecb)
callAndUnsetCb(this);
}
_destroy(err, cb) {
this._hparser = null;
this._bparser = ignoreData;
if (!err)
err = checkEndState(this);
const fileStream = this._fileStream;
if (fileStream) {
this._fileStream = null;
fileStream.destroy(err);
}
cb(err);
}
_final(cb) {
this._bparser.destroy();
if (!this._complete)
return cb(new Error('Unexpected end of form'));
if (this._fileEndsLeft)
this._finalcb = finalcb.bind(null, this, cb);
else
finalcb(this, cb);
}
}
function finalcb(self, cb, err) {
if (err)
return cb(err);
err = checkEndState(self);
cb(err);
}
function checkEndState(self) {
if (self._hparser)
return new Error('Malformed part header');
const fileStream = self._fileStream;
if (fileStream) {
self._fileStream = null;
fileStream.destroy(new Error('Unexpected end of file'));
}
if (!self._complete)
return new Error('Unexpected end of form');
}
inherits(FileStream, ReadableStream);
FileStream.prototype._read = function(n) {};
const TOKEN = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
const FIELD_VCHAR = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
];
module.exports = Multipart;

@ -1,214 +1,350 @@
var Decoder = require('../utils').Decoder,
decodeText = require('../utils').decodeText;
'use strict';
var RE_CHARSET = /^charset$/i;
const { Writable } = require('stream');
UrlEncoded.detect = /^application\/x-www-form-urlencoded/i;
function UrlEncoded(boy, cfg) {
if (!(this instanceof UrlEncoded))
return new UrlEncoded(boy, cfg);
var limits = cfg.limits,
headers = cfg.headers,
parsedConType = cfg.parsedConType;
this.boy = boy;
const { getDecoder } = require('../utils.js');
class URLEncoded extends Writable {
constructor(cfg) {
const streamOpts = {
autoDestroy: true,
emitClose: true,
highWaterMark: (typeof cfg.highWaterMark === 'number'
? cfg.highWaterMark
: undefined),
};
super(streamOpts);
let charset = (cfg.defCharset || 'utf8');
if (cfg.conType.params && typeof cfg.conType.params.charset === 'string')
charset = cfg.conType.params.charset;
this.charset = charset;
const limits = cfg.limits;
this.fieldSizeLimit = (limits && typeof limits.fieldSize === 'number'
? limits.fieldSize
: 1 * 1024 * 1024);
this.fieldNameSizeLimit = (limits && typeof limits.fieldNameSize === 'number'
? limits.fieldNameSize
: 100);
this.fieldsLimit = (limits && typeof limits.fields === 'number'
? limits.fields
: Infinity);
this.fieldNameSizeLimit = (
limits && typeof limits.fieldNameSize === 'number'
? limits.fieldNameSize
: 100
);
var charset;
for (var i = 0, len = parsedConType.length; i < len; ++i) {
if (Array.isArray(parsedConType[i])
&& RE_CHARSET.test(parsedConType[i][0])) {
charset = parsedConType[i][1].toLowerCase();
break;
}
}
if (charset === undefined)
charset = cfg.defCharset || 'utf8';
this.decoder = new Decoder();
this.charset = charset;
this._fields = 0;
this._state = 'key';
this._checkingBytes = true;
this._inKey = true;
this._keyTrunc = false;
this._valTrunc = false;
this._bytesKey = 0;
this._bytesVal = 0;
this._fields = 0;
this._key = '';
this._val = '';
this._keyTrunc = false;
this._valTrunc = false;
this._hitlimit = false;
this._byte = -2;
this._lastPos = 0;
this._encode = 0;
this._decoder = getDecoder(charset);
}
UrlEncoded.prototype.write = function(data, cb) {
if (this._fields === this.fieldsLimit) {
if (!this.boy.hitFieldsLimit) {
this.boy.hitFieldsLimit = true;
this.boy.emit('fieldsLimit');
static detect(conType) {
return (conType.type === 'application'
&& conType.subtype === 'x-www-form-urlencoded');
}
_write(chunk, enc, cb) {
if (this._fields >= this.fieldsLimit)
return cb();
let i = 0;
const len = chunk.length;
this._lastPos = 0;
// Check if we last ended mid-percent-encoded byte
if (this._byte !== -2) {
i = readPctEnc(this, chunk, i, len);
if (i === -1)
return cb(new Error('Malformed urlencoded form'));
if (i >= len)
return cb();
if (this._inKey)
++this._bytesKey;
else
++this._bytesVal;
}
var idxeq, idxamp, i, p = 0, len = data.length;
main:
while (i < len) {
if (this._inKey) {
// Parsing key
while (p < len) {
if (this._state === 'key') {
idxeq = idxamp = undefined;
for (i = p; i < len; ++i) {
if (!this._checkingBytes)
++p;
if (data[i] === 0x3D/*=*/) {
idxeq = i;
break;
} else if (data[i] === 0x26/*&*/) {
idxamp = i;
break;
i = skipKeyBytes(this, chunk, i, len);
while (i < len) {
switch (chunk[i]) {
case 61: // '='
if (this._lastPos < i)
this._key += chunk.latin1Slice(this._lastPos, i);
this._lastPos = ++i;
this._key = this._decoder(this._key, this._encode);
this._encode = 0;
this._inKey = false;
continue main;
case 38: // '&'
if (this._lastPos < i)
this._key += chunk.latin1Slice(this._lastPos, i);
this._lastPos = ++i;
this._key = this._decoder(this._key, this._encode);
this._encode = 0;
if (this._bytesKey > 0) {
this.emit(
'field',
this._key,
'',
{ nameTruncated: this._keyTrunc,
valueTruncated: false,
encoding: this.charset,
mimeType: 'text/plain' }
);
}
this._key = '';
this._val = '';
this._keyTrunc = false;
this._valTrunc = false;
this._bytesKey = 0;
this._bytesVal = 0;
if (++this._fields >= this.fieldsLimit) {
this.emit('fieldsLimit');
return cb();
}
if (this._checkingBytes && this._bytesKey === this.fieldNameSizeLimit) {
this._hitLimit = true;
continue;
case 43: // '+'
if (this._lastPos < i)
this._key += chunk.latin1Slice(this._lastPos, i);
this._key += ' ';
this._lastPos = i + 1;
break;
} else if (this._checkingBytes)
case 37: // '%'
if (this._encode === 0)
this._encode = 1;
if (this._lastPos < i)
this._key += chunk.latin1Slice(this._lastPos, i);
this._lastPos = i + 1;
this._byte = -1;
i = readPctEnc(this, chunk, i + 1, len);
if (i === -1)
return cb(new Error('Malformed urlencoded form'));
if (i >= len)
return cb();
++this._bytesKey;
i = skipKeyBytes(this, chunk, i, len);
continue;
}
++i;
++this._bytesKey;
i = skipKeyBytes(this, chunk, i, len);
}
if (this._lastPos < i)
this._key += chunk.latin1Slice(this._lastPos, i);
} else {
// Parsing value
if (idxeq !== undefined) {
// key with assignment
if (idxeq > p)
this._key += this.decoder.write(data.toString('binary', p, idxeq));
this._state = 'val';
i = skipValBytes(this, chunk, i, len);
this._hitLimit = false;
this._checkingBytes = true;
while (i < len) {
switch (chunk[i]) {
case 38: // '&'
if (this._lastPos < i)
this._val += chunk.latin1Slice(this._lastPos, i);
this._lastPos = ++i;
this._inKey = true;
this._val = this._decoder(this._val, this._encode);
this._encode = 0;
if (this._bytesKey > 0 || this._bytesVal > 0) {
this.emit(
'field',
this._key,
this._val,
{ nameTruncated: this._keyTrunc,
valueTruncated: this._valTrunc,
encoding: this.charset,
mimeType: 'text/plain' }
);
}
this._key = '';
this._val = '';
this._bytesVal = 0;
this._keyTrunc = false;
this._valTrunc = false;
this.decoder.reset();
p = idxeq + 1;
} else if (idxamp !== undefined) {
// key with no assignment
++this._fields;
var key, keyTrunc = this._keyTrunc;
if (idxamp > p)
key = (this._key += this.decoder.write(data.toString('binary', p, idxamp)));
else
key = this._key;
this._hitLimit = false;
this._checkingBytes = true;
this._key = '';
this._bytesKey = 0;
this._keyTrunc = false;
this.decoder.reset();
this._bytesVal = 0;
if (++this._fields >= this.fieldsLimit) {
this.emit('fieldsLimit');
return cb();
}
continue main;
case 43: // '+'
if (this._lastPos < i)
this._val += chunk.latin1Slice(this._lastPos, i);
this._val += ' ';
this._lastPos = i + 1;
break;
case 37: // '%'
if (this._encode === 0)
this._encode = 1;
if (this._lastPos < i)
this._val += chunk.latin1Slice(this._lastPos, i);
this._lastPos = i + 1;
this._byte = -1;
i = readPctEnc(this, chunk, i + 1, len);
if (i === -1)
return cb(new Error('Malformed urlencoded form'));
if (i >= len)
return cb();
++this._bytesVal;
i = skipValBytes(this, chunk, i, len);
continue;
}
++i;
++this._bytesVal;
i = skipValBytes(this, chunk, i, len);
}
if (this._lastPos < i)
this._val += chunk.latin1Slice(this._lastPos, i);
}
}
if (key.length) {
this.boy.emit('field', decodeText(key, 'binary', this.charset),
'',
keyTrunc,
false);
cb();
}
p = idxamp + 1;
if (this._fields === this.fieldsLimit)
return cb();
} else if (this._hitLimit) {
// we may not have hit the actual limit if there are encoded bytes...
if (i > p)
this._key += this.decoder.write(data.toString('binary', p, i));
p = i;
if ((this._bytesKey = this._key.length) === this.fieldNameSizeLimit) {
// yep, we actually did hit the limit
this._checkingBytes = false;
this._keyTrunc = true;
_final(cb) {
if (this._byte !== -2)
return cb(new Error('Malformed urlencoded form'));
if (!this._inKey || this._bytesKey > 0 || this._bytesVal > 0) {
if (this._inKey)
this._key = this._decoder(this._key, this._encode);
else
this._val = this._decoder(this._val, this._encode);
this.emit(
'field',
this._key,
this._val,
{ nameTruncated: this._keyTrunc,
valueTruncated: this._valTrunc,
encoding: this.charset,
mimeType: 'text/plain' }
);
}
cb();
}
}
function readPctEnc(self, chunk, pos, len) {
if (pos >= len)
return len;
if (self._byte === -1) {
// We saw a '%' but no hex characters yet
const hexUpper = HEX_VALUES[chunk[pos++]];
if (hexUpper === -1)
return -1;
if (hexUpper >= 8)
self._encode = 2; // Indicate high bits detected
if (pos < len) {
// Both hex characters are in this chunk
const hexLower = HEX_VALUES[chunk[pos++]];
if (hexLower === -1)
return -1;
if (self._inKey)
self._key += String.fromCharCode((hexUpper << 4) + hexLower);
else
self._val += String.fromCharCode((hexUpper << 4) + hexLower);
self._byte = -2;
self._lastPos = pos;
} else {
if (p < len)
this._key += this.decoder.write(data.toString('binary', p));
p = len;
// Only one hex character was available in this chunk
self._byte = hexUpper;
}
} else {
idxamp = undefined;
for (i = p; i < len; ++i) {
if (!this._checkingBytes)
++p;
if (data[i] === 0x26/*&*/) {
idxamp = i;
break;
// We saw only one hex character so far
const hexLower = HEX_VALUES[chunk[pos++]];
if (hexLower === -1)
return -1;
if (self._inKey)
self._key += String.fromCharCode((self._byte << 4) + hexLower);
else
self._val += String.fromCharCode((self._byte << 4) + hexLower);
self._byte = -2;
self._lastPos = pos;
}
return pos;
}
function skipKeyBytes(self, chunk, pos, len) {
// Skip bytes if we've truncated
if (self._bytesKey > self.fieldNameSizeLimit) {
if (!self._keyTrunc) {
if (self._lastPos < pos)
self._key += chunk.latin1Slice(self._lastPos, pos - 1);
}
if (this._checkingBytes && this._bytesVal === this.fieldSizeLimit) {
this._hitLimit = true;
self._keyTrunc = true;
for (; pos < len; ++pos) {
const code = chunk[pos];
if (code === 61/* '=' */ || code === 38/* '&' */)
break;
++self._bytesKey;
}
else if (this._checkingBytes)
++this._bytesVal;
self._lastPos = pos;
}
if (idxamp !== undefined) {
++this._fields;
if (idxamp > p)
this._val += this.decoder.write(data.toString('binary', p, idxamp));
this.boy.emit('field', decodeText(this._key, 'binary', this.charset),
decodeText(this._val, 'binary', this.charset),
this._keyTrunc,
this._valTrunc);
this._state = 'key';
this._hitLimit = false;
this._checkingBytes = true;
this._key = '';
this._bytesKey = 0;
this._keyTrunc = false;
this.decoder.reset();
p = idxamp + 1;
if (this._fields === this.fieldsLimit)
return cb();
} else if (this._hitLimit) {
// we may not have hit the actual limit if there are encoded bytes...
if (i > p)
this._val += this.decoder.write(data.toString('binary', p, i));
p = i;
if ((this._val === '' && this.fieldSizeLimit === 0)
|| (this._bytesVal = this._val.length) === this.fieldSizeLimit) {
// yep, we actually did hit the limit
this._checkingBytes = false;
this._valTrunc = true;
return pos;
}
} else {
if (p < len)
this._val += this.decoder.write(data.toString('binary', p));
p = len;
function skipValBytes(self, chunk, pos, len) {
// Skip bytes if we've truncated
if (self._bytesVal > self.fieldSizeLimit) {
if (!self._valTrunc) {
if (self._lastPos < pos)
self._val += chunk.latin1Slice(self._lastPos, pos - 1);
}
self._valTrunc = true;
for (; pos < len; ++pos) {
if (chunk[pos] === 38/* '&' */)
break;
++self._bytesVal;
}
self._lastPos = pos;
}
cb();
};
UrlEncoded.prototype.end = function() {
if (this.boy._done)
return;
return pos;
}
if (this._state === 'key' && this._key.length > 0) {
this.boy.emit('field', decodeText(this._key, 'binary', this.charset),
'',
this._keyTrunc,
false);
} else if (this._state === 'val') {
this.boy.emit('field', decodeText(this._key, 'binary', this.charset),
decodeText(this._val, 'binary', this.charset),
this._keyTrunc,
this._valTrunc);
}
this.boy._done = true;
this.boy.emit('finish');
};
/* eslint-disable no-multi-spaces */
const HEX_VALUES = [
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
];
/* eslint-enable no-multi-spaces */
module.exports = UrlEncoded;
module.exports = URLEncoded;

724
node_modules/busboy/lib/utils.js generated vendored

@ -1,186 +1,596 @@
var jsencoding = require('../deps/encoding/encoding');
var RE_ENCODED = /%([a-fA-F0-9]{2})/g;
function encodedReplacer(match, byte) {
return String.fromCharCode(parseInt(byte, 16));
}
function parseParams(str) {
var res = [],
state = 'key',
charset = '',
inquote = false,
escaping = false,
p = 0,
tmp = '';
for (var i = 0, len = str.length; i < len; ++i) {
if (str[i] === '\\' && inquote) {
if (escaping)
'use strict';
function parseContentType(str) {
if (str.length === 0)
return;
const params = Object.create(null);
let i = 0;
// Parse type
for (; i < str.length; ++i) {
const code = str.charCodeAt(i);
if (TOKEN[code] !== 1) {
if (code !== 47/* '/' */ || i === 0)
return;
break;
}
}
// Check for type without subtype
if (i === str.length)
return;
const type = str.slice(0, i).toLowerCase();
// Parse subtype
const subtypeStart = ++i;
for (; i < str.length; ++i) {
const code = str.charCodeAt(i);
if (TOKEN[code] !== 1) {
// Make sure we have a subtype
if (i === subtypeStart)
return;
if (parseContentTypeParams(str, i, params) === undefined)
return;
break;
}
}
// Make sure we have a subtype
if (i === subtypeStart)
return;
const subtype = str.slice(subtypeStart, i).toLowerCase();
return { type, subtype, params };
}
function parseContentTypeParams(str, i, params) {
while (i < str.length) {
// Consume whitespace
for (; i < str.length; ++i) {
const code = str.charCodeAt(i);
if (code !== 32/* ' ' */ && code !== 9/* '\t' */)
break;
}
// Ended on whitespace
if (i === str.length)
break;
// Check for malformed parameter
if (str.charCodeAt(i++) !== 59/* ';' */)
return;
// Consume whitespace
for (; i < str.length; ++i) {
const code = str.charCodeAt(i);
if (code !== 32/* ' ' */ && code !== 9/* '\t' */)
break;
}
// Ended on whitespace (malformed)
if (i === str.length)
return;
let name;
const nameStart = i;
// Parse parameter name
for (; i < str.length; ++i) {
const code = str.charCodeAt(i);
if (TOKEN[code] !== 1) {
if (code !== 61/* '=' */)
return;
break;
}
}
// No value (malformed)
if (i === str.length)
return;
name = str.slice(nameStart, i);
++i; // Skip over '='
// No value (malformed)
if (i === str.length)
return;
let value = '';
let valueStart;
if (str.charCodeAt(i) === 34/* '"' */) {
valueStart = ++i;
let escaping = false;
// Parse quoted value
for (; i < str.length; ++i) {
const code = str.charCodeAt(i);
if (code === 92/* '\\' */) {
if (escaping) {
valueStart = i;
escaping = false;
else {
} else {
value += str.slice(valueStart, i);
escaping = true;
}
continue;
}
} else if (str[i] === '"') {
if (!escaping) {
if (inquote) {
inquote = false;
state = 'key';
} else
inquote = true;
if (code === 34/* '"' */) {
if (escaping) {
valueStart = i;
escaping = false;
continue;
} else
}
value += str.slice(valueStart, i);
break;
}
if (escaping) {
valueStart = i - 1;
escaping = false;
}
// Invalid unescaped quoted character (malformed)
if (QDTEXT[code] !== 1)
return;
}
// No end quote (malformed)
if (i === str.length)
return;
++i; // Skip over double quote
} else {
if (escaping && inquote)
tmp += '\\';
escaping = false;
if ((state === 'charset' || state === 'lang') && str[i] === "'") {
if (state === 'charset') {
state = 'lang';
charset = tmp.substring(1);
} else
state = 'value';
tmp = '';
continue;
} else if (state === 'key'
&& (str[i] === '*' || str[i] === '=')
&& res.length) {
if (str[i] === '*')
state = 'charset';
else
state = 'value';
res[p] = [tmp, undefined];
tmp = '';
continue;
} else if (!inquote && str[i] === ';') {
state = 'key';
if (charset) {
if (tmp.length) {
tmp = decodeText(tmp.replace(RE_ENCODED, encodedReplacer),
'binary',
charset);
}
charset = '';
}
if (res[p] === undefined)
res[p] = tmp;
else
res[p][1] = tmp;
tmp = '';
++p;
continue;
} else if (!inquote && (str[i] === ' ' || str[i] === '\t'))
valueStart = i;
// Parse unquoted value
for (; i < str.length; ++i) {
const code = str.charCodeAt(i);
if (TOKEN[code] !== 1) {
// No value (malformed)
if (i === valueStart)
return;
break;
}
}
value = str.slice(valueStart, i);
}
name = name.toLowerCase();
if (params[name] === undefined)
params[name] = value;
}
return params;
}
function parseDisposition(str, defDecoder) {
if (str.length === 0)
return;
const params = Object.create(null);
let i = 0;
for (; i < str.length; ++i) {
const code = str.charCodeAt(i);
if (TOKEN[code] !== 1) {
if (parseDispositionParams(str, i, params, defDecoder) === undefined)
return;
break;
}
}
const type = str.slice(0, i).toLowerCase();
return { type, params };
}
function parseDispositionParams(str, i, params, defDecoder) {
while (i < str.length) {
// Consume whitespace
for (; i < str.length; ++i) {
const code = str.charCodeAt(i);
if (code !== 32/* ' ' */ && code !== 9/* '\t' */)
break;
}
// Ended on whitespace
if (i === str.length)
break;
// Check for malformed parameter
if (str.charCodeAt(i++) !== 59/* ';' */)
return;
// Consume whitespace
for (; i < str.length; ++i) {
const code = str.charCodeAt(i);
if (code !== 32/* ' ' */ && code !== 9/* '\t' */)
break;
}
// Ended on whitespace (malformed)
if (i === str.length)
return;
let name;
const nameStart = i;
// Parse parameter name
for (; i < str.length; ++i) {
const code = str.charCodeAt(i);
if (TOKEN[code] !== 1) {
if (code === 61/* '=' */)
break;
return;
}
}
// No value (malformed)
if (i === str.length)
return;
let value = '';
let valueStart;
let charset;
//~ let lang;
name = str.slice(nameStart, i);
if (name.charCodeAt(name.length - 1) === 42/* '*' */) {
// Extended value
const charsetStart = ++i;
// Parse charset name
for (; i < str.length; ++i) {
const code = str.charCodeAt(i);
if (CHARSET[code] !== 1) {
if (code !== 39/* '\'' */)
return;
break;
}
}
// Incomplete charset (malformed)
if (i === str.length)
return;
charset = str.slice(charsetStart, i);
++i; // Skip over the '\''
//~ const langStart = ++i;
// Parse language name
for (; i < str.length; ++i) {
const code = str.charCodeAt(i);
if (code === 39/* '\'' */)
break;
}
// Incomplete language (malformed)
if (i === str.length)
return;
//~ lang = str.slice(langStart, i);
++i; // Skip over the '\''
// No value (malformed)
if (i === str.length)
return;
valueStart = i;
let encode = 0;
// Parse value
for (; i < str.length; ++i) {
const code = str.charCodeAt(i);
if (EXTENDED_VALUE[code] !== 1) {
if (code === 37/* '%' */) {
let hexUpper;
let hexLower;
if (i + 2 < str.length
&& (hexUpper = HEX_VALUES[str.charCodeAt(i + 1)]) !== -1
&& (hexLower = HEX_VALUES[str.charCodeAt(i + 2)]) !== -1) {
const byteVal = (hexUpper << 4) + hexLower;
value += str.slice(valueStart, i);
value += String.fromCharCode(byteVal);
i += 2;
valueStart = i + 1;
if (byteVal >= 128)
encode = 2;
else if (encode === 0)
encode = 1;
continue;
}
tmp += str[i];
// '%' disallowed in non-percent encoded contexts (malformed)
return;
}
break;
}
if (charset && tmp.length) {
tmp = decodeText(tmp.replace(RE_ENCODED, encodedReplacer),
'binary',
charset);
}
if (res[p] === undefined) {
if (tmp)
res[p] = tmp;
} else
res[p][1] = tmp;
value += str.slice(valueStart, i);
value = convertToUTF8(value, charset, encode);
if (value === undefined)
return;
} else {
// Non-extended value
return res;
};
exports.parseParams = parseParams;
++i; // Skip over '='
// No value (malformed)
if (i === str.length)
return;
function decodeText(text, textEncoding, destEncoding) {
var ret;
if (text && jsencoding.encodingExists(destEncoding)) {
try {
ret = jsencoding.TextDecoder(destEncoding)
.decode(new Buffer(text, textEncoding));
} catch(e) {}
if (str.charCodeAt(i) === 34/* '"' */) {
valueStart = ++i;
let escaping = false;
// Parse quoted value
for (; i < str.length; ++i) {
const code = str.charCodeAt(i);
if (code === 92/* '\\' */) {
if (escaping) {
valueStart = i;
escaping = false;
} else {
value += str.slice(valueStart, i);
escaping = true;
}
return (typeof ret === 'string' ? ret : text);
continue;
}
if (code === 34/* '"' */) {
if (escaping) {
valueStart = i;
escaping = false;
continue;
}
value += str.slice(valueStart, i);
break;
}
if (escaping) {
valueStart = i - 1;
escaping = false;
}
// Invalid unescaped quoted character (malformed)
if (QDTEXT[code] !== 1)
return;
}
exports.decodeText = decodeText;
// No end quote (malformed)
if (i === str.length)
return;
var HEX = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
], RE_PLUS = /\+/g;
function Decoder() {
this.buffer = undefined;
}
Decoder.prototype.write = function(str) {
// Replace '+' with ' ' before decoding
str = str.replace(RE_PLUS, ' ');
var res = '';
var i = 0, p = 0, len = str.length;
for (; i < len; ++i) {
if (this.buffer !== undefined) {
if (!HEX[str.charCodeAt(i)]) {
res += '%' + this.buffer;
this.buffer = undefined;
--i; // retry character
++i; // Skip over double quote
} else {
this.buffer += str[i];
++p;
if (this.buffer.length === 2) {
res += String.fromCharCode(parseInt(this.buffer, 16));
this.buffer = undefined;
valueStart = i;
// Parse unquoted value
for (; i < str.length; ++i) {
const code = str.charCodeAt(i);
if (TOKEN[code] !== 1) {
// No value (malformed)
if (i === valueStart)
return;
break;
}
}
} else if (str[i] === '%') {
if (i > p) {
res += str.substring(p, i);
p = i;
value = str.slice(valueStart, i);
}
this.buffer = '';
++p;
value = defDecoder(value, 2);
if (value === undefined)
return;
}
name = name.toLowerCase();
if (params[name] === undefined)
params[name] = value;
}
if (p < len && this.buffer === undefined)
res += str.substring(p);
return res;
};
Decoder.prototype.reset = function() {
this.buffer = undefined;
return params;
}
function getDecoder(charset) {
let lc;
while (true) {
switch (charset) {
case 'utf-8':
case 'utf8':
return decoders.utf8;
case 'latin1':
case 'ascii': // TODO: Make these a separate, strict decoder?
case 'us-ascii':
case 'iso-8859-1':
case 'iso8859-1':
case 'iso88591':
case 'iso_8859-1':
case 'windows-1252':
case 'iso_8859-1:1987':
case 'cp1252':
case 'x-cp1252':
return decoders.latin1;
case 'utf16le':
case 'utf-16le':
case 'ucs2':
case 'ucs-2':
return decoders.utf16le;
case 'base64':
return decoders.base64;
default:
if (lc === undefined) {
lc = true;
charset = charset.toLowerCase();
continue;
}
return decoders.other.bind(charset);
}
}
}
const decoders = {
utf8: (data, hint) => {
if (data.length === 0)
return '';
if (typeof data === 'string') {
// If `data` never had any percent-encoded bytes or never had any that
// were outside of the ASCII range, then we can safely just return the
// input since UTF-8 is ASCII compatible
if (hint < 2)
return data;
data = Buffer.from(data, 'latin1');
}
return data.utf8Slice(0, data.length);
},
latin1: (data, hint) => {
if (data.length === 0)
return '';
if (typeof data === 'string')
return data;
return data.latin1Slice(0, data.length);
},
utf16le: (data, hint) => {
if (data.length === 0)
return '';
if (typeof data === 'string')
data = Buffer.from(data, 'latin1');
return data.ucs2Slice(0, data.length);
},
base64: (data, hint) => {
if (data.length === 0)
return '';
if (typeof data === 'string')
data = Buffer.from(data, 'latin1');
return data.base64Slice(0, data.length);
},
other: (data, hint) => {
if (data.length === 0)
return '';
if (typeof data === 'string')
data = Buffer.from(data, 'latin1');
try {
const decoder = new TextDecoder(this);
return decoder.decode(data);
} catch {}
},
};
exports.Decoder = Decoder;
var RE_SPLIT_POSIX =
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/,
RE_SPLIT_DEVICE =
/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/,
RE_SPLIT_WINDOWS =
/^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/;
function splitPathPosix(filename) {
return RE_SPLIT_POSIX.exec(filename).slice(1);
}
function splitPathWindows(filename) {
// Separate device+slash from tail
var result = RE_SPLIT_DEVICE.exec(filename),
device = (result[1] || '') + (result[2] || ''),
tail = result[3] || '';
// Split the tail into dir, basename and extension
var result2 = RE_SPLIT_WINDOWS.exec(tail),
dir = result2[1],
basename = result2[2],
ext = result2[3];
return [device, dir, basename, ext];
function convertToUTF8(data, charset, hint) {
const decode = getDecoder(charset);
if (decode)
return decode(data, hint);
}
function basename(path) {
var f = splitPathPosix(path)[2];
if (f === path)
f = splitPathWindows(path)[2];
return f;
if (typeof path !== 'string')
return '';
for (let i = path.length - 1; i >= 0; --i) {
switch (path.charCodeAt(i)) {
case 0x2F: // '/'
case 0x5C: // '\'
path = path.slice(i + 1);
return (path === '..' || path === '.' ? '' : path);
}
}
exports.basename = basename;
return (path === '..' || path === '.' ? '' : path);
}
const TOKEN = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
const QDTEXT = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
];
const CHARSET = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
const EXTENDED_VALUE = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
/* eslint-disable no-multi-spaces */
const HEX_VALUES = [
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
];
/* eslint-enable no-multi-spaces */
module.exports = {
basename,
convertToUTF8,
getDecoder,
parseContentType,
parseDisposition,
};

@ -1,54 +0,0 @@
# isarray
`Array#isArray` for older browsers.
## Usage
```js
var isArray = require('isarray');
console.log(isArray([])); // => true
console.log(isArray({})); // => false
```
## Installation
With [npm](http://npmjs.org) do
```bash
$ npm install isarray
```
Then bundle for the browser with
[browserify](https://github.com/substack/browserify).
With [component](http://component.io) do
```bash
$ component install juliangruber/isarray
```
## License
(MIT)
Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -1,209 +0,0 @@
/**
* Require the given path.
*
* @param {String} path
* @return {Object} exports
* @api public
*/
function require(path, parent, orig) {
var resolved = require.resolve(path);
// lookup failed
if (null == resolved) {
orig = orig || path;
parent = parent || 'root';
var err = new Error('Failed to require "' + orig + '" from "' + parent + '"');
err.path = orig;
err.parent = parent;
err.require = true;
throw err;
}
var module = require.modules[resolved];
// perform real require()
// by invoking the module's
// registered function
if (!module.exports) {
module.exports = {};
module.client = module.component = true;
module.call(this, module.exports, require.relative(resolved), module);
}
return module.exports;
}
/**
* Registered modules.
*/
require.modules = {};
/**
* Registered aliases.
*/
require.aliases = {};
/**
* Resolve `path`.
*
* Lookup:
*
* - PATH/index.js
* - PATH.js
* - PATH
*
* @param {String} path
* @return {String} path or null
* @api private
*/
require.resolve = function(path) {
if (path.charAt(0) === '/') path = path.slice(1);
var index = path + '/index.js';
var paths = [
path,
path + '.js',
path + '.json',
path + '/index.js',
path + '/index.json'
];
for (var i = 0; i < paths.length; i++) {
var path = paths[i];
if (require.modules.hasOwnProperty(path)) return path;
}
if (require.aliases.hasOwnProperty(index)) {
return require.aliases[index];
}
};
/**
* Normalize `path` relative to the current path.
*
* @param {String} curr
* @param {String} path
* @return {String}
* @api private
*/
require.normalize = function(curr, path) {
var segs = [];
if ('.' != path.charAt(0)) return path;
curr = curr.split('/');
path = path.split('/');
for (var i = 0; i < path.length; ++i) {
if ('..' == path[i]) {
curr.pop();
} else if ('.' != path[i] && '' != path[i]) {
segs.push(path[i]);
}
}
return curr.concat(segs).join('/');
};
/**
* Register module at `path` with callback `definition`.
*
* @param {String} path
* @param {Function} definition
* @api private
*/
require.register = function(path, definition) {
require.modules[path] = definition;
};
/**
* Alias a module definition.
*
* @param {String} from
* @param {String} to
* @api private
*/
require.alias = function(from, to) {
if (!require.modules.hasOwnProperty(from)) {
throw new Error('Failed to alias "' + from + '", it does not exist');
}
require.aliases[to] = from;
};
/**
* Return a require function relative to the `parent` path.
*
* @param {String} parent
* @return {Function}
* @api private
*/
require.relative = function(parent) {
var p = require.normalize(parent, '..');
/**
* lastIndexOf helper.
*/
function lastIndexOf(arr, obj) {
var i = arr.length;
while (i--) {
if (arr[i] === obj) return i;
}
return -1;
}
/**
* The relative require() itself.
*/
function localRequire(path) {
var resolved = localRequire.resolve(path);
return require(resolved, parent, path);
}
/**
* Resolve relative to the parent.
*/
localRequire.resolve = function(path) {
var c = path.charAt(0);
if ('/' == c) return path.slice(1);
if ('.' == c) return require.normalize(p, path);
// resolve deps by returning
// the dep in the nearest "deps"
// directory
var segs = parent.split('/');
var i = lastIndexOf(segs, 'deps') + 1;
if (!i) i = 0;
path = segs.slice(0, i + 1).join('/') + '/deps/' + path;
return path;
};
/**
* Check if module is defined at `path`.
*/
localRequire.exists = function(path) {
return require.modules.hasOwnProperty(localRequire.resolve(path));
};
return localRequire;
};
require.register("isarray/index.js", function(exports, require, module){
module.exports = Array.isArray || function (arr) {
return Object.prototype.toString.call(arr) == '[object Array]';
};
});
require.alias("isarray/index.js", "isarray/index.js");

@ -1,19 +0,0 @@
{
"name" : "isarray",
"description" : "Array#isArray for older browsers",
"version" : "0.0.1",
"repository" : "juliangruber/isarray",
"homepage": "https://github.com/juliangruber/isarray",
"main" : "index.js",
"scripts" : [
"index.js"
],
"dependencies" : {},
"keywords": ["browser","isarray","array"],
"author": {
"name": "Julian Gruber",
"email": "mail@juliangruber.com",
"url": "http://juliangruber.com"
},
"license": "MIT"
}

@ -1,3 +0,0 @@
module.exports = Array.isArray || function (arr) {
return Object.prototype.toString.call(arr) == '[object Array]';
};

@ -1,25 +0,0 @@
{
"name" : "isarray",
"description" : "Array#isArray for older browsers",
"version" : "0.0.1",
"repository" : {
"type" : "git",
"url" : "git://github.com/juliangruber/isarray.git"
},
"homepage": "https://github.com/juliangruber/isarray",
"main" : "index.js",
"scripts" : {
"test" : "tap test/*.js"
},
"dependencies" : {},
"devDependencies" : {
"tap" : "*"
},
"keywords": ["browser","isarray","array"],
"author": {
"name": "Julian Gruber",
"email": "mail@juliangruber.com",
"url": "http://juliangruber.com"
},
"license": "MIT"
}

@ -1,5 +0,0 @@
build/
test/
examples/
fs.js
zlib.js

@ -1,15 +0,0 @@
# readable-stream
***Node-core streams for userland***
[![NPM](https://nodei.co/npm/readable-stream.png?downloads=true&downloadRank=true)](https://nodei.co/npm/readable-stream/)
[![NPM](https://nodei.co/npm-dl/readable-stream.png&months=6&height=3)](https://nodei.co/npm/readable-stream/)
This package is a mirror of the Streams2 and Streams3 implementations in Node-core.
If you want to guarantee a stable streams base, regardless of what version of Node you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *"stream"* module in Node-core.
**readable-stream** comes in two major versions, v1.0.x and v1.1.x. The former tracks the Streams2 implementation in Node 0.10, including bug-fixes and minor improvements as they are added. The latter tracks Streams3 as it develops in Node 0.11; we will likely see a v1.2.x branch for Node 0.12.
**readable-stream** uses proper patch-level versioning so if you pin to `"~1.0.0"` youll get the latest Node 0.10 Streams2 implementation, including any fixes and minor non-breaking improvements. The patch-level versions of 1.0.x and 1.1.x should mirror the patch-level versions of Node-core releases. You should prefer the **1.0.x** releases for now and when youre ready to start using Streams3, pin to `"~1.1.0"`

@ -1 +0,0 @@
module.exports = require("./lib/_stream_duplex.js")

@ -1,923 +0,0 @@
diff --git a/lib/_stream_duplex.js b/lib/_stream_duplex.js
index c5a741c..a2e0d8e 100644
--- a/lib/_stream_duplex.js
+++ b/lib/_stream_duplex.js
@@ -26,8 +26,8 @@
module.exports = Duplex;
var util = require('util');
-var Readable = require('_stream_readable');
-var Writable = require('_stream_writable');
+var Readable = require('./_stream_readable');
+var Writable = require('./_stream_writable');
util.inherits(Duplex, Readable);
diff --git a/lib/_stream_passthrough.js b/lib/_stream_passthrough.js
index a5e9864..330c247 100644
--- a/lib/_stream_passthrough.js
+++ b/lib/_stream_passthrough.js
@@ -25,7 +25,7 @@
module.exports = PassThrough;
-var Transform = require('_stream_transform');
+var Transform = require('./_stream_transform');
var util = require('util');
util.inherits(PassThrough, Transform);
diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js
index 0c3fe3e..90a8298 100644
--- a/lib/_stream_readable.js
+++ b/lib/_stream_readable.js
@@ -23,10 +23,34 @@ module.exports = Readable;
Readable.ReadableState = ReadableState;
var EE = require('events').EventEmitter;
+if (!EE.listenerCount) EE.listenerCount = function(emitter, type) {
+ return emitter.listeners(type).length;
+};
+
+if (!global.setImmediate) global.setImmediate = function setImmediate(fn) {
+ return setTimeout(fn, 0);
+};
+if (!global.clearImmediate) global.clearImmediate = function clearImmediate(i) {
+ return clearTimeout(i);
+};
+
var Stream = require('stream');
var util = require('util');
+if (!util.isUndefined) {
+ var utilIs = require('core-util-is');
+ for (var f in utilIs) {
+ util[f] = utilIs[f];
+ }
+}
var StringDecoder;
-var debug = util.debuglog('stream');
+var debug;
+if (util.debuglog)
+ debug = util.debuglog('stream');
+else try {
+ debug = require('debuglog')('stream');
+} catch (er) {
+ debug = function() {};
+}
util.inherits(Readable, Stream);
@@ -380,7 +404,7 @@ function chunkInvalid(state, chunk) {
function onEofChunk(stream, state) {
- if (state.decoder && !state.ended) {
+ if (state.decoder && !state.ended && state.decoder.end) {
var chunk = state.decoder.end();
if (chunk && chunk.length) {
state.buffer.push(chunk);
diff --git a/lib/_stream_transform.js b/lib/_stream_transform.js
index b1f9fcc..b0caf57 100644
--- a/lib/_stream_transform.js
+++ b/lib/_stream_transform.js
@@ -64,8 +64,14 @@
module.exports = Transform;
-var Duplex = require('_stream_duplex');
+var Duplex = require('./_stream_duplex');
var util = require('util');
+if (!util.isUndefined) {
+ var utilIs = require('core-util-is');
+ for (var f in utilIs) {
+ util[f] = utilIs[f];
+ }
+}
util.inherits(Transform, Duplex);
diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js
index ba2e920..f49288b 100644
--- a/lib/_stream_writable.js
+++ b/lib/_stream_writable.js
@@ -27,6 +27,12 @@ module.exports = Writable;
Writable.WritableState = WritableState;
var util = require('util');
+if (!util.isUndefined) {
+ var utilIs = require('core-util-is');
+ for (var f in utilIs) {
+ util[f] = utilIs[f];
+ }
+}
var Stream = require('stream');
util.inherits(Writable, Stream);
@@ -119,7 +125,7 @@ function WritableState(options, stream) {
function Writable(options) {
// Writable ctor is applied to Duplexes, though they're not
// instanceof Writable, they're instanceof Readable.
- if (!(this instanceof Writable) && !(this instanceof Stream.Duplex))
+ if (!(this instanceof Writable) && !(this instanceof require('./_stream_duplex')))
return new Writable(options);
this._writableState = new WritableState(options, this);
diff --git a/test/simple/test-stream-big-push.js b/test/simple/test-stream-big-push.js
index e3787e4..8cd2127 100644
--- a/test/simple/test-stream-big-push.js
+++ b/test/simple/test-stream-big-push.js
@@ -21,7 +21,7 @@
var common = require('../common');
var assert = require('assert');
-var stream = require('stream');
+var stream = require('../../');
var str = 'asdfasdfasdfasdfasdf';
var r = new stream.Readable({
diff --git a/test/simple/test-stream-end-paused.js b/test/simple/test-stream-end-paused.js
index bb73777..d40efc7 100644
--- a/test/simple/test-stream-end-paused.js
+++ b/test/simple/test-stream-end-paused.js
@@ -25,7 +25,7 @@ var gotEnd = false;
// Make sure we don't miss the end event for paused 0-length streams
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
var stream = new Readable();
var calledRead = false;
stream._read = function() {
diff --git a/test/simple/test-stream-pipe-after-end.js b/test/simple/test-stream-pipe-after-end.js
index b46ee90..0be8366 100644
--- a/test/simple/test-stream-pipe-after-end.js
+++ b/test/simple/test-stream-pipe-after-end.js
@@ -22,8 +22,8 @@
var common = require('../common');
var assert = require('assert');
-var Readable = require('_stream_readable');
-var Writable = require('_stream_writable');
+var Readable = require('../../lib/_stream_readable');
+var Writable = require('../../lib/_stream_writable');
var util = require('util');
util.inherits(TestReadable, Readable);
diff --git a/test/simple/test-stream-pipe-cleanup.js b/test/simple/test-stream-pipe-cleanup.js
deleted file mode 100644
index f689358..0000000
--- a/test/simple/test-stream-pipe-cleanup.js
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-// This test asserts that Stream.prototype.pipe does not leave listeners
-// hanging on the source or dest.
-
-var common = require('../common');
-var stream = require('stream');
-var assert = require('assert');
-var util = require('util');
-
-function Writable() {
- this.writable = true;
- this.endCalls = 0;
- stream.Stream.call(this);
-}
-util.inherits(Writable, stream.Stream);
-Writable.prototype.end = function() {
- this.endCalls++;
-};
-
-Writable.prototype.destroy = function() {
- this.endCalls++;
-};
-
-function Readable() {
- this.readable = true;
- stream.Stream.call(this);
-}
-util.inherits(Readable, stream.Stream);
-
-function Duplex() {
- this.readable = true;
- Writable.call(this);
-}
-util.inherits(Duplex, Writable);
-
-var i = 0;
-var limit = 100;
-
-var w = new Writable();
-
-var r;
-
-for (i = 0; i < limit; i++) {
- r = new Readable();
- r.pipe(w);
- r.emit('end');
-}
-assert.equal(0, r.listeners('end').length);
-assert.equal(limit, w.endCalls);
-
-w.endCalls = 0;
-
-for (i = 0; i < limit; i++) {
- r = new Readable();
- r.pipe(w);
- r.emit('close');
-}
-assert.equal(0, r.listeners('close').length);
-assert.equal(limit, w.endCalls);
-
-w.endCalls = 0;
-
-r = new Readable();
-
-for (i = 0; i < limit; i++) {
- w = new Writable();
- r.pipe(w);
- w.emit('close');
-}
-assert.equal(0, w.listeners('close').length);
-
-r = new Readable();
-w = new Writable();
-var d = new Duplex();
-r.pipe(d); // pipeline A
-d.pipe(w); // pipeline B
-assert.equal(r.listeners('end').length, 2); // A.onend, A.cleanup
-assert.equal(r.listeners('close').length, 2); // A.onclose, A.cleanup
-assert.equal(d.listeners('end').length, 2); // B.onend, B.cleanup
-assert.equal(d.listeners('close').length, 3); // A.cleanup, B.onclose, B.cleanup
-assert.equal(w.listeners('end').length, 0);
-assert.equal(w.listeners('close').length, 1); // B.cleanup
-
-r.emit('end');
-assert.equal(d.endCalls, 1);
-assert.equal(w.endCalls, 0);
-assert.equal(r.listeners('end').length, 0);
-assert.equal(r.listeners('close').length, 0);
-assert.equal(d.listeners('end').length, 2); // B.onend, B.cleanup
-assert.equal(d.listeners('close').length, 2); // B.onclose, B.cleanup
-assert.equal(w.listeners('end').length, 0);
-assert.equal(w.listeners('close').length, 1); // B.cleanup
-
-d.emit('end');
-assert.equal(d.endCalls, 1);
-assert.equal(w.endCalls, 1);
-assert.equal(r.listeners('end').length, 0);
-assert.equal(r.listeners('close').length, 0);
-assert.equal(d.listeners('end').length, 0);
-assert.equal(d.listeners('close').length, 0);
-assert.equal(w.listeners('end').length, 0);
-assert.equal(w.listeners('close').length, 0);
diff --git a/test/simple/test-stream-pipe-error-handling.js b/test/simple/test-stream-pipe-error-handling.js
index c5d724b..c7d6b7d 100644
--- a/test/simple/test-stream-pipe-error-handling.js
+++ b/test/simple/test-stream-pipe-error-handling.js
@@ -21,7 +21,7 @@
var common = require('../common');
var assert = require('assert');
-var Stream = require('stream').Stream;
+var Stream = require('../../').Stream;
(function testErrorListenerCatches() {
var source = new Stream();
diff --git a/test/simple/test-stream-pipe-event.js b/test/simple/test-stream-pipe-event.js
index cb9d5fe..56f8d61 100644
--- a/test/simple/test-stream-pipe-event.js
+++ b/test/simple/test-stream-pipe-event.js
@@ -20,7 +20,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common');
-var stream = require('stream');
+var stream = require('../../');
var assert = require('assert');
var util = require('util');
diff --git a/test/simple/test-stream-push-order.js b/test/simple/test-stream-push-order.js
index f2e6ec2..a5c9bf9 100644
--- a/test/simple/test-stream-push-order.js
+++ b/test/simple/test-stream-push-order.js
@@ -20,7 +20,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common.js');
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
var assert = require('assert');
var s = new Readable({
diff --git a/test/simple/test-stream-push-strings.js b/test/simple/test-stream-push-strings.js
index 06f43dc..1701a9a 100644
--- a/test/simple/test-stream-push-strings.js
+++ b/test/simple/test-stream-push-strings.js
@@ -22,7 +22,7 @@
var common = require('../common');
var assert = require('assert');
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
var util = require('util');
util.inherits(MyStream, Readable);
diff --git a/test/simple/test-stream-readable-event.js b/test/simple/test-stream-readable-event.js
index ba6a577..a8e6f7b 100644
--- a/test/simple/test-stream-readable-event.js
+++ b/test/simple/test-stream-readable-event.js
@@ -22,7 +22,7 @@
var common = require('../common');
var assert = require('assert');
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
(function first() {
// First test, not reading when the readable is added.
diff --git a/test/simple/test-stream-readable-flow-recursion.js b/test/simple/test-stream-readable-flow-recursion.js
index 2891ad6..11689ba 100644
--- a/test/simple/test-stream-readable-flow-recursion.js
+++ b/test/simple/test-stream-readable-flow-recursion.js
@@ -27,7 +27,7 @@ var assert = require('assert');
// more data continuously, but without triggering a nextTick
// warning or RangeError.
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
// throw an error if we trigger a nextTick warning.
process.throwDeprecation = true;
diff --git a/test/simple/test-stream-unshift-empty-chunk.js b/test/simple/test-stream-unshift-empty-chunk.js
index 0c96476..7827538 100644
--- a/test/simple/test-stream-unshift-empty-chunk.js
+++ b/test/simple/test-stream-unshift-empty-chunk.js
@@ -24,7 +24,7 @@ var assert = require('assert');
// This test verifies that stream.unshift(Buffer(0)) or
// stream.unshift('') does not set state.reading=false.
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
var r = new Readable();
var nChunks = 10;
diff --git a/test/simple/test-stream-unshift-read-race.js b/test/simple/test-stream-unshift-read-race.js
index 83fd9fa..17c18aa 100644
--- a/test/simple/test-stream-unshift-read-race.js
+++ b/test/simple/test-stream-unshift-read-race.js
@@ -29,7 +29,7 @@ var assert = require('assert');
// 3. push() after the EOF signaling null is an error.
// 4. _read() is not called after pushing the EOF null chunk.
-var stream = require('stream');
+var stream = require('../../');
var hwm = 10;
var r = stream.Readable({ highWaterMark: hwm });
var chunks = 10;
@@ -51,7 +51,14 @@ r._read = function(n) {
function push(fast) {
assert(!pushedNull, 'push() after null push');
- var c = pos >= data.length ? null : data.slice(pos, pos + n);
+ var c;
+ if (pos >= data.length)
+ c = null;
+ else {
+ if (n + pos > data.length)
+ n = data.length - pos;
+ c = data.slice(pos, pos + n);
+ }
pushedNull = c === null;
if (fast) {
pos += n;
diff --git a/test/simple/test-stream-writev.js b/test/simple/test-stream-writev.js
index 5b49e6e..b5321f3 100644
--- a/test/simple/test-stream-writev.js
+++ b/test/simple/test-stream-writev.js
@@ -22,7 +22,7 @@
var common = require('../common');
var assert = require('assert');
-var stream = require('stream');
+var stream = require('../../');
var queue = [];
for (var decode = 0; decode < 2; decode++) {
diff --git a/test/simple/test-stream2-basic.js b/test/simple/test-stream2-basic.js
index 3814bf0..248c1be 100644
--- a/test/simple/test-stream2-basic.js
+++ b/test/simple/test-stream2-basic.js
@@ -21,7 +21,7 @@
var common = require('../common.js');
-var R = require('_stream_readable');
+var R = require('../../lib/_stream_readable');
var assert = require('assert');
var util = require('util');
diff --git a/test/simple/test-stream2-compatibility.js b/test/simple/test-stream2-compatibility.js
index 6cdd4e9..f0fa84b 100644
--- a/test/simple/test-stream2-compatibility.js
+++ b/test/simple/test-stream2-compatibility.js
@@ -21,7 +21,7 @@
var common = require('../common.js');
-var R = require('_stream_readable');
+var R = require('../../lib/_stream_readable');
var assert = require('assert');
var util = require('util');
diff --git a/test/simple/test-stream2-finish-pipe.js b/test/simple/test-stream2-finish-pipe.js
index 39b274f..006a19b 100644
--- a/test/simple/test-stream2-finish-pipe.js
+++ b/test/simple/test-stream2-finish-pipe.js
@@ -20,7 +20,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common.js');
-var stream = require('stream');
+var stream = require('../../');
var Buffer = require('buffer').Buffer;
var r = new stream.Readable();
diff --git a/test/simple/test-stream2-fs.js b/test/simple/test-stream2-fs.js
deleted file mode 100644
index e162406..0000000
--- a/test/simple/test-stream2-fs.js
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-var common = require('../common.js');
-var R = require('_stream_readable');
-var assert = require('assert');
-
-var fs = require('fs');
-var FSReadable = fs.ReadStream;
-
-var path = require('path');
-var file = path.resolve(common.fixturesDir, 'x1024.txt');
-
-var size = fs.statSync(file).size;
-
-var expectLengths = [1024];
-
-var util = require('util');
-var Stream = require('stream');
-
-util.inherits(TestWriter, Stream);
-
-function TestWriter() {
- Stream.apply(this);
- this.buffer = [];
- this.length = 0;
-}
-
-TestWriter.prototype.write = function(c) {
- this.buffer.push(c.toString());
- this.length += c.length;
- return true;
-};
-
-TestWriter.prototype.end = function(c) {
- if (c) this.buffer.push(c.toString());
- this.emit('results', this.buffer);
-}
-
-var r = new FSReadable(file);
-var w = new TestWriter();
-
-w.on('results', function(res) {
- console.error(res, w.length);
- assert.equal(w.length, size);
- var l = 0;
- assert.deepEqual(res.map(function (c) {
- return c.length;
- }), expectLengths);
- console.log('ok');
-});
-
-r.pipe(w);
diff --git a/test/simple/test-stream2-httpclient-response-end.js b/test/simple/test-stream2-httpclient-response-end.js
deleted file mode 100644
index 15cffc2..0000000
--- a/test/simple/test-stream2-httpclient-response-end.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-var common = require('../common.js');
-var assert = require('assert');
-var http = require('http');
-var msg = 'Hello';
-var readable_event = false;
-var end_event = false;
-var server = http.createServer(function(req, res) {
- res.writeHead(200, {'Content-Type': 'text/plain'});
- res.end(msg);
-}).listen(common.PORT, function() {
- http.get({port: common.PORT}, function(res) {
- var data = '';
- res.on('readable', function() {
- console.log('readable event');
- readable_event = true;
- data += res.read();
- });
- res.on('end', function() {
- console.log('end event');
- end_event = true;
- assert.strictEqual(msg, data);
- server.close();
- });
- });
-});
-
-process.on('exit', function() {
- assert(readable_event);
- assert(end_event);
-});
-
diff --git a/test/simple/test-stream2-large-read-stall.js b/test/simple/test-stream2-large-read-stall.js
index 2fbfbca..667985b 100644
--- a/test/simple/test-stream2-large-read-stall.js
+++ b/test/simple/test-stream2-large-read-stall.js
@@ -30,7 +30,7 @@ var PUSHSIZE = 20;
var PUSHCOUNT = 1000;
var HWM = 50;
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
var r = new Readable({
highWaterMark: HWM
});
@@ -39,23 +39,23 @@ var rs = r._readableState;
r._read = push;
r.on('readable', function() {
- console.error('>> readable');
+ //console.error('>> readable');
do {
- console.error(' > read(%d)', READSIZE);
+ //console.error(' > read(%d)', READSIZE);
var ret = r.read(READSIZE);
- console.error(' < %j (%d remain)', ret && ret.length, rs.length);
+ //console.error(' < %j (%d remain)', ret && ret.length, rs.length);
} while (ret && ret.length === READSIZE);
- console.error('<< after read()',
- ret && ret.length,
- rs.needReadable,
- rs.length);
+ //console.error('<< after read()',
+ // ret && ret.length,
+ // rs.needReadable,
+ // rs.length);
});
var endEmitted = false;
r.on('end', function() {
endEmitted = true;
- console.error('end');
+ //console.error('end');
});
var pushes = 0;
@@ -64,11 +64,11 @@ function push() {
return;
if (pushes++ === PUSHCOUNT) {
- console.error(' push(EOF)');
+ //console.error(' push(EOF)');
return r.push(null);
}
- console.error(' push #%d', pushes);
+ //console.error(' push #%d', pushes);
if (r.push(new Buffer(PUSHSIZE)))
setTimeout(push);
}
diff --git a/test/simple/test-stream2-objects.js b/test/simple/test-stream2-objects.js
index 3e6931d..ff47d89 100644
--- a/test/simple/test-stream2-objects.js
+++ b/test/simple/test-stream2-objects.js
@@ -21,8 +21,8 @@
var common = require('../common.js');
-var Readable = require('_stream_readable');
-var Writable = require('_stream_writable');
+var Readable = require('../../lib/_stream_readable');
+var Writable = require('../../lib/_stream_writable');
var assert = require('assert');
// tiny node-tap lookalike.
diff --git a/test/simple/test-stream2-pipe-error-handling.js b/test/simple/test-stream2-pipe-error-handling.js
index cf7531c..e3f3e4e 100644
--- a/test/simple/test-stream2-pipe-error-handling.js
+++ b/test/simple/test-stream2-pipe-error-handling.js
@@ -21,7 +21,7 @@
var common = require('../common');
var assert = require('assert');
-var stream = require('stream');
+var stream = require('../../');
(function testErrorListenerCatches() {
var count = 1000;
diff --git a/test/simple/test-stream2-pipe-error-once-listener.js b/test/simple/test-stream2-pipe-error-once-listener.js
index 5e8e3cb..53b2616 100755
--- a/test/simple/test-stream2-pipe-error-once-listener.js
+++ b/test/simple/test-stream2-pipe-error-once-listener.js
@@ -24,7 +24,7 @@ var common = require('../common.js');
var assert = require('assert');
var util = require('util');
-var stream = require('stream');
+var stream = require('../../');
var Read = function() {
diff --git a/test/simple/test-stream2-push.js b/test/simple/test-stream2-push.js
index b63edc3..eb2b0e9 100644
--- a/test/simple/test-stream2-push.js
+++ b/test/simple/test-stream2-push.js
@@ -20,7 +20,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common.js');
-var stream = require('stream');
+var stream = require('../../');
var Readable = stream.Readable;
var Writable = stream.Writable;
var assert = require('assert');
diff --git a/test/simple/test-stream2-read-sync-stack.js b/test/simple/test-stream2-read-sync-stack.js
index e8a7305..9740a47 100644
--- a/test/simple/test-stream2-read-sync-stack.js
+++ b/test/simple/test-stream2-read-sync-stack.js
@@ -21,7 +21,7 @@
var common = require('../common');
var assert = require('assert');
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
var r = new Readable();
var N = 256 * 1024;
diff --git a/test/simple/test-stream2-readable-empty-buffer-no-eof.js b/test/simple/test-stream2-readable-empty-buffer-no-eof.js
index cd30178..4b1659d 100644
--- a/test/simple/test-stream2-readable-empty-buffer-no-eof.js
+++ b/test/simple/test-stream2-readable-empty-buffer-no-eof.js
@@ -22,10 +22,9 @@
var common = require('../common');
var assert = require('assert');
-var Readable = require('stream').Readable;
+var Readable = require('../../').Readable;
test1();
-test2();
function test1() {
var r = new Readable();
@@ -88,31 +87,3 @@ function test1() {
console.log('ok');
});
}
-
-function test2() {
- var r = new Readable({ encoding: 'base64' });
- var reads = 5;
- r._read = function(n) {
- if (!reads--)
- return r.push(null); // EOF
- else
- return r.push(new Buffer('x'));
- };
-
- var results = [];
- function flow() {
- var chunk;
- while (null !== (chunk = r.read()))
- results.push(chunk + '');
- }
- r.on('readable', flow);
- r.on('end', function() {
- results.push('EOF');
- });
- flow();
-
- process.on('exit', function() {
- assert.deepEqual(results, [ 'eHh4', 'eHg=', 'EOF' ]);
- console.log('ok');
- });
-}
diff --git a/test/simple/test-stream2-readable-from-list.js b/test/simple/test-stream2-readable-from-list.js
index 7c96ffe..04a96f5 100644
--- a/test/simple/test-stream2-readable-from-list.js
+++ b/test/simple/test-stream2-readable-from-list.js
@@ -21,7 +21,7 @@
var assert = require('assert');
var common = require('../common.js');
-var fromList = require('_stream_readable')._fromList;
+var fromList = require('../../lib/_stream_readable')._fromList;
// tiny node-tap lookalike.
var tests = [];
diff --git a/test/simple/test-stream2-readable-legacy-drain.js b/test/simple/test-stream2-readable-legacy-drain.js
index 675da8e..51fd3d5 100644
--- a/test/simple/test-stream2-readable-legacy-drain.js
+++ b/test/simple/test-stream2-readable-legacy-drain.js
@@ -22,7 +22,7 @@
var common = require('../common');
var assert = require('assert');
-var Stream = require('stream');
+var Stream = require('../../');
var Readable = Stream.Readable;
var r = new Readable();
diff --git a/test/simple/test-stream2-readable-non-empty-end.js b/test/simple/test-stream2-readable-non-empty-end.js
index 7314ae7..c971898 100644
--- a/test/simple/test-stream2-readable-non-empty-end.js
+++ b/test/simple/test-stream2-readable-non-empty-end.js
@@ -21,7 +21,7 @@
var assert = require('assert');
var common = require('../common.js');
-var Readable = require('_stream_readable');
+var Readable = require('../../lib/_stream_readable');
var len = 0;
var chunks = new Array(10);
diff --git a/test/simple/test-stream2-readable-wrap-empty.js b/test/simple/test-stream2-readable-wrap-empty.js
index 2e5cf25..fd8a3dc 100644
--- a/test/simple/test-stream2-readable-wrap-empty.js
+++ b/test/simple/test-stream2-readable-wrap-empty.js
@@ -22,7 +22,7 @@
var common = require('../common');
var assert = require('assert');
-var Readable = require('_stream_readable');
+var Readable = require('../../lib/_stream_readable');
var EE = require('events').EventEmitter;
var oldStream = new EE();
diff --git a/test/simple/test-stream2-readable-wrap.js b/test/simple/test-stream2-readable-wrap.js
index 90eea01..6b177f7 100644
--- a/test/simple/test-stream2-readable-wrap.js
+++ b/test/simple/test-stream2-readable-wrap.js
@@ -22,8 +22,8 @@
var common = require('../common');
var assert = require('assert');
-var Readable = require('_stream_readable');
-var Writable = require('_stream_writable');
+var Readable = require('../../lib/_stream_readable');
+var Writable = require('../../lib/_stream_writable');
var EE = require('events').EventEmitter;
var testRuns = 0, completedRuns = 0;
diff --git a/test/simple/test-stream2-set-encoding.js b/test/simple/test-stream2-set-encoding.js
index 5d2c32a..685531b 100644
--- a/test/simple/test-stream2-set-encoding.js
+++ b/test/simple/test-stream2-set-encoding.js
@@ -22,7 +22,7 @@
var common = require('../common.js');
var assert = require('assert');
-var R = require('_stream_readable');
+var R = require('../../lib/_stream_readable');
var util = require('util');
// tiny node-tap lookalike.
diff --git a/test/simple/test-stream2-transform.js b/test/simple/test-stream2-transform.js
index 9c9ddd8..a0cacc6 100644
--- a/test/simple/test-stream2-transform.js
+++ b/test/simple/test-stream2-transform.js
@@ -21,8 +21,8 @@
var assert = require('assert');
var common = require('../common.js');
-var PassThrough = require('_stream_passthrough');
-var Transform = require('_stream_transform');
+var PassThrough = require('../../').PassThrough;
+var Transform = require('../../').Transform;
// tiny node-tap lookalike.
var tests = [];
diff --git a/test/simple/test-stream2-unpipe-drain.js b/test/simple/test-stream2-unpipe-drain.js
index d66dc3c..365b327 100644
--- a/test/simple/test-stream2-unpipe-drain.js
+++ b/test/simple/test-stream2-unpipe-drain.js
@@ -22,7 +22,7 @@
var common = require('../common.js');
var assert = require('assert');
-var stream = require('stream');
+var stream = require('../../');
var crypto = require('crypto');
var util = require('util');
diff --git a/test/simple/test-stream2-unpipe-leak.js b/test/simple/test-stream2-unpipe-leak.js
index 99f8746..17c92ae 100644
--- a/test/simple/test-stream2-unpipe-leak.js
+++ b/test/simple/test-stream2-unpipe-leak.js
@@ -22,7 +22,7 @@
var common = require('../common.js');
var assert = require('assert');
-var stream = require('stream');
+var stream = require('../../');
var chunk = new Buffer('hallo');
diff --git a/test/simple/test-stream2-writable.js b/test/simple/test-stream2-writable.js
index 704100c..209c3a6 100644
--- a/test/simple/test-stream2-writable.js
+++ b/test/simple/test-stream2-writable.js
@@ -20,8 +20,8 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common.js');
-var W = require('_stream_writable');
-var D = require('_stream_duplex');
+var W = require('../../').Writable;
+var D = require('../../').Duplex;
var assert = require('assert');
var util = require('util');
diff --git a/test/simple/test-stream3-pause-then-read.js b/test/simple/test-stream3-pause-then-read.js
index b91bde3..2f72c15 100644
--- a/test/simple/test-stream3-pause-then-read.js
+++ b/test/simple/test-stream3-pause-then-read.js
@@ -22,7 +22,7 @@
var common = require('../common');
var assert = require('assert');
-var stream = require('stream');
+var stream = require('../../');
var Readable = stream.Readable;
var Writable = stream.Writable;

@ -1,89 +0,0 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// a duplex stream is just a stream that is both readable and writable.
// Since JS doesn't have multiple prototypal inheritance, this class
// prototypally inherits from Readable, and then parasitically from
// Writable.
module.exports = Duplex;
/*<replacement>*/
var objectKeys = Object.keys || function (obj) {
var keys = [];
for (var key in obj) keys.push(key);
return keys;
}
/*</replacement>*/
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
var Readable = require('./_stream_readable');
var Writable = require('./_stream_writable');
util.inherits(Duplex, Readable);
forEach(objectKeys(Writable.prototype), function(method) {
if (!Duplex.prototype[method])
Duplex.prototype[method] = Writable.prototype[method];
});
function Duplex(options) {
if (!(this instanceof Duplex))
return new Duplex(options);
Readable.call(this, options);
Writable.call(this, options);
if (options && options.readable === false)
this.readable = false;
if (options && options.writable === false)
this.writable = false;
this.allowHalfOpen = true;
if (options && options.allowHalfOpen === false)
this.allowHalfOpen = false;
this.once('end', onend);
}
// the no-half-open enforcer
function onend() {
// if we allow half-open state, or if the writable side ended,
// then we're ok.
if (this.allowHalfOpen || this._writableState.ended)
return;
// no more data can be written.
// But allow more writes to happen in this tick.
process.nextTick(this.end.bind(this));
}
function forEach (xs, f) {
for (var i = 0, l = xs.length; i < l; i++) {
f(xs[i], i);
}
}

@ -1,46 +0,0 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// a passthrough stream.
// basically just the most minimal sort of Transform stream.
// Every written chunk gets output as-is.
module.exports = PassThrough;
var Transform = require('./_stream_transform');
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
util.inherits(PassThrough, Transform);
function PassThrough(options) {
if (!(this instanceof PassThrough))
return new PassThrough(options);
Transform.call(this, options);
}
PassThrough.prototype._transform = function(chunk, encoding, cb) {
cb(null, chunk);
};

@ -1,951 +0,0 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
module.exports = Readable;
/*<replacement>*/
var isArray = require('isarray');
/*</replacement>*/
/*<replacement>*/
var Buffer = require('buffer').Buffer;
/*</replacement>*/
Readable.ReadableState = ReadableState;
var EE = require('events').EventEmitter;
/*<replacement>*/
if (!EE.listenerCount) EE.listenerCount = function(emitter, type) {
return emitter.listeners(type).length;
};
/*</replacement>*/
var Stream = require('stream');
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
var StringDecoder;
/*<replacement>*/
var debug = require('util');
if (debug && debug.debuglog) {
debug = debug.debuglog('stream');
} else {
debug = function () {};
}
/*</replacement>*/
util.inherits(Readable, Stream);
function ReadableState(options, stream) {
var Duplex = require('./_stream_duplex');
options = options || {};
// the point at which it stops calling _read() to fill the buffer
// Note: 0 is a valid value, means "don't call _read preemptively ever"
var hwm = options.highWaterMark;
var defaultHwm = options.objectMode ? 16 : 16 * 1024;
this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;
// cast to ints.
this.highWaterMark = ~~this.highWaterMark;
this.buffer = [];
this.length = 0;
this.pipes = null;
this.pipesCount = 0;
this.flowing = null;
this.ended = false;
this.endEmitted = false;
this.reading = false;
// a flag to be able to tell if the onwrite cb is called immediately,
// or on a later tick. We set this to true at first, because any
// actions that shouldn't happen until "later" should generally also
// not happen before the first write call.
this.sync = true;
// whenever we return null, then we set a flag to say
// that we're awaiting a 'readable' event emission.
this.needReadable = false;
this.emittedReadable = false;
this.readableListening = false;
// object stream flag. Used to make read(n) ignore n and to
// make all the buffer merging and length checks go away
this.objectMode = !!options.objectMode;
if (stream instanceof Duplex)
this.objectMode = this.objectMode || !!options.readableObjectMode;
// Crypto is kind of old and crusty. Historically, its default string
// encoding is 'binary' so we have to make this configurable.
// Everything else in the universe uses 'utf8', though.
this.defaultEncoding = options.defaultEncoding || 'utf8';
// when piping, we only care about 'readable' events that happen
// after read()ing all the bytes and not getting any pushback.
this.ranOut = false;
// the number of writers that are awaiting a drain event in .pipe()s
this.awaitDrain = 0;
// if true, a maybeReadMore has been scheduled
this.readingMore = false;
this.decoder = null;
this.encoding = null;
if (options.encoding) {
if (!StringDecoder)
StringDecoder = require('string_decoder/').StringDecoder;
this.decoder = new StringDecoder(options.encoding);
this.encoding = options.encoding;
}
}
function Readable(options) {
var Duplex = require('./_stream_duplex');
if (!(this instanceof Readable))
return new Readable(options);
this._readableState = new ReadableState(options, this);
// legacy
this.readable = true;
Stream.call(this);
}
// Manually shove something into the read() buffer.
// This returns true if the highWaterMark has not been hit yet,
// similar to how Writable.write() returns true if you should
// write() some more.
Readable.prototype.push = function(chunk, encoding) {
var state = this._readableState;
if (util.isString(chunk) && !state.objectMode) {
encoding = encoding || state.defaultEncoding;
if (encoding !== state.encoding) {
chunk = new Buffer(chunk, encoding);
encoding = '';
}
}
return readableAddChunk(this, state, chunk, encoding, false);
};
// Unshift should *always* be something directly out of read()
Readable.prototype.unshift = function(chunk) {
var state = this._readableState;
return readableAddChunk(this, state, chunk, '', true);
};
function readableAddChunk(stream, state, chunk, encoding, addToFront) {
var er = chunkInvalid(state, chunk);
if (er) {
stream.emit('error', er);
} else if (util.isNullOrUndefined(chunk)) {
state.reading = false;
if (!state.ended)
onEofChunk(stream, state);
} else if (state.objectMode || chunk && chunk.length > 0) {
if (state.ended && !addToFront) {
var e = new Error('stream.push() after EOF');
stream.emit('error', e);
} else if (state.endEmitted && addToFront) {
var e = new Error('stream.unshift() after end event');
stream.emit('error', e);
} else {
if (state.decoder && !addToFront && !encoding)
chunk = state.decoder.write(chunk);
if (!addToFront)
state.reading = false;
// if we want the data now, just emit it.
if (state.flowing && state.length === 0 && !state.sync) {
stream.emit('data', chunk);
stream.read(0);
} else {
// update the buffer info.
state.length += state.objectMode ? 1 : chunk.length;
if (addToFront)
state.buffer.unshift(chunk);
else
state.buffer.push(chunk);
if (state.needReadable)
emitReadable(stream);
}
maybeReadMore(stream, state);
}
} else if (!addToFront) {
state.reading = false;
}
return needMoreData(state);
}
// if it's past the high water mark, we can push in some more.
// Also, if we have no data yet, we can stand some
// more bytes. This is to work around cases where hwm=0,
// such as the repl. Also, if the push() triggered a
// readable event, and the user called read(largeNumber) such that
// needReadable was set, then we ought to push more, so that another
// 'readable' event will be triggered.
function needMoreData(state) {
return !state.ended &&
(state.needReadable ||
state.length < state.highWaterMark ||
state.length === 0);
}
// backwards compatibility.
Readable.prototype.setEncoding = function(enc) {
if (!StringDecoder)
StringDecoder = require('string_decoder/').StringDecoder;
this._readableState.decoder = new StringDecoder(enc);
this._readableState.encoding = enc;
return this;
};
// Don't raise the hwm > 128MB
var MAX_HWM = 0x800000;
function roundUpToNextPowerOf2(n) {
if (n >= MAX_HWM) {
n = MAX_HWM;
} else {
// Get the next highest power of 2
n--;
for (var p = 1; p < 32; p <<= 1) n |= n >> p;
n++;
}
return n;
}
function howMuchToRead(n, state) {
if (state.length === 0 && state.ended)
return 0;
if (state.objectMode)
return n === 0 ? 0 : 1;
if (isNaN(n) || util.isNull(n)) {
// only flow one buffer at a time
if (state.flowing && state.buffer.length)
return state.buffer[0].length;
else
return state.length;
}
if (n <= 0)
return 0;
// If we're asking for more than the target buffer level,
// then raise the water mark. Bump up to the next highest
// power of 2, to prevent increasing it excessively in tiny
// amounts.
if (n > state.highWaterMark)
state.highWaterMark = roundUpToNextPowerOf2(n);
// don't have that much. return null, unless we've ended.
if (n > state.length) {
if (!state.ended) {
state.needReadable = true;
return 0;
} else
return state.length;
}
return n;
}
// you can override either this method, or the async _read(n) below.
Readable.prototype.read = function(n) {
debug('read', n);
var state = this._readableState;
var nOrig = n;
if (!util.isNumber(n) || n > 0)
state.emittedReadable = false;
// if we're doing read(0) to trigger a readable event, but we
// already have a bunch of data in the buffer, then just trigger
// the 'readable' event and move on.
if (n === 0 &&
state.needReadable &&
(state.length >= state.highWaterMark || state.ended)) {
debug('read: emitReadable', state.length, state.ended);
if (state.length === 0 && state.ended)
endReadable(this);
else
emitReadable(this);
return null;
}
n = howMuchToRead(n, state);
// if we've ended, and we're now clear, then finish it up.
if (n === 0 && state.ended) {
if (state.length === 0)
endReadable(this);
return null;
}
// All the actual chunk generation logic needs to be
// *below* the call to _read. The reason is that in certain
// synthetic stream cases, such as passthrough streams, _read
// may be a completely synchronous operation which may change
// the state of the read buffer, providing enough data when
// before there was *not* enough.
//
// So, the steps are:
// 1. Figure out what the state of things will be after we do
// a read from the buffer.
//
// 2. If that resulting state will trigger a _read, then call _read.
// Note that this may be asynchronous, or synchronous. Yes, it is
// deeply ugly to write APIs this way, but that still doesn't mean
// that the Readable class should behave improperly, as streams are
// designed to be sync/async agnostic.
// Take note if the _read call is sync or async (ie, if the read call
// has returned yet), so that we know whether or not it's safe to emit
// 'readable' etc.
//
// 3. Actually pull the requested chunks out of the buffer and return.
// if we need a readable event, then we need to do some reading.
var doRead = state.needReadable;
debug('need readable', doRead);
// if we currently have less than the highWaterMark, then also read some
if (state.length === 0 || state.length - n < state.highWaterMark) {
doRead = true;
debug('length less than watermark', doRead);
}
// however, if we've ended, then there's no point, and if we're already
// reading, then it's unnecessary.
if (state.ended || state.reading) {
doRead = false;
debug('reading or ended', doRead);
}
if (doRead) {
debug('do read');
state.reading = true;
state.sync = true;
// if the length is currently zero, then we *need* a readable event.
if (state.length === 0)
state.needReadable = true;
// call internal read method
this._read(state.highWaterMark);
state.sync = false;
}
// If _read pushed data synchronously, then `reading` will be false,
// and we need to re-evaluate how much data we can return to the user.
if (doRead && !state.reading)
n = howMuchToRead(nOrig, state);
var ret;
if (n > 0)
ret = fromList(n, state);
else
ret = null;
if (util.isNull(ret)) {
state.needReadable = true;
n = 0;
}
state.length -= n;
// If we have nothing in the buffer, then we want to know
// as soon as we *do* get something into the buffer.
if (state.length === 0 && !state.ended)
state.needReadable = true;
// If we tried to read() past the EOF, then emit end on the next tick.
if (nOrig !== n && state.ended && state.length === 0)
endReadable(this);
if (!util.isNull(ret))
this.emit('data', ret);
return ret;
};
function chunkInvalid(state, chunk) {
var er = null;
if (!util.isBuffer(chunk) &&
!util.isString(chunk) &&
!util.isNullOrUndefined(chunk) &&
!state.objectMode) {
er = new TypeError('Invalid non-string/buffer chunk');
}
return er;
}
function onEofChunk(stream, state) {
if (state.decoder && !state.ended) {
var chunk = state.decoder.end();
if (chunk && chunk.length) {
state.buffer.push(chunk);
state.length += state.objectMode ? 1 : chunk.length;
}
}
state.ended = true;
// emit 'readable' now to make sure it gets picked up.
emitReadable(stream);
}
// Don't emit readable right away in sync mode, because this can trigger
// another read() call => stack overflow. This way, it might trigger
// a nextTick recursion warning, but that's not so bad.
function emitReadable(stream) {
var state = stream._readableState;
state.needReadable = false;
if (!state.emittedReadable) {
debug('emitReadable', state.flowing);
state.emittedReadable = true;
if (state.sync)
process.nextTick(function() {
emitReadable_(stream);
});
else
emitReadable_(stream);
}
}
function emitReadable_(stream) {
debug('emit readable');
stream.emit('readable');
flow(stream);
}
// at this point, the user has presumably seen the 'readable' event,
// and called read() to consume some data. that may have triggered
// in turn another _read(n) call, in which case reading = true if
// it's in progress.
// However, if we're not ended, or reading, and the length < hwm,
// then go ahead and try to read some more preemptively.
function maybeReadMore(stream, state) {
if (!state.readingMore) {
state.readingMore = true;
process.nextTick(function() {
maybeReadMore_(stream, state);
});
}
}
function maybeReadMore_(stream, state) {
var len = state.length;
while (!state.reading && !state.flowing && !state.ended &&
state.length < state.highWaterMark) {
debug('maybeReadMore read 0');
stream.read(0);
if (len === state.length)
// didn't get any data, stop spinning.
break;
else
len = state.length;
}
state.readingMore = false;
}
// abstract method. to be overridden in specific implementation classes.
// call cb(er, data) where data is <= n in length.
// for virtual (non-string, non-buffer) streams, "length" is somewhat
// arbitrary, and perhaps not very meaningful.
Readable.prototype._read = function(n) {
this.emit('error', new Error('not implemented'));
};
Readable.prototype.pipe = function(dest, pipeOpts) {
var src = this;
var state = this._readableState;
switch (state.pipesCount) {
case 0:
state.pipes = dest;
break;
case 1:
state.pipes = [state.pipes, dest];
break;
default:
state.pipes.push(dest);
break;
}
state.pipesCount += 1;
debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
var doEnd = (!pipeOpts || pipeOpts.end !== false) &&
dest !== process.stdout &&
dest !== process.stderr;
var endFn = doEnd ? onend : cleanup;
if (state.endEmitted)
process.nextTick(endFn);
else
src.once('end', endFn);
dest.on('unpipe', onunpipe);
function onunpipe(readable) {
debug('onunpipe');
if (readable === src) {
cleanup();
}
}
function onend() {
debug('onend');
dest.end();
}
// when the dest drains, it reduces the awaitDrain counter
// on the source. This would be more elegant with a .once()
// handler in flow(), but adding and removing repeatedly is
// too slow.
var ondrain = pipeOnDrain(src);
dest.on('drain', ondrain);
function cleanup() {
debug('cleanup');
// cleanup event handlers once the pipe is broken
dest.removeListener('close', onclose);
dest.removeListener('finish', onfinish);
dest.removeListener('drain', ondrain);
dest.removeListener('error', onerror);
dest.removeListener('unpipe', onunpipe);
src.removeListener('end', onend);
src.removeListener('end', cleanup);
src.removeListener('data', ondata);
// if the reader is waiting for a drain event from this
// specific writer, then it would cause it to never start
// flowing again.
// So, if this is awaiting a drain, then we just call it now.
// If we don't know, then assume that we are waiting for one.
if (state.awaitDrain &&
(!dest._writableState || dest._writableState.needDrain))
ondrain();
}
src.on('data', ondata);
function ondata(chunk) {
debug('ondata');
var ret = dest.write(chunk);
if (false === ret) {
debug('false write response, pause',
src._readableState.awaitDrain);
src._readableState.awaitDrain++;
src.pause();
}
}
// if the dest has an error, then stop piping into it.
// however, don't suppress the throwing behavior for this.
function onerror(er) {
debug('onerror', er);
unpipe();
dest.removeListener('error', onerror);
if (EE.listenerCount(dest, 'error') === 0)
dest.emit('error', er);
}
// This is a brutally ugly hack to make sure that our error handler
// is attached before any userland ones. NEVER DO THIS.
if (!dest._events || !dest._events.error)
dest.on('error', onerror);
else if (isArray(dest._events.error))
dest._events.error.unshift(onerror);
else
dest._events.error = [onerror, dest._events.error];
// Both close and finish should trigger unpipe, but only once.
function onclose() {
dest.removeListener('finish', onfinish);
unpipe();
}
dest.once('close', onclose);
function onfinish() {
debug('onfinish');
dest.removeListener('close', onclose);
unpipe();
}
dest.once('finish', onfinish);
function unpipe() {
debug('unpipe');
src.unpipe(dest);
}
// tell the dest that it's being piped to
dest.emit('pipe', src);
// start the flow if it hasn't been started already.
if (!state.flowing) {
debug('pipe resume');
src.resume();
}
return dest;
};
function pipeOnDrain(src) {
return function() {
var state = src._readableState;
debug('pipeOnDrain', state.awaitDrain);
if (state.awaitDrain)
state.awaitDrain--;
if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) {
state.flowing = true;
flow(src);
}
};
}
Readable.prototype.unpipe = function(dest) {
var state = this._readableState;
// if we're not piping anywhere, then do nothing.
if (state.pipesCount === 0)
return this;
// just one destination. most common case.
if (state.pipesCount === 1) {
// passed in one, but it's not the right one.
if (dest && dest !== state.pipes)
return this;
if (!dest)
dest = state.pipes;
// got a match.
state.pipes = null;
state.pipesCount = 0;
state.flowing = false;
if (dest)
dest.emit('unpipe', this);
return this;
}
// slow case. multiple pipe destinations.
if (!dest) {
// remove all.
var dests = state.pipes;
var len = state.pipesCount;
state.pipes = null;
state.pipesCount = 0;
state.flowing = false;
for (var i = 0; i < len; i++)
dests[i].emit('unpipe', this);
return this;
}
// try to find the right one.
var i = indexOf(state.pipes, dest);
if (i === -1)
return this;
state.pipes.splice(i, 1);
state.pipesCount -= 1;
if (state.pipesCount === 1)
state.pipes = state.pipes[0];
dest.emit('unpipe', this);
return this;
};
// set up data events if they are asked for
// Ensure readable listeners eventually get something
Readable.prototype.on = function(ev, fn) {
var res = Stream.prototype.on.call(this, ev, fn);
// If listening to data, and it has not explicitly been paused,
// then call resume to start the flow of data on the next tick.
if (ev === 'data' && false !== this._readableState.flowing) {
this.resume();
}
if (ev === 'readable' && this.readable) {
var state = this._readableState;
if (!state.readableListening) {
state.readableListening = true;
state.emittedReadable = false;
state.needReadable = true;
if (!state.reading) {
var self = this;
process.nextTick(function() {
debug('readable nexttick read 0');
self.read(0);
});
} else if (state.length) {
emitReadable(this, state);
}
}
}
return res;
};
Readable.prototype.addListener = Readable.prototype.on;
// pause() and resume() are remnants of the legacy readable stream API
// If the user uses them, then switch into old mode.
Readable.prototype.resume = function() {
var state = this._readableState;
if (!state.flowing) {
debug('resume');
state.flowing = true;
if (!state.reading) {
debug('resume read 0');
this.read(0);
}
resume(this, state);
}
return this;
};
function resume(stream, state) {
if (!state.resumeScheduled) {
state.resumeScheduled = true;
process.nextTick(function() {
resume_(stream, state);
});
}
}
function resume_(stream, state) {
state.resumeScheduled = false;
stream.emit('resume');
flow(stream);
if (state.flowing && !state.reading)
stream.read(0);
}
Readable.prototype.pause = function() {
debug('call pause flowing=%j', this._readableState.flowing);
if (false !== this._readableState.flowing) {
debug('pause');
this._readableState.flowing = false;
this.emit('pause');
}
return this;
};
function flow(stream) {
var state = stream._readableState;
debug('flow', state.flowing);
if (state.flowing) {
do {
var chunk = stream.read();
} while (null !== chunk && state.flowing);
}
}
// wrap an old-style stream as the async data source.
// This is *not* part of the readable stream interface.
// It is an ugly unfortunate mess of history.
Readable.prototype.wrap = function(stream) {
var state = this._readableState;
var paused = false;
var self = this;
stream.on('end', function() {
debug('wrapped end');
if (state.decoder && !state.ended) {
var chunk = state.decoder.end();
if (chunk && chunk.length)
self.push(chunk);
}
self.push(null);
});
stream.on('data', function(chunk) {
debug('wrapped data');
if (state.decoder)
chunk = state.decoder.write(chunk);
if (!chunk || !state.objectMode && !chunk.length)
return;
var ret = self.push(chunk);
if (!ret) {
paused = true;
stream.pause();
}
});
// proxy all the other methods.
// important when wrapping filters and duplexes.
for (var i in stream) {
if (util.isFunction(stream[i]) && util.isUndefined(this[i])) {
this[i] = function(method) { return function() {
return stream[method].apply(stream, arguments);
}}(i);
}
}
// proxy certain important events.
var events = ['error', 'close', 'destroy', 'pause', 'resume'];
forEach(events, function(ev) {
stream.on(ev, self.emit.bind(self, ev));
});
// when we try to consume some more bytes, simply unpause the
// underlying stream.
self._read = function(n) {
debug('wrapped _read', n);
if (paused) {
paused = false;
stream.resume();
}
};
return self;
};
// exposed for testing purposes only.
Readable._fromList = fromList;
// Pluck off n bytes from an array of buffers.
// Length is the combined lengths of all the buffers in the list.
function fromList(n, state) {
var list = state.buffer;
var length = state.length;
var stringMode = !!state.decoder;
var objectMode = !!state.objectMode;
var ret;
// nothing in the list, definitely empty.
if (list.length === 0)
return null;
if (length === 0)
ret = null;
else if (objectMode)
ret = list.shift();
else if (!n || n >= length) {
// read it all, truncate the array.
if (stringMode)
ret = list.join('');
else
ret = Buffer.concat(list, length);
list.length = 0;
} else {
// read just some of it.
if (n < list[0].length) {
// just take a part of the first list item.
// slice is the same for buffers and strings.
var buf = list[0];
ret = buf.slice(0, n);
list[0] = buf.slice(n);
} else if (n === list[0].length) {
// first list is a perfect match
ret = list.shift();
} else {
// complex case.
// we have enough to cover it, but it spans past the first buffer.
if (stringMode)
ret = '';
else
ret = new Buffer(n);
var c = 0;
for (var i = 0, l = list.length; i < l && c < n; i++) {
var buf = list[0];
var cpy = Math.min(n - c, buf.length);
if (stringMode)
ret += buf.slice(0, cpy);
else
buf.copy(ret, c, 0, cpy);
if (cpy < buf.length)
list[0] = buf.slice(cpy);
else
list.shift();
c += cpy;
}
}
}
return ret;
}
function endReadable(stream) {
var state = stream._readableState;
// If we get here before consuming all the bytes, then that is a
// bug in node. Should never happen.
if (state.length > 0)
throw new Error('endReadable called on non-empty stream');
if (!state.endEmitted) {
state.ended = true;
process.nextTick(function() {
// Check that we didn't get one last unshift.
if (!state.endEmitted && state.length === 0) {
state.endEmitted = true;
stream.readable = false;
stream.emit('end');
}
});
}
}
function forEach (xs, f) {
for (var i = 0, l = xs.length; i < l; i++) {
f(xs[i], i);
}
}
function indexOf (xs, x) {
for (var i = 0, l = xs.length; i < l; i++) {
if (xs[i] === x) return i;
}
return -1;
}

@ -1,209 +0,0 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// a transform stream is a readable/writable stream where you do
// something with the data. Sometimes it's called a "filter",
// but that's not a great name for it, since that implies a thing where
// some bits pass through, and others are simply ignored. (That would
// be a valid example of a transform, of course.)
//
// While the output is causally related to the input, it's not a
// necessarily symmetric or synchronous transformation. For example,
// a zlib stream might take multiple plain-text writes(), and then
// emit a single compressed chunk some time in the future.
//
// Here's how this works:
//
// The Transform stream has all the aspects of the readable and writable
// stream classes. When you write(chunk), that calls _write(chunk,cb)
// internally, and returns false if there's a lot of pending writes
// buffered up. When you call read(), that calls _read(n) until
// there's enough pending readable data buffered up.
//
// In a transform stream, the written data is placed in a buffer. When
// _read(n) is called, it transforms the queued up data, calling the
// buffered _write cb's as it consumes chunks. If consuming a single
// written chunk would result in multiple output chunks, then the first
// outputted bit calls the readcb, and subsequent chunks just go into
// the read buffer, and will cause it to emit 'readable' if necessary.
//
// This way, back-pressure is actually determined by the reading side,
// since _read has to be called to start processing a new chunk. However,
// a pathological inflate type of transform can cause excessive buffering
// here. For example, imagine a stream where every byte of input is
// interpreted as an integer from 0-255, and then results in that many
// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in
// 1kb of data being output. In this case, you could write a very small
// amount of input, and end up with a very large amount of output. In
// such a pathological inflating mechanism, there'd be no way to tell
// the system to stop doing the transform. A single 4MB write could
// cause the system to run out of memory.
//
// However, even in such a pathological case, only a single written chunk
// would be consumed, and then the rest would wait (un-transformed) until
// the results of the previous transformed chunk were consumed.
module.exports = Transform;
var Duplex = require('./_stream_duplex');
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
util.inherits(Transform, Duplex);
function TransformState(options, stream) {
this.afterTransform = function(er, data) {
return afterTransform(stream, er, data);
};
this.needTransform = false;
this.transforming = false;
this.writecb = null;
this.writechunk = null;
}
function afterTransform(stream, er, data) {
var ts = stream._transformState;
ts.transforming = false;
var cb = ts.writecb;
if (!cb)
return stream.emit('error', new Error('no writecb in Transform class'));
ts.writechunk = null;
ts.writecb = null;
if (!util.isNullOrUndefined(data))
stream.push(data);
if (cb)
cb(er);
var rs = stream._readableState;
rs.reading = false;
if (rs.needReadable || rs.length < rs.highWaterMark) {
stream._read(rs.highWaterMark);
}
}
function Transform(options) {
if (!(this instanceof Transform))
return new Transform(options);
Duplex.call(this, options);
this._transformState = new TransformState(options, this);
// when the writable side finishes, then flush out anything remaining.
var stream = this;
// start out asking for a readable event once data is transformed.
this._readableState.needReadable = true;
// we have implemented the _read method, and done the other things
// that Readable wants before the first _read call, so unset the
// sync guard flag.
this._readableState.sync = false;
this.once('prefinish', function() {
if (util.isFunction(this._flush))
this._flush(function(er) {
done(stream, er);
});
else
done(stream);
});
}
Transform.prototype.push = function(chunk, encoding) {
this._transformState.needTransform = false;
return Duplex.prototype.push.call(this, chunk, encoding);
};
// This is the part where you do stuff!
// override this function in implementation classes.
// 'chunk' is an input chunk.
//
// Call `push(newChunk)` to pass along transformed output
// to the readable side. You may call 'push' zero or more times.
//
// Call `cb(err)` when you are done with this chunk. If you pass
// an error, then that'll put the hurt on the whole operation. If you
// never call cb(), then you'll never get another chunk.
Transform.prototype._transform = function(chunk, encoding, cb) {
throw new Error('not implemented');
};
Transform.prototype._write = function(chunk, encoding, cb) {
var ts = this._transformState;
ts.writecb = cb;
ts.writechunk = chunk;
ts.writeencoding = encoding;
if (!ts.transforming) {
var rs = this._readableState;
if (ts.needTransform ||
rs.needReadable ||
rs.length < rs.highWaterMark)
this._read(rs.highWaterMark);
}
};
// Doesn't matter what the args are here.
// _transform does all the work.
// That we got here means that the readable side wants more data.
Transform.prototype._read = function(n) {
var ts = this._transformState;
if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) {
ts.transforming = true;
this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
} else {
// mark that we need a transform, so that any data that comes in
// will get processed, now that we've asked for it.
ts.needTransform = true;
}
};
function done(stream, er) {
if (er)
return stream.emit('error', er);
// if there's nothing in the write buffer, then that means
// that nothing more will ever be provided
var ws = stream._writableState;
var ts = stream._transformState;
if (ws.length)
throw new Error('calling transform done when ws.length != 0');
if (ts.transforming)
throw new Error('calling transform done when still transforming');
return stream.push(null);
}

@ -1,477 +0,0 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// A bit simpler than readable streams.
// Implement an async ._write(chunk, cb), and it'll handle all
// the drain event emission and buffering.
module.exports = Writable;
/*<replacement>*/
var Buffer = require('buffer').Buffer;
/*</replacement>*/
Writable.WritableState = WritableState;
/*<replacement>*/
var util = require('core-util-is');
util.inherits = require('inherits');
/*</replacement>*/
var Stream = require('stream');
util.inherits(Writable, Stream);
function WriteReq(chunk, encoding, cb) {
this.chunk = chunk;
this.encoding = encoding;
this.callback = cb;
}
function WritableState(options, stream) {
var Duplex = require('./_stream_duplex');
options = options || {};
// the point at which write() starts returning false
// Note: 0 is a valid value, means that we always return false if
// the entire buffer is not flushed immediately on write()
var hwm = options.highWaterMark;
var defaultHwm = options.objectMode ? 16 : 16 * 1024;
this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm;
// object stream flag to indicate whether or not this stream
// contains buffers or objects.
this.objectMode = !!options.objectMode;
if (stream instanceof Duplex)
this.objectMode = this.objectMode || !!options.writableObjectMode;
// cast to ints.
this.highWaterMark = ~~this.highWaterMark;
this.needDrain = false;
// at the start of calling end()
this.ending = false;
// when end() has been called, and returned
this.ended = false;
// when 'finish' is emitted
this.finished = false;
// should we decode strings into buffers before passing to _write?
// this is here so that some node-core streams can optimize string
// handling at a lower level.
var noDecode = options.decodeStrings === false;
this.decodeStrings = !noDecode;
// Crypto is kind of old and crusty. Historically, its default string
// encoding is 'binary' so we have to make this configurable.
// Everything else in the universe uses 'utf8', though.
this.defaultEncoding = options.defaultEncoding || 'utf8';
// not an actual buffer we keep track of, but a measurement
// of how much we're waiting to get pushed to some underlying
// socket or file.
this.length = 0;
// a flag to see when we're in the middle of a write.
this.writing = false;
// when true all writes will be buffered until .uncork() call
this.corked = 0;
// a flag to be able to tell if the onwrite cb is called immediately,
// or on a later tick. We set this to true at first, because any
// actions that shouldn't happen until "later" should generally also
// not happen before the first write call.
this.sync = true;
// a flag to know if we're processing previously buffered items, which
// may call the _write() callback in the same tick, so that we don't
// end up in an overlapped onwrite situation.
this.bufferProcessing = false;
// the callback that's passed to _write(chunk,cb)
this.onwrite = function(er) {
onwrite(stream, er);
};
// the callback that the user supplies to write(chunk,encoding,cb)
this.writecb = null;
// the amount that is being written when _write is called.
this.writelen = 0;
this.buffer = [];
// number of pending user-supplied write callbacks
// this must be 0 before 'finish' can be emitted
this.pendingcb = 0;
// emit prefinish if the only thing we're waiting for is _write cbs
// This is relevant for synchronous Transform streams
this.prefinished = false;
// True if the error was already emitted and should not be thrown again
this.errorEmitted = false;
}
function Writable(options) {
var Duplex = require('./_stream_duplex');
// Writable ctor is applied to Duplexes, though they're not
// instanceof Writable, they're instanceof Readable.
if (!(this instanceof Writable) && !(this instanceof Duplex))
return new Writable(options);
this._writableState = new WritableState(options, this);
// legacy.
this.writable = true;
Stream.call(this);
}
// Otherwise people can pipe Writable streams, which is just wrong.
Writable.prototype.pipe = function() {
this.emit('error', new Error('Cannot pipe. Not readable.'));
};
function writeAfterEnd(stream, state, cb) {
var er = new Error('write after end');
// TODO: defer error events consistently everywhere, not just the cb
stream.emit('error', er);
process.nextTick(function() {
cb(er);
});
}
// If we get something that is not a buffer, string, null, or undefined,
// and we're not in objectMode, then that's an error.
// Otherwise stream chunks are all considered to be of length=1, and the
// watermarks determine how many objects to keep in the buffer, rather than
// how many bytes or characters.
function validChunk(stream, state, chunk, cb) {
var valid = true;
if (!util.isBuffer(chunk) &&
!util.isString(chunk) &&
!util.isNullOrUndefined(chunk) &&
!state.objectMode) {
var er = new TypeError('Invalid non-string/buffer chunk');
stream.emit('error', er);
process.nextTick(function() {
cb(er);
});
valid = false;
}
return valid;
}
Writable.prototype.write = function(chunk, encoding, cb) {
var state = this._writableState;
var ret = false;
if (util.isFunction(encoding)) {
cb = encoding;
encoding = null;
}
if (util.isBuffer(chunk))
encoding = 'buffer';
else if (!encoding)
encoding = state.defaultEncoding;
if (!util.isFunction(cb))
cb = function() {};
if (state.ended)
writeAfterEnd(this, state, cb);
else if (validChunk(this, state, chunk, cb)) {
state.pendingcb++;
ret = writeOrBuffer(this, state, chunk, encoding, cb);
}
return ret;
};
Writable.prototype.cork = function() {
var state = this._writableState;
state.corked++;
};
Writable.prototype.uncork = function() {
var state = this._writableState;
if (state.corked) {
state.corked--;
if (!state.writing &&
!state.corked &&
!state.finished &&
!state.bufferProcessing &&
state.buffer.length)
clearBuffer(this, state);
}
};
function decodeChunk(state, chunk, encoding) {
if (!state.objectMode &&
state.decodeStrings !== false &&
util.isString(chunk)) {
chunk = new Buffer(chunk, encoding);
}
return chunk;
}
// if we're already writing something, then just put this
// in the queue, and wait our turn. Otherwise, call _write
// If we return false, then we need a drain event, so set that flag.
function writeOrBuffer(stream, state, chunk, encoding, cb) {
chunk = decodeChunk(state, chunk, encoding);
if (util.isBuffer(chunk))
encoding = 'buffer';
var len = state.objectMode ? 1 : chunk.length;
state.length += len;
var ret = state.length < state.highWaterMark;
// we must ensure that previous needDrain will not be reset to false.
if (!ret)
state.needDrain = true;
if (state.writing || state.corked)
state.buffer.push(new WriteReq(chunk, encoding, cb));
else
doWrite(stream, state, false, len, chunk, encoding, cb);
return ret;
}
function doWrite(stream, state, writev, len, chunk, encoding, cb) {
state.writelen = len;
state.writecb = cb;
state.writing = true;
state.sync = true;
if (writev)
stream._writev(chunk, state.onwrite);
else
stream._write(chunk, encoding, state.onwrite);
state.sync = false;
}
function onwriteError(stream, state, sync, er, cb) {
if (sync)
process.nextTick(function() {
state.pendingcb--;
cb(er);
});
else {
state.pendingcb--;
cb(er);
}
stream._writableState.errorEmitted = true;
stream.emit('error', er);
}
function onwriteStateUpdate(state) {
state.writing = false;
state.writecb = null;
state.length -= state.writelen;
state.writelen = 0;
}
function onwrite(stream, er) {
var state = stream._writableState;
var sync = state.sync;
var cb = state.writecb;
onwriteStateUpdate(state);
if (er)
onwriteError(stream, state, sync, er, cb);
else {
// Check if we're actually ready to finish, but don't emit yet
var finished = needFinish(stream, state);
if (!finished &&
!state.corked &&
!state.bufferProcessing &&
state.buffer.length) {
clearBuffer(stream, state);
}
if (sync) {
process.nextTick(function() {
afterWrite(stream, state, finished, cb);
});
} else {
afterWrite(stream, state, finished, cb);
}
}
}
function afterWrite(stream, state, finished, cb) {
if (!finished)
onwriteDrain(stream, state);
state.pendingcb--;
cb();
finishMaybe(stream, state);
}
// Must force callback to be called on nextTick, so that we don't
// emit 'drain' before the write() consumer gets the 'false' return
// value, and has a chance to attach a 'drain' listener.
function onwriteDrain(stream, state) {
if (state.length === 0 && state.needDrain) {
state.needDrain = false;
stream.emit('drain');
}
}
// if there's something in the buffer waiting, then process it
function clearBuffer(stream, state) {
state.bufferProcessing = true;
if (stream._writev && state.buffer.length > 1) {
// Fast case, write everything using _writev()
var cbs = [];
for (var c = 0; c < state.buffer.length; c++)
cbs.push(state.buffer[c].callback);
// count the one we are adding, as well.
// TODO(isaacs) clean this up
state.pendingcb++;
doWrite(stream, state, true, state.length, state.buffer, '', function(err) {
for (var i = 0; i < cbs.length; i++) {
state.pendingcb--;
cbs[i](err);
}
});
// Clear buffer
state.buffer = [];
} else {
// Slow case, write chunks one-by-one
for (var c = 0; c < state.buffer.length; c++) {
var entry = state.buffer[c];
var chunk = entry.chunk;
var encoding = entry.encoding;
var cb = entry.callback;
var len = state.objectMode ? 1 : chunk.length;
doWrite(stream, state, false, len, chunk, encoding, cb);
// if we didn't call the onwrite immediately, then
// it means that we need to wait until it does.
// also, that means that the chunk and cb are currently
// being processed, so move the buffer counter past them.
if (state.writing) {
c++;
break;
}
}
if (c < state.buffer.length)
state.buffer = state.buffer.slice(c);
else
state.buffer.length = 0;
}
state.bufferProcessing = false;
}
Writable.prototype._write = function(chunk, encoding, cb) {
cb(new Error('not implemented'));
};
Writable.prototype._writev = null;
Writable.prototype.end = function(chunk, encoding, cb) {
var state = this._writableState;
if (util.isFunction(chunk)) {
cb = chunk;
chunk = null;
encoding = null;
} else if (util.isFunction(encoding)) {
cb = encoding;
encoding = null;
}
if (!util.isNullOrUndefined(chunk))
this.write(chunk, encoding);
// .end() fully uncorks
if (state.corked) {
state.corked = 1;
this.uncork();
}
// ignore unnecessary end() calls.
if (!state.ending && !state.finished)
endWritable(this, state, cb);
};
function needFinish(stream, state) {
return (state.ending &&
state.length === 0 &&
!state.finished &&
!state.writing);
}
function prefinish(stream, state) {
if (!state.prefinished) {
state.prefinished = true;
stream.emit('prefinish');
}
}
function finishMaybe(stream, state) {
var need = needFinish(stream, state);
if (need) {
if (state.pendingcb === 0) {
prefinish(stream, state);
state.finished = true;
stream.emit('finish');
} else
prefinish(stream, state);
}
return need;
}
function endWritable(stream, state, cb) {
state.ending = true;
finishMaybe(stream, state);
if (cb) {
if (state.finished)
process.nextTick(cb);
else
stream.once('finish', cb);
}
state.ended = true;
}

@ -1,32 +0,0 @@
{
"name": "readable-stream",
"version": "1.1.14",
"description": "Streams3, a user-land copy of the stream library from Node.js v0.11.x",
"main": "readable.js",
"dependencies": {
"core-util-is": "~1.0.0",
"isarray": "0.0.1",
"string_decoder": "~0.10.x",
"inherits": "~2.0.1"
},
"devDependencies": {
"tap": "~0.2.6"
},
"scripts": {
"test": "tap test/simple/*.js"
},
"repository": {
"type": "git",
"url": "git://github.com/isaacs/readable-stream"
},
"keywords": [
"readable",
"stream",
"pipe"
],
"browser": {
"util": false
},
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
"license": "MIT"
}

@ -1 +0,0 @@
module.exports = require("./lib/_stream_passthrough.js")

@ -1,10 +0,0 @@
exports = module.exports = require('./lib/_stream_readable.js');
exports.Stream = require('stream');
exports.Readable = exports;
exports.Writable = require('./lib/_stream_writable.js');
exports.Duplex = require('./lib/_stream_duplex.js');
exports.Transform = require('./lib/_stream_transform.js');
exports.PassThrough = require('./lib/_stream_passthrough.js');
if (!process.browser && process.env.READABLE_STREAM === 'disable') {
module.exports = require('stream');
}

@ -1 +0,0 @@
module.exports = require("./lib/_stream_transform.js")

@ -1 +0,0 @@
module.exports = require("./lib/_stream_writable.js")

@ -1,20 +0,0 @@
Copyright Joyent, Inc. and other Node contributors.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -1,7 +0,0 @@
**string_decoder.js** (`require('string_decoder')`) from Node.js core
Copyright Joyent, Inc. and other Node contributors. See LICENCE file for details.
Version numbers match the versions found in Node core, e.g. 0.10.24 matches Node 0.10.24, likewise 0.11.10 matches Node 0.11.10. **Prefer the stable version over the unstable.**
The *build/* directory contains a build script that will scrape the source from the [joyent/node](https://github.com/joyent/node) repo given a specific Node version.

@ -1,221 +0,0 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var Buffer = require('buffer').Buffer;
var isBufferEncoding = Buffer.isEncoding
|| function(encoding) {
switch (encoding && encoding.toLowerCase()) {
case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;
default: return false;
}
}
function assertEncoding(encoding) {
if (encoding && !isBufferEncoding(encoding)) {
throw new Error('Unknown encoding: ' + encoding);
}
}
// StringDecoder provides an interface for efficiently splitting a series of
// buffers into a series of JS strings without breaking apart multi-byte
// characters. CESU-8 is handled as part of the UTF-8 encoding.
//
// @TODO Handling all encodings inside a single object makes it very difficult
// to reason about this code, so it should be split up in the future.
// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code
// points as used by CESU-8.
var StringDecoder = exports.StringDecoder = function(encoding) {
this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');
assertEncoding(encoding);
switch (this.encoding) {
case 'utf8':
// CESU-8 represents each of Surrogate Pair by 3-bytes
this.surrogateSize = 3;
break;
case 'ucs2':
case 'utf16le':
// UTF-16 represents each of Surrogate Pair by 2-bytes
this.surrogateSize = 2;
this.detectIncompleteChar = utf16DetectIncompleteChar;
break;
case 'base64':
// Base-64 stores 3 bytes in 4 chars, and pads the remainder.
this.surrogateSize = 3;
this.detectIncompleteChar = base64DetectIncompleteChar;
break;
default:
this.write = passThroughWrite;
return;
}
// Enough space to store all bytes of a single character. UTF-8 needs 4
// bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).
this.charBuffer = new Buffer(6);
// Number of bytes received for the current incomplete multi-byte character.
this.charReceived = 0;
// Number of bytes expected for the current incomplete multi-byte character.
this.charLength = 0;
};
// write decodes the given buffer and returns it as JS string that is
// guaranteed to not contain any partial multi-byte characters. Any partial
// character found at the end of the buffer is buffered up, and will be
// returned when calling write again with the remaining bytes.
//
// Note: Converting a Buffer containing an orphan surrogate to a String
// currently works, but converting a String to a Buffer (via `new Buffer`, or
// Buffer#write) will replace incomplete surrogates with the unicode
// replacement character. See https://codereview.chromium.org/121173009/ .
StringDecoder.prototype.write = function(buffer) {
var charStr = '';
// if our last write ended with an incomplete multibyte character
while (this.charLength) {
// determine how many remaining bytes this buffer has to offer for this char
var available = (buffer.length >= this.charLength - this.charReceived) ?
this.charLength - this.charReceived :
buffer.length;
// add the new bytes to the char buffer
buffer.copy(this.charBuffer, this.charReceived, 0, available);
this.charReceived += available;
if (this.charReceived < this.charLength) {
// still not enough chars in this buffer? wait for more ...
return '';
}
// remove bytes belonging to the current character from the buffer
buffer = buffer.slice(available, buffer.length);
// get the character that was split
charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);
// CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
var charCode = charStr.charCodeAt(charStr.length - 1);
if (charCode >= 0xD800 && charCode <= 0xDBFF) {
this.charLength += this.surrogateSize;
charStr = '';
continue;
}
this.charReceived = this.charLength = 0;
// if there are no more bytes in this buffer, just emit our char
if (buffer.length === 0) {
return charStr;
}
break;
}
// determine and set charLength / charReceived
this.detectIncompleteChar(buffer);
var end = buffer.length;
if (this.charLength) {
// buffer the incomplete character bytes we got
buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);
end -= this.charReceived;
}
charStr += buffer.toString(this.encoding, 0, end);
var end = charStr.length - 1;
var charCode = charStr.charCodeAt(end);
// CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
if (charCode >= 0xD800 && charCode <= 0xDBFF) {
var size = this.surrogateSize;
this.charLength += size;
this.charReceived += size;
this.charBuffer.copy(this.charBuffer, size, 0, size);
buffer.copy(this.charBuffer, 0, 0, size);
return charStr.substring(0, end);
}
// or just emit the charStr
return charStr;
};
// detectIncompleteChar determines if there is an incomplete UTF-8 character at
// the end of the given buffer. If so, it sets this.charLength to the byte
// length that character, and sets this.charReceived to the number of bytes
// that are available for this character.
StringDecoder.prototype.detectIncompleteChar = function(buffer) {
// determine how many bytes we have to check at the end of this buffer
var i = (buffer.length >= 3) ? 3 : buffer.length;
// Figure out if one of the last i bytes of our buffer announces an
// incomplete char.
for (; i > 0; i--) {
var c = buffer[buffer.length - i];
// See http://en.wikipedia.org/wiki/UTF-8#Description
// 110XXXXX
if (i == 1 && c >> 5 == 0x06) {
this.charLength = 2;
break;
}
// 1110XXXX
if (i <= 2 && c >> 4 == 0x0E) {
this.charLength = 3;
break;
}
// 11110XXX
if (i <= 3 && c >> 3 == 0x1E) {
this.charLength = 4;
break;
}
}
this.charReceived = i;
};
StringDecoder.prototype.end = function(buffer) {
var res = '';
if (buffer && buffer.length)
res = this.write(buffer);
if (this.charReceived) {
var cr = this.charReceived;
var buf = this.charBuffer;
var enc = this.encoding;
res += buf.slice(0, cr).toString(enc);
}
return res;
};
function passThroughWrite(buffer) {
return buffer.toString(this.encoding);
}
function utf16DetectIncompleteChar(buffer) {
this.charReceived = buffer.length % 2;
this.charLength = this.charReceived ? 2 : 0;
}
function base64DetectIncompleteChar(buffer) {
this.charReceived = buffer.length % 3;
this.charLength = this.charReceived ? 3 : 0;
}

@ -1,25 +0,0 @@
{
"name": "string_decoder",
"version": "0.10.31",
"description": "The string_decoder module from Node core",
"main": "index.js",
"dependencies": {},
"devDependencies": {
"tap": "~0.4.8"
},
"scripts": {
"test": "tap test/simple/*.js"
},
"repository": {
"type": "git",
"url": "git://github.com/rvagg/string_decoder.git"
},
"homepage": "https://github.com/rvagg/string_decoder",
"keywords": [
"string",
"decoder",
"browser",
"browserify"
],
"license": "MIT"
}

17
node_modules/busboy/package.json generated vendored

@ -1,16 +1,21 @@
{ "name": "busboy",
"version": "0.2.14",
"version": "1.6.0",
"author": "Brian White <mscdex@mscdex.net>",
"description": "A streaming parser for HTML form data for node.js",
"main": "./lib/main",
"main": "./lib/index.js",
"dependencies": {
"dicer": "0.2.5",
"readable-stream": "1.1.x"
"streamsearch": "^1.1.0"
},
"devDependencies": {
"@mscdex/eslint-config": "^1.1.0",
"eslint": "^7.32.0"
},
"scripts": {
"test": "node test/test.js"
"test": "node test/test.js",
"lint": "eslint --cache --report-unused-disable-directives --ext=.js .eslintrc.js lib test bench",
"lint:fix": "npm run lint -- --fix"
},
"engines": { "node": ">=0.8.0" },
"engines": { "node": ">=10.16.0" },
"keywords": [ "uploads", "forms", "multipart", "form-data" ],
"licenses": [ { "type": "MIT", "url": "http://github.com/mscdex/busboy/raw/master/LICENSE" } ],
"repository": { "type": "git", "url": "http://github.com/mscdex/busboy.git" }

109
node_modules/busboy/test/common.js generated vendored

@ -0,0 +1,109 @@
'use strict';
const assert = require('assert');
const { inspect } = require('util');
const mustCallChecks = [];
function noop() {}
function runCallChecks(exitCode) {
if (exitCode !== 0) return;
const failed = mustCallChecks.filter((context) => {
if ('minimum' in context) {
context.messageSegment = `at least ${context.minimum}`;
return context.actual < context.minimum;
}
context.messageSegment = `exactly ${context.exact}`;
return context.actual !== context.exact;
});
failed.forEach((context) => {
console.error('Mismatched %s function calls. Expected %s, actual %d.',
context.name,
context.messageSegment,
context.actual);
console.error(context.stack.split('\n').slice(2).join('\n'));
});
if (failed.length)
process.exit(1);
}
function mustCall(fn, exact) {
return _mustCallInner(fn, exact, 'exact');
}
function mustCallAtLeast(fn, minimum) {
return _mustCallInner(fn, minimum, 'minimum');
}
function _mustCallInner(fn, criteria = 1, field) {
if (process._exiting)
throw new Error('Cannot use common.mustCall*() in process exit handler');
if (typeof fn === 'number') {
criteria = fn;
fn = noop;
} else if (fn === undefined) {
fn = noop;
}
if (typeof criteria !== 'number')
throw new TypeError(`Invalid ${field} value: ${criteria}`);
const context = {
[field]: criteria,
actual: 0,
stack: inspect(new Error()),
name: fn.name || '<anonymous>'
};
// Add the exit listener only once to avoid listener leak warnings
if (mustCallChecks.length === 0)
process.on('exit', runCallChecks);
mustCallChecks.push(context);
function wrapped(...args) {
++context.actual;
return fn.call(this, ...args);
}
// TODO: remove origFn?
wrapped.origFn = fn;
return wrapped;
}
function getCallSite(top) {
const originalStackFormatter = Error.prepareStackTrace;
Error.prepareStackTrace = (err, stack) =>
`${stack[0].getFileName()}:${stack[0].getLineNumber()}`;
const err = new Error();
Error.captureStackTrace(err, top);
// With the V8 Error API, the stack is not formatted until it is accessed
// eslint-disable-next-line no-unused-expressions
err.stack;
Error.prepareStackTrace = originalStackFormatter;
return err.stack;
}
function mustNotCall(msg) {
const callSite = getCallSite(mustNotCall);
return function mustNotCall(...args) {
args = args.map(inspect).join(', ');
const argsInfo = (args.length > 0
? `\ncalled with arguments: ${args}`
: '');
assert.fail(
`${msg || 'function should not have been called'} at ${callSite}`
+ argsInfo);
};
}
module.exports = {
mustCall,
mustCallAtLeast,
mustNotCall,
};

@ -0,0 +1,94 @@
'use strict';
const assert = require('assert');
const { inspect } = require('util');
const { mustCall } = require(`${__dirname}/common.js`);
const busboy = require('..');
const input = Buffer.from([
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
'Content-Disposition: form-data; '
+ 'name="upload_file_0"; filename="テスト.dat"',
'Content-Type: application/octet-stream',
'',
'A'.repeat(1023),
'-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
].join('\r\n'));
const boundary = '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k';
const expected = [
{ type: 'file',
name: 'upload_file_0',
data: Buffer.from('A'.repeat(1023)),
info: {
filename: 'テスト.dat',
encoding: '7bit',
mimeType: 'application/octet-stream',
},
limited: false,
},
];
const bb = busboy({
defParamCharset: 'utf8',
headers: {
'content-type': `multipart/form-data; boundary=${boundary}`,
}
});
const results = [];
bb.on('field', (name, val, info) => {
results.push({ type: 'field', name, val, info });
});
bb.on('file', (name, stream, info) => {
const data = [];
let nb = 0;
const file = {
type: 'file',
name,
data: null,
info,
limited: false,
};
results.push(file);
stream.on('data', (d) => {
data.push(d);
nb += d.length;
}).on('limit', () => {
file.limited = true;
}).on('close', () => {
file.data = Buffer.concat(data, nb);
assert.strictEqual(stream.truncated, file.limited);
}).once('error', (err) => {
file.err = err.message;
});
});
bb.on('error', (err) => {
results.push({ error: err.message });
});
bb.on('partsLimit', () => {
results.push('partsLimit');
});
bb.on('filesLimit', () => {
results.push('filesLimit');
});
bb.on('fieldsLimit', () => {
results.push('fieldsLimit');
});
bb.on('close', mustCall(() => {
assert.deepStrictEqual(
results,
expected,
'Results mismatch.\n'
+ `Parsed: ${inspect(results)}\n`
+ `Expected: ${inspect(expected)}`
);
}));
bb.end(input);

@ -0,0 +1,102 @@
'use strict';
const assert = require('assert');
const { randomFillSync } = require('crypto');
const { inspect } = require('util');
const busboy = require('..');
const { mustCall } = require('./common.js');
const BOUNDARY = 'u2KxIV5yF1y+xUspOQCCZopaVgeV6Jxihv35XQJmuTx8X3sh';
function formDataSection(key, value) {
return Buffer.from(
`\r\n--${BOUNDARY}`
+ `\r\nContent-Disposition: form-data; name="${key}"`
+ `\r\n\r\n${value}`
);
}
function formDataFile(key, filename, contentType) {
const buf = Buffer.allocUnsafe(100000);
return Buffer.concat([
Buffer.from(`\r\n--${BOUNDARY}\r\n`),
Buffer.from(`Content-Disposition: form-data; name="${key}"`
+ `; filename="${filename}"\r\n`),
Buffer.from(`Content-Type: ${contentType}\r\n\r\n`),
randomFillSync(buf)
]);
}
const reqChunks = [
Buffer.concat([
formDataFile('file', 'file.bin', 'application/octet-stream'),
formDataSection('foo', 'foo value'),
]),
formDataSection('bar', 'bar value'),
Buffer.from(`\r\n--${BOUNDARY}--\r\n`)
];
const bb = busboy({
headers: {
'content-type': `multipart/form-data; boundary=${BOUNDARY}`
}
});
const expected = [
{ type: 'file',
name: 'file',
info: {
filename: 'file.bin',
encoding: '7bit',
mimeType: 'application/octet-stream',
},
},
{ type: 'field',
name: 'foo',
val: 'foo value',
info: {
nameTruncated: false,
valueTruncated: false,
encoding: '7bit',
mimeType: 'text/plain',
},
},
{ type: 'field',
name: 'bar',
val: 'bar value',
info: {
nameTruncated: false,
valueTruncated: false,
encoding: '7bit',
mimeType: 'text/plain',
},
},
];
const results = [];
bb.on('field', (name, val, info) => {
results.push({ type: 'field', name, val, info });
});
bb.on('file', (name, stream, info) => {
results.push({ type: 'file', name, info });
// Simulate a pipe where the destination is pausing (perhaps due to waiting
// for file system write to finish)
setTimeout(() => {
stream.resume();
}, 10);
});
bb.on('close', mustCall(() => {
assert.deepStrictEqual(
results,
expected,
'Results mismatch.\n'
+ `Parsed: ${inspect(results)}\n`
+ `Expected: ${inspect(expected)}`
);
}));
for (const chunk of reqChunks)
bb.write(chunk);
bb.end();

File diff suppressed because it is too large Load Diff

@ -1,108 +1,362 @@
var Busboy = require('..');
'use strict';
var path = require('path'),
inspect = require('util').inspect,
assert = require('assert');
const assert = require('assert');
const { transcode } = require('buffer');
const { inspect } = require('util');
var EMPTY_FN = function() {};
const busboy = require('..');
var t = 0,
group = path.basename(__filename, '.js') + '/';
const active = new Map();
var tests = [
const tests = [
{ source: ['foo'],
expected: [['foo', '', false, false]],
expected: [
['foo',
'',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Unassigned value'
},
{ source: ['foo=bar'],
expected: [['foo', 'bar', false, false]],
expected: [
['foo',
'bar',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Assigned value'
},
{ source: ['foo&bar=baz'],
expected: [['foo', '', false, false],
['bar', 'baz', false, false]],
expected: [
['foo',
'',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
['bar',
'baz',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Unassigned and assigned value'
},
{ source: ['foo=bar&baz'],
expected: [['foo', 'bar', false, false],
['baz', '', false, false]],
expected: [
['foo',
'bar',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
['baz',
'',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Assigned and unassigned value'
},
{ source: ['foo=bar&baz=bla'],
expected: [['foo', 'bar', false, false],
['baz', 'bla', false, false]],
expected: [
['foo',
'bar',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
['baz',
'bla',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Two assigned values'
},
{ source: ['foo&bar'],
expected: [['foo', '', false, false],
['bar', '', false, false]],
expected: [
['foo',
'',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
['bar',
'',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Two unassigned values'
},
{ source: ['foo&bar&'],
expected: [['foo', '', false, false],
['bar', '', false, false]],
expected: [
['foo',
'',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
['bar',
'',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Two unassigned values and ampersand'
},
{ source: ['foo=bar+baz%2Bquux'],
expected: [['foo', 'bar baz+quux', false, false]],
what: 'Assigned value with (plus) space'
{ source: ['foo+1=bar+baz%2Bquux'],
expected: [
['foo 1',
'bar baz+quux',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Assigned key and value with (plus) space'
},
{ source: ['foo=bar%20baz%21'],
expected: [['foo', 'bar baz!', false, false]],
expected: [
['foo',
'bar baz!',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Assigned value with encoded bytes'
},
{ source: ['foo%20bar=baz%20bla%21'],
expected: [['foo bar', 'baz bla!', false, false]],
expected: [
['foo bar',
'baz bla!',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Assigned value with encoded bytes #2'
},
{ source: ['foo=bar%20baz%21&num=1000'],
expected: [['foo', 'bar baz!', false, false],
['num', '1000', false, false]],
expected: [
['foo',
'bar baz!',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
['num',
'1000',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Two assigned values, one with encoded bytes'
},
{ source: [
Array.from(transcode(Buffer.from('foo'), 'utf8', 'utf16le')).map(
(n) => `%${n.toString(16).padStart(2, '0')}`
).join(''),
'=',
Array.from(transcode(Buffer.from('😀!'), 'utf8', 'utf16le')).map(
(n) => `%${n.toString(16).padStart(2, '0')}`
).join(''),
],
expected: [
['foo',
'😀!',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'UTF-16LE',
mimeType: 'text/plain' },
],
],
charset: 'UTF-16LE',
what: 'Encoded value with multi-byte charset'
},
{ source: [
'foo=<',
Array.from(transcode(Buffer.from('©:^þ'), 'utf8', 'latin1')).map(
(n) => `%${n.toString(16).padStart(2, '0')}`
).join(''),
],
expected: [
['foo',
'<©:^þ',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'ISO-8859-1',
mimeType: 'text/plain' },
],
],
charset: 'ISO-8859-1',
what: 'Encoded value with single-byte, ASCII-compatible, non-UTF8 charset'
},
{ source: ['foo=bar&baz=bla'],
expected: [],
what: 'Limits: zero fields',
limits: { fields: 0 }
},
{ source: ['foo=bar&baz=bla'],
expected: [['foo', 'bar', false, false]],
expected: [
['foo',
'bar',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Limits: one field',
limits: { fields: 1 }
},
{ source: ['foo=bar&baz=bla'],
expected: [['foo', 'bar', false, false],
['baz', 'bla', false, false]],
expected: [
['foo',
'bar',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
['baz',
'bla',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Limits: field part lengths match limits',
limits: { fieldNameSize: 3, fieldSize: 3 }
},
{ source: ['foo=bar&baz=bla'],
expected: [['fo', 'bar', true, false],
['ba', 'bla', true, false]],
expected: [
['fo',
'bar',
{ nameTruncated: true,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
['ba',
'bla',
{ nameTruncated: true,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Limits: truncated field name',
limits: { fieldNameSize: 2 }
},
{ source: ['foo=bar&baz=bla'],
expected: [['foo', 'ba', false, true],
['baz', 'bl', false, true]],
expected: [
['foo',
'ba',
{ nameTruncated: false,
valueTruncated: true,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
['baz',
'bl',
{ nameTruncated: false,
valueTruncated: true,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Limits: truncated field value',
limits: { fieldSize: 2 }
},
{ source: ['foo=bar&baz=bla'],
expected: [['fo', 'ba', true, true],
['ba', 'bl', true, true]],
expected: [
['fo',
'ba',
{ nameTruncated: true,
valueTruncated: true,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
['ba',
'bl',
{ nameTruncated: true,
valueTruncated: true,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Limits: truncated field name and value',
limits: { fieldNameSize: 2, fieldSize: 2 }
},
{ source: ['foo=bar&baz=bla'],
expected: [['fo', '', true, true],
['ba', '', true, true]],
expected: [
['fo',
'',
{ nameTruncated: true,
valueTruncated: true,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
['ba',
'',
{ nameTruncated: true,
valueTruncated: true,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Limits: truncated field name and zero value limit',
limits: { fieldNameSize: 2, fieldSize: 0 }
},
{ source: ['foo=bar&baz=bla'],
expected: [['', '', true, true],
['', '', true, true]],
expected: [
['',
'',
{ nameTruncated: true,
valueTruncated: true,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
['',
'',
{ nameTruncated: true,
valueTruncated: true,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Limits: truncated zero field name and zero value limit',
limits: { fieldNameSize: 0, fieldSize: 0 }
},
@ -115,7 +369,15 @@ var tests = [
what: 'Many ampersands'
},
{ source: ['='],
expected: [['', '', false, false]],
expected: [
['',
'',
{ nameTruncated: false,
valueTruncated: false,
encoding: 'utf-8',
mimeType: 'text/plain' },
],
],
what: 'Assigned value, empty name and value'
},
{ source: [''],
@ -124,60 +386,103 @@ var tests = [
},
];
function next() {
if (t === tests.length)
return;
var v = tests[t];
for (const test of tests) {
active.set(test, 1);
var busboy = new Busboy({
limits: v.limits,
const { what } = test;
const charset = test.charset || 'utf-8';
const bb = busboy({
limits: test.limits,
headers: {
'content-type': 'application/x-www-form-urlencoded; charset=utf-8'
}
}),
finishes = 0,
results = [];
'content-type': `application/x-www-form-urlencoded; charset=${charset}`,
},
});
const results = [];
busboy.on('field', function(key, val, keyTrunc, valTrunc) {
results.push([key, val, keyTrunc, valTrunc]);
bb.on('field', (key, val, info) => {
results.push([key, val, info]);
});
busboy.on('file', function() {
throw new Error(makeMsg(v.what, 'Unexpected file'));
bb.on('file', () => {
throw new Error(`[${what}] Unexpected file`);
});
busboy.on('finish', function() {
assert(finishes++ === 0, makeMsg(v.what, 'finish emitted multiple times'));
assert.deepEqual(results.length,
v.expected.length,
makeMsg(v.what, 'Parsed result count mismatch. Saw '
+ results.length
+ '. Expected: ' + v.expected.length));
var i = 0;
results.forEach(function(result) {
assert.deepEqual(result,
v.expected[i],
makeMsg(v.what,
'Result mismatch:\nParsed: ' + inspect(result)
+ '\nExpected: ' + inspect(v.expected[i]))
bb.on('close', () => {
active.delete(test);
assert.deepStrictEqual(
results,
test.expected,
`[${what}] Results mismatch.\n`
+ `Parsed: ${inspect(results)}\n`
+ `Expected: ${inspect(test.expected)}`
);
++i;
});
++t;
next();
for (const src of test.source) {
const buf = (typeof src === 'string' ? Buffer.from(src, 'utf8') : src);
bb.write(buf);
}
bb.end();
}
// Byte-by-byte versions
for (let test of tests) {
test = { ...test };
test.what += ' (byte-by-byte)';
active.set(test, 1);
const { what } = test;
const charset = test.charset || 'utf-8';
const bb = busboy({
limits: test.limits,
headers: {
'content-type': `application/x-www-form-urlencoded; charset="${charset}"`,
},
});
const results = [];
bb.on('field', (key, val, info) => {
results.push([key, val, info]);
});
v.source.forEach(function(s) {
busboy.write(new Buffer(s, 'utf8'), EMPTY_FN);
bb.on('file', () => {
throw new Error(`[${what}] Unexpected file`);
});
busboy.end();
}
next();
function makeMsg(what, msg) {
return '[' + group + what + ']: ' + msg;
bb.on('close', () => {
active.delete(test);
assert.deepStrictEqual(
results,
test.expected,
`[${what}] Results mismatch.\n`
+ `Parsed: ${inspect(results)}\n`
+ `Expected: ${inspect(test.expected)}`
);
});
for (const src of test.source) {
const buf = (typeof src === 'string' ? Buffer.from(src, 'utf8') : src);
for (let i = 0; i < buf.length; ++i)
bb.write(buf.slice(i, i + 1));
}
bb.end();
}
process.on('exit', function() {
assert(t === tests.length, makeMsg('_exit', 'Only finished ' + t + '/' + tests.length + ' tests'));
{
let exception = false;
process.once('uncaughtException', (ex) => {
exception = true;
throw ex;
});
process.on('exit', () => {
if (exception || active.size === 0)
return;
process.exitCode = 1;
console.error('==========================');
console.error(`${active.size} test(s) did not finish:`);
console.error('==========================');
console.error(Array.from(active.keys()).map((v) => v.what).join('\n'));
});
}

@ -1,66 +0,0 @@
var Decoder = require('../lib/utils').Decoder;
var path = require('path'),
assert = require('assert');
var group = path.basename(__filename, '.js') + '/';
[
{ source: ['Hello world'],
expected: 'Hello world',
what: 'No encoded bytes'
},
{ source: ['Hello%20world'],
expected: 'Hello world',
what: 'One full encoded byte'
},
{ source: ['Hello%20world%21'],
expected: 'Hello world!',
what: 'Two full encoded bytes'
},
{ source: ['Hello%', '20world'],
expected: 'Hello world',
what: 'One full encoded byte split #1'
},
{ source: ['Hello%2', '0world'],
expected: 'Hello world',
what: 'One full encoded byte split #2'
},
{ source: ['Hello%20', 'world'],
expected: 'Hello world',
what: 'One full encoded byte (concat)'
},
{ source: ['Hello%2Qworld'],
expected: 'Hello%2Qworld',
what: 'Malformed encoded byte #1'
},
{ source: ['Hello%world'],
expected: 'Hello%world',
what: 'Malformed encoded byte #2'
},
{ source: ['Hello+world'],
expected: 'Hello world',
what: 'Plus to space'
},
{ source: ['Hello+world%21'],
expected: 'Hello world!',
what: 'Plus and encoded byte'
},
{ source: ['5%2B5%3D10'],
expected: '5+5=10',
what: 'Encoded plus'
},
{ source: ['5+%2B+5+%3D+10'],
expected: '5 + 5 = 10',
what: 'Spaces and encoded plus'
},
].forEach(function(v) {
var dec = new Decoder(), result = '';
v.source.forEach(function(s) {
result += dec.write(s);
});
var msg = '[' + group + v.what + ']: decoded string mismatch.\n'
+ 'Saw: ' + result + '\n'
+ 'Expected: ' + v.expected;
assert.deepEqual(result, v.expected, msg);
});

@ -1,96 +0,0 @@
var parseParams = require('../lib/utils').parseParams;
var path = require('path'),
assert = require('assert'),
inspect = require('util').inspect;
var group = path.basename(__filename, '.js') + '/';
[
{ source: 'video/ogg',
expected: ['video/ogg'],
what: 'No parameters'
},
{ source: 'video/ogg;',
expected: ['video/ogg'],
what: 'No parameters (with separator)'
},
{ source: 'video/ogg; ',
expected: ['video/ogg'],
what: 'No parameters (with separator followed by whitespace)'
},
{ source: ';video/ogg',
expected: ['', 'video/ogg'],
what: 'Empty parameter'
},
{ source: 'video/*',
expected: ['video/*'],
what: 'Subtype with asterisk'
},
{ source: 'text/plain; encoding=utf8',
expected: ['text/plain', ['encoding', 'utf8']],
what: 'Unquoted'
},
{ source: 'text/plain; encoding=',
expected: ['text/plain', ['encoding', '']],
what: 'Unquoted empty string'
},
{ source: 'text/plain; encoding="utf8"',
expected: ['text/plain', ['encoding', 'utf8']],
what: 'Quoted'
},
{ source: 'text/plain; greeting="hello \\"world\\""',
expected: ['text/plain', ['greeting', 'hello "world"']],
what: 'Quotes within quoted'
},
{ source: 'text/plain; encoding=""',
expected: ['text/plain', ['encoding', '']],
what: 'Quoted empty string'
},
{ source: 'text/plain; encoding="utf8";\t foo=bar;test',
expected: ['text/plain', ['encoding', 'utf8'], ['foo', 'bar'], 'test'],
what: 'Multiple params with various spacing'
},
{ source: "text/plain; filename*=iso-8859-1'en'%A3%20rates",
expected: ['text/plain', ['filename', '£ rates']],
what: 'Extended parameter (RFC 5987) with language'
},
{ source: "text/plain; filename*=utf-8''%c2%a3%20and%20%e2%82%ac%20rates",
expected: ['text/plain', ['filename', '£ and € rates']],
what: 'Extended parameter (RFC 5987) without language'
},
{ source: "text/plain; filename*=utf-8''%E6%B5%8B%E8%AF%95%E6%96%87%E6%A1%A3",
expected: ['text/plain', ['filename', '测试文档']],
what: 'Extended parameter (RFC 5987) without language #2'
},
{ source: "text/plain; filename*=iso-8859-1'en'%A3%20rates; altfilename*=utf-8''%c2%a3%20and%20%e2%82%ac%20rates",
expected: ['text/plain', ['filename', '£ rates'], ['altfilename', '£ and € rates']],
what: 'Multiple extended parameters (RFC 5987) with mixed charsets'
},
{ source: "text/plain; filename*=iso-8859-1'en'%A3%20rates; altfilename=\"foobarbaz\"",
expected: ['text/plain', ['filename', '£ rates'], ['altfilename', 'foobarbaz']],
what: 'Mixed regular and extended parameters (RFC 5987)'
},
{ source: "text/plain; filename=\"foobarbaz\"; altfilename*=iso-8859-1'en'%A3%20rates",
expected: ['text/plain', ['filename', 'foobarbaz'], ['altfilename', '£ rates']],
what: 'Mixed regular and extended parameters (RFC 5987) #2'
},
{ source: 'text/plain; filename="C:\\folder\\test.png"',
expected: ['text/plain', ['filename', 'C:\\folder\\test.png']],
what: 'Unescaped backslashes should be considered backslashes'
},
{ source: 'text/plain; filename="John \\"Magic\\" Smith.png"',
expected: ['text/plain', ['filename', 'John "Magic" Smith.png']],
what: 'Escaped double-quotes should be considered double-quotes'
},
{ source: 'multipart/form-data; charset=utf-8; boundary=0xKhTmLbOuNdArY',
expected: ['multipart/form-data', ['charset', 'utf-8'], ['boundary', '0xKhTmLbOuNdArY']],
what: 'Multiple non-quoted parameters'
},
].forEach(function(v) {
var result = parseParams(v.source),
msg = '[' + group + v.what + ']: parsed parameters mismatch.\n'
+ 'Saw: ' + inspect(result) + '\n'
+ 'Expected: ' + inspect(v.expected);
assert.deepEqual(result, v.expected, msg);
});

22
node_modules/busboy/test/test.js generated vendored

@ -1,4 +1,20 @@
require('fs').readdirSync(__dirname).forEach(function(f) {
if (f.substr(0, 5) === 'test-')
require('./' + f);
'use strict';
const { spawnSync } = require('child_process');
const { readdirSync } = require('fs');
const { join } = require('path');
const files = readdirSync(__dirname).sort();
for (const filename of files) {
if (filename.startsWith('test-')) {
const path = join(__dirname, filename);
console.log(`> Running ${filename} ...`);
const result = spawnSync(`${process.argv0} ${path}`, {
shell: true,
stdio: 'inherit',
windowsHide: true
});
if (result.status !== 0)
process.exitCode = 1;
}
}

16
node_modules/dicer/.travis.yml generated vendored

@ -1,16 +0,0 @@
sudo: false
language: cpp
notifications:
email: false
env:
matrix:
- TRAVIS_NODE_VERSION="0.10"
- TRAVIS_NODE_VERSION="0.12"
- TRAVIS_NODE_VERSION="4"
- TRAVIS_NODE_VERSION="5"
install:
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION
- node --version
- npm --version
- npm install
script: npm test

19
node_modules/dicer/LICENSE generated vendored

@ -1,19 +0,0 @@
Copyright Brian White. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

122
node_modules/dicer/README.md generated vendored

@ -1,122 +0,0 @@
Description
===========
A very fast streaming multipart parser for node.js.
Benchmarks can be found [here](https://github.com/mscdex/dicer/wiki/Benchmarks).
Requirements
============
* [node.js](http://nodejs.org/) -- v0.8.0 or newer
Install
============
npm install dicer
Examples
========
* Parse an HTTP form upload
```javascript
var inspect = require('util').inspect,
http = require('http');
var Dicer = require('dicer');
// quick and dirty way to parse multipart boundary
var RE_BOUNDARY = /^multipart\/.+?(?:; boundary=(?:(?:"(.+)")|(?:([^\s]+))))$/i,
HTML = new Buffer('<html><head></head><body>\
<form method="POST" enctype="multipart/form-data">\
<input type="text" name="textfield"><br />\
<input type="file" name="filefield"><br />\
<input type="submit">\
</form>\
</body></html>'),
PORT = 8080;
http.createServer(function(req, res) {
var m;
if (req.method === 'POST'
&& req.headers['content-type']
&& (m = RE_BOUNDARY.exec(req.headers['content-type']))) {
var d = new Dicer({ boundary: m[1] || m[2] });
d.on('part', function(p) {
console.log('New part!');
p.on('header', function(header) {
for (var h in header) {
console.log('Part header: k: ' + inspect(h)
+ ', v: ' + inspect(header[h]));
}
});
p.on('data', function(data) {
console.log('Part data: ' + inspect(data.toString()));
});
p.on('end', function() {
console.log('End of part\n');
});
});
d.on('finish', function() {
console.log('End of parts');
res.writeHead(200);
res.end('Form submission successful!');
});
req.pipe(d);
} else if (req.method === 'GET' && req.url === '/') {
res.writeHead(200);
res.end(HTML);
} else {
res.writeHead(404);
res.end();
}
}).listen(PORT, function() {
console.log('Listening for requests on port ' + PORT);
});
```
API
===
_Dicer_ is a _WritableStream_
Dicer (special) events
----------------------
* **finish**() - Emitted when all parts have been parsed and the Dicer instance has been ended.
* **part**(< _PartStream_ >stream) - Emitted when a new part has been found.
* **preamble**(< _PartStream_ >stream) - Emitted for preamble if you should happen to need it (can usually be ignored).
* **trailer**(< _Buffer_ >data) - Emitted when trailing data was found after the terminating boundary (as with the preamble, this can usually be ignored too).
Dicer methods
-------------
* **(constructor)**(< _object_ >config) - Creates and returns a new Dicer instance with the following valid `config` settings:
* **boundary** - _string_ - This is the boundary used to detect the beginning of a new part.
* **headerFirst** - _boolean_ - If true, preamble header parsing will be performed first.
* **maxHeaderPairs** - _integer_ - The maximum number of header key=>value pairs to parse **Default:** 2000 (same as node's http).
* **setBoundary**(< _string_ >boundary) - _(void)_ - Sets the boundary to use for parsing and performs some initialization needed for parsing. You should only need to use this if you set `headerFirst` to true in the constructor and are parsing the boundary from the preamble header.
_PartStream_ is a _ReadableStream_
PartStream (special) events
---------------------------
* **header**(< _object_ >header) - An object containing the header for this particular part. Each property value is an _array_ of one or more string values.

@ -1,63 +0,0 @@
var assert = require('assert');
var Dicer = require('..'),
boundary = '-----------------------------168072824752491622650073',
d = new Dicer({ boundary: boundary }),
mb = 100,
buffer = createMultipartBuffer(boundary, mb * 1024 * 1024),
callbacks =
{ partBegin: -1,
partEnd: -1,
headerField: -1,
headerValue: -1,
partData: -1,
end: -1,
};
d.on('part', function(p) {
callbacks.partBegin++;
p.on('header', function(header) {
/*for (var h in header)
console.log('Part header: k: ' + inspect(h) + ', v: ' + inspect(header[h]));*/
});
p.on('data', function(data) {
callbacks.partData++;
//console.log('Part data: ' + inspect(data.toString()));
});
p.on('end', function() {
//console.log('End of part\n');
callbacks.partEnd++;
});
});
d.on('end', function() {
//console.log('End of parts');
callbacks.end++;
});
var start = +new Date(),
nparsed = d.write(buffer),
duration = +new Date - start,
mbPerSec = (mb / (duration / 1000)).toFixed(2);
console.log(mbPerSec+' mb/sec');
//assert.equal(nparsed, buffer.length);
function createMultipartBuffer(boundary, size) {
var head =
'--'+boundary+'\r\n'
+ 'content-disposition: form-data; name="field1"\r\n'
+ '\r\n'
, tail = '\r\n--'+boundary+'--\r\n'
, buffer = new Buffer(size);
buffer.write(head, 'ascii', 0);
buffer.write(tail, 'ascii', buffer.length - tail.length);
return buffer;
}
process.on('exit', function() {
/*for (var k in callbacks) {
assert.equal(0, callbacks[k], k+' count off by '+callbacks[k]);
}*/
});

@ -1,70 +0,0 @@
var assert = require('assert');
require('../node_modules/formidable/test/common');
var multipartParser = require('../node_modules/formidable/lib/multipart_parser'),
MultipartParser = multipartParser.MultipartParser,
parser = new MultipartParser(),
boundary = '-----------------------------168072824752491622650073',
mb = 100,
buffer = createMultipartBuffer(boundary, mb * 1024 * 1024),
callbacks =
{ partBegin: -1,
partEnd: -1,
headerField: -1,
headerValue: -1,
partData: -1,
end: -1,
};
parser.initWithBoundary(boundary);
parser.onHeaderField = function() {
callbacks.headerField++;
};
parser.onHeaderValue = function() {
callbacks.headerValue++;
};
parser.onPartBegin = function() {
callbacks.partBegin++;
};
parser.onPartData = function() {
callbacks.partData++;
};
parser.onPartEnd = function() {
callbacks.partEnd++;
};
parser.onEnd = function() {
callbacks.end++;
};
var start = +new Date(),
nparsed = parser.write(buffer),
duration = +new Date - start,
mbPerSec = (mb / (duration / 1000)).toFixed(2);
console.log(mbPerSec+' mb/sec');
//assert.equal(nparsed, buffer.length);
function createMultipartBuffer(boundary, size) {
var head =
'--'+boundary+'\r\n'
+ 'content-disposition: form-data; name="field1"\r\n'
+ '\r\n'
, tail = '\r\n--'+boundary+'--\r\n'
, buffer = new Buffer(size);
buffer.write(head, 'ascii', 0);
buffer.write(tail, 'ascii', buffer.length - tail.length);
return buffer;
}
process.on('exit', function() {
/*for (var k in callbacks) {
assert.equal(0, callbacks[k], k+' count off by '+callbacks[k]);
}*/
});

@ -1,56 +0,0 @@
var assert = require('assert');
var multipartser = require('multipartser'),
boundary = '-----------------------------168072824752491622650073',
parser = multipartser(),
mb = 100,
buffer = createMultipartBuffer(boundary, mb * 1024 * 1024),
callbacks =
{ partBegin: -1,
partEnd: -1,
headerField: -1,
headerValue: -1,
partData: -1,
end: -1,
};
parser.boundary( boundary );
parser.on( 'part', function ( part ) {
});
parser.on( 'end', function () {
//console.log( 'completed parsing' );
});
parser.on( 'error', function ( error ) {
console.error( error );
});
var start = +new Date(),
nparsed = parser.data(buffer),
nend = parser.end(),
duration = +new Date - start,
mbPerSec = (mb / (duration / 1000)).toFixed(2);
console.log(mbPerSec+' mb/sec');
//assert.equal(nparsed, buffer.length);
function createMultipartBuffer(boundary, size) {
var head =
'--'+boundary+'\r\n'
+ 'content-disposition: form-data; name="field1"\r\n'
+ '\r\n'
, tail = '\r\n--'+boundary+'--\r\n'
, buffer = new Buffer(size);
buffer.write(head, 'ascii', 0);
buffer.write(tail, 'ascii', buffer.length - tail.length);
return buffer;
}
process.on('exit', function() {
/*for (var k in callbacks) {
assert.equal(0, callbacks[k], k+' count off by '+callbacks[k]);
}*/
});

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save