From bc59c0c7859277cf5c41f238e31a68149bf7729b Mon Sep 17 00:00:00 2001 From: seung6lee Date: Thu, 13 Aug 2026 17:51:31 +0900 Subject: [PATCH] untrack unnecessary files --- .DS_Store | Bin 6148 -> 0 bytes .gitignore | 4 + data/responses.csv | 2 - data/responses.json | 285 - mise.toml | 2 + node_modules/.bin/mime | 1 - node_modules/.bin/sass | 1 - node_modules/.package-lock.json | 1007 - .../@parcel/watcher-darwin-arm64/LICENSE | 21 - .../@parcel/watcher-darwin-arm64/README.md | 1 - .../@parcel/watcher-darwin-arm64/package.json | 30 - .../@parcel/watcher-darwin-arm64/watcher.node | Bin 326112 -> 0 bytes node_modules/@parcel/watcher/LICENSE | 21 - node_modules/@parcel/watcher/README.md | 136 - node_modules/@parcel/watcher/binding.gyp | 109 - node_modules/@parcel/watcher/index.d.ts | 49 - node_modules/@parcel/watcher/index.js | 42 - node_modules/@parcel/watcher/index.js.flow | 48 - node_modules/@parcel/watcher/package.json | 88 - .../watcher/scripts/build-from-source.js | 13 - node_modules/@parcel/watcher/src/Backend.cc | 186 - node_modules/@parcel/watcher/src/Backend.hh | 37 - node_modules/@parcel/watcher/src/Debounce.cc | 113 - node_modules/@parcel/watcher/src/Debounce.hh | 49 - node_modules/@parcel/watcher/src/DirTree.cc | 164 - node_modules/@parcel/watcher/src/DirTree.hh | 50 - node_modules/@parcel/watcher/src/Event.hh | 109 - node_modules/@parcel/watcher/src/Glob.cc | 22 - node_modules/@parcel/watcher/src/Glob.hh | 34 - .../@parcel/watcher/src/PromiseRunner.hh | 101 - node_modules/@parcel/watcher/src/Signal.hh | 46 - node_modules/@parcel/watcher/src/Watcher.cc | 241 - node_modules/@parcel/watcher/src/Watcher.hh | 73 - node_modules/@parcel/watcher/src/binding.cc | 268 - .../watcher/src/kqueue/KqueueBackend.cc | 306 - .../watcher/src/kqueue/KqueueBackend.hh | 35 - .../watcher/src/linux/InotifyBackend.cc | 236 - .../watcher/src/linux/InotifyBackend.hh | 34 - .../watcher/src/macos/FSEventsBackend.cc | 338 - .../watcher/src/macos/FSEventsBackend.hh | 20 - .../watcher/src/shared/BruteForceBackend.cc | 41 - .../watcher/src/shared/BruteForceBackend.hh | 25 - node_modules/@parcel/watcher/src/unix/fts.cc | 50 - .../@parcel/watcher/src/unix/legacy.cc | 77 - .../@parcel/watcher/src/wasm/WasmBackend.cc | 132 - .../@parcel/watcher/src/wasm/WasmBackend.hh | 34 - .../@parcel/watcher/src/wasm/include.h | 74 - .../@parcel/watcher/src/watchman/BSER.cc | 302 - .../@parcel/watcher/src/watchman/BSER.hh | 69 - .../@parcel/watcher/src/watchman/IPC.hh | 175 - .../watcher/src/watchman/WatchmanBackend.cc | 342 - .../watcher/src/watchman/WatchmanBackend.hh | 35 - .../watcher/src/windows/WindowsBackend.cc | 282 - .../watcher/src/windows/WindowsBackend.hh | 18 - .../@parcel/watcher/src/windows/win_utils.cc | 44 - .../@parcel/watcher/src/windows/win_utils.hh | 11 - node_modules/@parcel/watcher/wrapper.js | 74 - node_modules/accepts/HISTORY.md | 243 - node_modules/accepts/LICENSE | 23 - node_modules/accepts/README.md | 140 - node_modules/accepts/index.js | 238 - node_modules/accepts/package.json | 47 - node_modules/array-flatten/LICENSE | 21 - node_modules/array-flatten/README.md | 43 - node_modules/array-flatten/array-flatten.js | 64 - node_modules/array-flatten/package.json | 39 - node_modules/body-parser/HISTORY.md | 686 - node_modules/body-parser/LICENSE | 23 - node_modules/body-parser/README.md | 476 - node_modules/body-parser/index.js | 156 - node_modules/body-parser/lib/read.js | 205 - node_modules/body-parser/lib/types/json.js | 243 - node_modules/body-parser/lib/types/raw.js | 101 - node_modules/body-parser/lib/types/text.js | 121 - .../body-parser/lib/types/urlencoded.js | 299 - .../body-parser/node_modules/qs/.editorconfig | 46 - .../node_modules/qs/.github/FUNDING.yml | 12 - .../node_modules/qs/.github/SECURITY.md | 11 - .../node_modules/qs/.github/THREAT_MODEL.md | 78 - .../body-parser/node_modules/qs/.nycrc | 13 - .../body-parser/node_modules/qs/CHANGELOG.md | 812 - .../body-parser/node_modules/qs/LICENSE.md | 29 - .../body-parser/node_modules/qs/README.md | 758 - .../body-parser/node_modules/qs/dist/qs.js | 141 - .../node_modules/qs/eslint.config.mjs | 56 - .../node_modules/qs/lib/formats.js | 23 - .../body-parser/node_modules/qs/lib/index.js | 11 - .../body-parser/node_modules/qs/lib/parse.js | 373 - .../node_modules/qs/lib/stringify.js | 356 - .../body-parser/node_modules/qs/lib/utils.js | 342 - .../body-parser/node_modules/qs/package.json | 94 - .../node_modules/qs/test/empty-keys-cases.js | 267 - .../body-parser/node_modules/qs/test/parse.js | 1654 - .../node_modules/qs/test/stringify.js | 1319 - .../body-parser/node_modules/qs/test/utils.js | 432 - node_modules/body-parser/package.json | 55 - node_modules/bytes/History.md | 97 - node_modules/bytes/LICENSE | 23 - node_modules/bytes/Readme.md | 152 - node_modules/bytes/index.js | 170 - node_modules/bytes/package.json | 42 - .../call-bind-apply-helpers/.eslintrc | 17 - .../.github/FUNDING.yml | 12 - node_modules/call-bind-apply-helpers/.nycrc | 9 - .../call-bind-apply-helpers/CHANGELOG.md | 30 - node_modules/call-bind-apply-helpers/LICENSE | 21 - .../call-bind-apply-helpers/README.md | 62 - .../call-bind-apply-helpers/actualApply.d.ts | 1 - .../call-bind-apply-helpers/actualApply.js | 10 - .../call-bind-apply-helpers/applyBind.d.ts | 19 - .../call-bind-apply-helpers/applyBind.js | 10 - .../functionApply.d.ts | 1 - .../call-bind-apply-helpers/functionApply.js | 4 - .../call-bind-apply-helpers/functionCall.d.ts | 1 - .../call-bind-apply-helpers/functionCall.js | 4 - .../call-bind-apply-helpers/index.d.ts | 64 - node_modules/call-bind-apply-helpers/index.js | 15 - .../call-bind-apply-helpers/package.json | 85 - .../call-bind-apply-helpers/reflectApply.d.ts | 3 - .../call-bind-apply-helpers/reflectApply.js | 4 - .../call-bind-apply-helpers/test/index.js | 63 - .../call-bind-apply-helpers/tsconfig.json | 9 - node_modules/call-bound/.eslintrc | 13 - node_modules/call-bound/.github/FUNDING.yml | 12 - node_modules/call-bound/.nycrc | 9 - node_modules/call-bound/CHANGELOG.md | 42 - node_modules/call-bound/LICENSE | 21 - node_modules/call-bound/README.md | 53 - node_modules/call-bound/index.d.ts | 94 - node_modules/call-bound/index.js | 19 - node_modules/call-bound/package.json | 99 - node_modules/call-bound/test/index.js | 61 - node_modules/call-bound/tsconfig.json | 10 - node_modules/chokidar/LICENSE | 21 - node_modules/chokidar/README.md | 305 - node_modules/chokidar/esm/handler.d.ts | 90 - node_modules/chokidar/esm/handler.js | 629 - node_modules/chokidar/esm/index.d.ts | 215 - node_modules/chokidar/esm/index.js | 798 - node_modules/chokidar/esm/package.json | 1 - node_modules/chokidar/handler.d.ts | 90 - node_modules/chokidar/handler.js | 635 - node_modules/chokidar/index.d.ts | 215 - node_modules/chokidar/index.js | 804 - node_modules/chokidar/package.json | 69 - node_modules/content-disposition/HISTORY.md | 60 - node_modules/content-disposition/LICENSE | 22 - node_modules/content-disposition/README.md | 142 - node_modules/content-disposition/index.js | 458 - node_modules/content-disposition/package.json | 44 - node_modules/content-type/HISTORY.md | 29 - node_modules/content-type/LICENSE | 22 - node_modules/content-type/README.md | 94 - node_modules/content-type/index.js | 225 - node_modules/content-type/package.json | 42 - node_modules/cookie-signature/History.md | 42 - node_modules/cookie-signature/Readme.md | 42 - node_modules/cookie-signature/index.js | 51 - node_modules/cookie-signature/package.json | 18 - node_modules/cookie/LICENSE | 24 - node_modules/cookie/README.md | 317 - node_modules/cookie/SECURITY.md | 25 - node_modules/cookie/index.js | 335 - node_modules/cookie/package.json | 44 - node_modules/debug/.coveralls.yml | 1 - node_modules/debug/.eslintrc | 11 - node_modules/debug/.npmignore | 9 - node_modules/debug/.travis.yml | 14 - node_modules/debug/CHANGELOG.md | 362 - node_modules/debug/LICENSE | 19 - node_modules/debug/Makefile | 50 - node_modules/debug/README.md | 312 - node_modules/debug/component.json | 19 - node_modules/debug/karma.conf.js | 70 - node_modules/debug/node.js | 1 - node_modules/debug/package.json | 49 - node_modules/debug/src/browser.js | 185 - node_modules/debug/src/debug.js | 202 - node_modules/debug/src/index.js | 10 - node_modules/debug/src/inspector-log.js | 15 - node_modules/debug/src/node.js | 248 - node_modules/depd/History.md | 103 - node_modules/depd/LICENSE | 22 - node_modules/depd/Readme.md | 280 - node_modules/depd/index.js | 538 - node_modules/depd/lib/browser/index.js | 77 - node_modules/depd/package.json | 45 - node_modules/destroy/LICENSE | 23 - node_modules/destroy/README.md | 63 - node_modules/destroy/index.js | 209 - node_modules/destroy/package.json | 48 - node_modules/detect-libc/LICENSE | 201 - node_modules/detect-libc/README.md | 163 - node_modules/detect-libc/index.d.ts | 14 - node_modules/detect-libc/lib/detect-libc.js | 313 - node_modules/detect-libc/lib/elf.js | 39 - node_modules/detect-libc/lib/filesystem.js | 51 - node_modules/detect-libc/lib/process.js | 24 - node_modules/detect-libc/package.json | 44 - node_modules/dunder-proto/.eslintrc | 5 - node_modules/dunder-proto/.github/FUNDING.yml | 12 - node_modules/dunder-proto/.nycrc | 13 - node_modules/dunder-proto/CHANGELOG.md | 24 - node_modules/dunder-proto/LICENSE | 21 - node_modules/dunder-proto/README.md | 54 - node_modules/dunder-proto/get.d.ts | 5 - node_modules/dunder-proto/get.js | 30 - node_modules/dunder-proto/package.json | 76 - node_modules/dunder-proto/set.d.ts | 5 - node_modules/dunder-proto/set.js | 35 - node_modules/dunder-proto/test/get.js | 34 - node_modules/dunder-proto/test/index.js | 4 - node_modules/dunder-proto/test/set.js | 50 - node_modules/dunder-proto/tsconfig.json | 9 - node_modules/ee-first/LICENSE | 22 - node_modules/ee-first/README.md | 80 - node_modules/ee-first/index.js | 95 - node_modules/ee-first/package.json | 29 - node_modules/encodeurl/LICENSE | 22 - node_modules/encodeurl/README.md | 109 - node_modules/encodeurl/index.js | 60 - node_modules/encodeurl/package.json | 40 - node_modules/es-define-property/.eslintrc | 13 - .../es-define-property/.github/FUNDING.yml | 12 - node_modules/es-define-property/.nycrc | 9 - node_modules/es-define-property/CHANGELOG.md | 29 - node_modules/es-define-property/LICENSE | 21 - node_modules/es-define-property/README.md | 49 - node_modules/es-define-property/index.d.ts | 3 - node_modules/es-define-property/index.js | 14 - node_modules/es-define-property/package.json | 81 - node_modules/es-define-property/test/index.js | 56 - node_modules/es-define-property/tsconfig.json | 10 - node_modules/es-errors/.eslintrc | 5 - node_modules/es-errors/.github/FUNDING.yml | 12 - node_modules/es-errors/CHANGELOG.md | 40 - node_modules/es-errors/LICENSE | 21 - node_modules/es-errors/README.md | 55 - node_modules/es-errors/eval.d.ts | 3 - node_modules/es-errors/eval.js | 4 - node_modules/es-errors/index.d.ts | 3 - node_modules/es-errors/index.js | 4 - node_modules/es-errors/package.json | 80 - node_modules/es-errors/range.d.ts | 3 - node_modules/es-errors/range.js | 4 - node_modules/es-errors/ref.d.ts | 3 - node_modules/es-errors/ref.js | 4 - node_modules/es-errors/syntax.d.ts | 3 - node_modules/es-errors/syntax.js | 4 - node_modules/es-errors/test/index.js | 19 - node_modules/es-errors/tsconfig.json | 49 - node_modules/es-errors/type.d.ts | 3 - node_modules/es-errors/type.js | 4 - node_modules/es-errors/uri.d.ts | 3 - node_modules/es-errors/uri.js | 4 - node_modules/es-object-atoms/.eslintrc | 16 - .../es-object-atoms/.github/FUNDING.yml | 12 - node_modules/es-object-atoms/CHANGELOG.md | 37 - node_modules/es-object-atoms/LICENSE | 21 - node_modules/es-object-atoms/README.md | 63 - .../RequireObjectCoercible.d.ts | 3 - .../es-object-atoms/RequireObjectCoercible.js | 11 - node_modules/es-object-atoms/ToObject.d.ts | 7 - node_modules/es-object-atoms/ToObject.js | 10 - node_modules/es-object-atoms/index.d.ts | 3 - node_modules/es-object-atoms/index.js | 4 - node_modules/es-object-atoms/isObject.d.ts | 3 - node_modules/es-object-atoms/isObject.js | 6 - node_modules/es-object-atoms/package.json | 80 - node_modules/es-object-atoms/test/index.js | 38 - node_modules/es-object-atoms/tsconfig.json | 6 - node_modules/escape-html/LICENSE | 24 - node_modules/escape-html/Readme.md | 43 - node_modules/escape-html/index.js | 78 - node_modules/escape-html/package.json | 24 - node_modules/etag/HISTORY.md | 83 - node_modules/etag/LICENSE | 22 - node_modules/etag/README.md | 159 - node_modules/etag/index.js | 131 - node_modules/etag/package.json | 47 - node_modules/express/History.md | 3667 - node_modules/express/LICENSE | 24 - node_modules/express/Readme.md | 260 - node_modules/express/index.js | 11 - node_modules/express/lib/application.js | 661 - node_modules/express/lib/express.js | 116 - node_modules/express/lib/middleware/init.js | 43 - node_modules/express/lib/middleware/query.js | 47 - node_modules/express/lib/request.js | 525 - node_modules/express/lib/response.js | 1179 - node_modules/express/lib/router/index.js | 673 - node_modules/express/lib/router/layer.js | 181 - node_modules/express/lib/router/route.js | 230 - node_modules/express/lib/utils.js | 303 - node_modules/express/lib/view.js | 182 - node_modules/express/package.json | 102 - node_modules/finalhandler/HISTORY.md | 216 - node_modules/finalhandler/LICENSE | 22 - node_modules/finalhandler/README.md | 147 - node_modules/finalhandler/SECURITY.md | 25 - node_modules/finalhandler/index.js | 341 - node_modules/finalhandler/package.json | 47 - node_modules/forwarded/HISTORY.md | 21 - node_modules/forwarded/LICENSE | 22 - node_modules/forwarded/README.md | 57 - node_modules/forwarded/index.js | 90 - node_modules/forwarded/package.json | 45 - node_modules/fresh/HISTORY.md | 70 - node_modules/fresh/LICENSE | 23 - node_modules/fresh/README.md | 119 - node_modules/fresh/index.js | 137 - node_modules/fresh/package.json | 46 - node_modules/function-bind/.eslintrc | 21 - .../function-bind/.github/FUNDING.yml | 12 - .../function-bind/.github/SECURITY.md | 3 - node_modules/function-bind/.nycrc | 13 - node_modules/function-bind/CHANGELOG.md | 136 - node_modules/function-bind/LICENSE | 20 - node_modules/function-bind/README.md | 46 - node_modules/function-bind/implementation.js | 84 - node_modules/function-bind/index.js | 5 - node_modules/function-bind/package.json | 87 - node_modules/function-bind/test/.eslintrc | 9 - node_modules/function-bind/test/index.js | 252 - node_modules/get-intrinsic/.eslintrc | 42 - .../get-intrinsic/.github/FUNDING.yml | 12 - node_modules/get-intrinsic/.nycrc | 9 - node_modules/get-intrinsic/CHANGELOG.md | 186 - node_modules/get-intrinsic/LICENSE | 21 - node_modules/get-intrinsic/README.md | 71 - node_modules/get-intrinsic/index.js | 378 - node_modules/get-intrinsic/package.json | 97 - .../get-intrinsic/test/GetIntrinsic.js | 274 - node_modules/get-proto/.eslintrc | 10 - node_modules/get-proto/.github/FUNDING.yml | 12 - node_modules/get-proto/.nycrc | 9 - node_modules/get-proto/CHANGELOG.md | 21 - node_modules/get-proto/LICENSE | 21 - .../get-proto/Object.getPrototypeOf.d.ts | 5 - .../get-proto/Object.getPrototypeOf.js | 6 - node_modules/get-proto/README.md | 50 - .../get-proto/Reflect.getPrototypeOf.d.ts | 3 - .../get-proto/Reflect.getPrototypeOf.js | 4 - node_modules/get-proto/index.d.ts | 5 - node_modules/get-proto/index.js | 27 - node_modules/get-proto/package.json | 81 - node_modules/get-proto/test/index.js | 68 - node_modules/get-proto/tsconfig.json | 9 - node_modules/gopd/.eslintrc | 16 - node_modules/gopd/.github/FUNDING.yml | 12 - node_modules/gopd/CHANGELOG.md | 45 - node_modules/gopd/LICENSE | 21 - node_modules/gopd/README.md | 40 - node_modules/gopd/gOPD.d.ts | 1 - node_modules/gopd/gOPD.js | 4 - node_modules/gopd/index.d.ts | 5 - node_modules/gopd/index.js | 15 - node_modules/gopd/package.json | 77 - node_modules/gopd/test/index.js | 36 - node_modules/gopd/tsconfig.json | 9 - node_modules/has-symbols/.eslintrc | 11 - node_modules/has-symbols/.github/FUNDING.yml | 12 - node_modules/has-symbols/.nycrc | 9 - node_modules/has-symbols/CHANGELOG.md | 91 - node_modules/has-symbols/LICENSE | 21 - node_modules/has-symbols/README.md | 46 - node_modules/has-symbols/index.d.ts | 3 - node_modules/has-symbols/index.js | 14 - node_modules/has-symbols/package.json | 111 - node_modules/has-symbols/shams.d.ts | 3 - node_modules/has-symbols/shams.js | 45 - node_modules/has-symbols/test/index.js | 22 - .../has-symbols/test/shams/core-js.js | 29 - .../test/shams/get-own-property-symbols.js | 29 - node_modules/has-symbols/test/tests.js | 58 - node_modules/has-symbols/tsconfig.json | 10 - node_modules/hasown/.github/FUNDING.yml | 12 - node_modules/hasown/.nycrc | 13 - node_modules/hasown/CHANGELOG.md | 51 - node_modules/hasown/LICENSE | 21 - node_modules/hasown/README.md | 40 - node_modules/hasown/eslint.config.mjs | 6 - node_modules/hasown/index.d.ts | 4 - node_modules/hasown/index.js | 8 - node_modules/hasown/package.json | 92 - node_modules/hasown/tsconfig.json | 6 - node_modules/http-errors/HISTORY.md | 186 - node_modules/http-errors/LICENSE | 23 - node_modules/http-errors/README.md | 169 - node_modules/http-errors/index.js | 290 - node_modules/http-errors/package.json | 54 - node_modules/iconv-lite/Changelog.md | 162 - node_modules/iconv-lite/LICENSE | 21 - node_modules/iconv-lite/README.md | 156 - .../iconv-lite/encodings/dbcs-codec.js | 555 - .../iconv-lite/encodings/dbcs-data.js | 176 - node_modules/iconv-lite/encodings/index.js | 22 - node_modules/iconv-lite/encodings/internal.js | 188 - .../iconv-lite/encodings/sbcs-codec.js | 72 - .../encodings/sbcs-data-generated.js | 451 - .../iconv-lite/encodings/sbcs-data.js | 174 - .../encodings/tables/big5-added.json | 122 - .../iconv-lite/encodings/tables/cp936.json | 264 - .../iconv-lite/encodings/tables/cp949.json | 273 - .../iconv-lite/encodings/tables/cp950.json | 177 - .../iconv-lite/encodings/tables/eucjp.json | 182 - .../encodings/tables/gb18030-ranges.json | 1 - .../encodings/tables/gbk-added.json | 55 - .../iconv-lite/encodings/tables/shiftjis.json | 125 - node_modules/iconv-lite/encodings/utf16.js | 177 - node_modules/iconv-lite/encodings/utf7.js | 290 - node_modules/iconv-lite/lib/bom-handling.js | 52 - node_modules/iconv-lite/lib/extend-node.js | 217 - node_modules/iconv-lite/lib/index.d.ts | 24 - node_modules/iconv-lite/lib/index.js | 153 - node_modules/iconv-lite/lib/streams.js | 121 - node_modules/iconv-lite/package.json | 46 - node_modules/immutable/LICENSE | 21 - node_modules/immutable/README.md | 731 - node_modules/immutable/dist/immutable.d.ts | 5126 - node_modules/immutable/dist/immutable.es.js | 6201 - node_modules/immutable/dist/immutable.js | 6255 - node_modules/immutable/dist/immutable.js.flow | 2414 - node_modules/immutable/dist/immutable.min.js | 25 - node_modules/immutable/package.json | 38 - node_modules/inherits/LICENSE | 16 - node_modules/inherits/README.md | 42 - node_modules/inherits/inherits.js | 9 - node_modules/inherits/inherits_browser.js | 27 - node_modules/inherits/package.json | 29 - node_modules/ipaddr.js/LICENSE | 19 - node_modules/ipaddr.js/README.md | 233 - node_modules/ipaddr.js/ipaddr.min.js | 1 - node_modules/ipaddr.js/lib/ipaddr.js | 673 - node_modules/ipaddr.js/lib/ipaddr.js.d.ts | 68 - node_modules/ipaddr.js/package.json | 35 - node_modules/is-extglob/LICENSE | 21 - node_modules/is-extglob/README.md | 107 - node_modules/is-extglob/index.js | 20 - node_modules/is-extglob/package.json | 69 - node_modules/is-glob/LICENSE | 21 - node_modules/is-glob/README.md | 206 - node_modules/is-glob/index.js | 150 - node_modules/is-glob/package.json | 81 - node_modules/math-intrinsics/.eslintrc | 16 - .../math-intrinsics/.github/FUNDING.yml | 12 - node_modules/math-intrinsics/CHANGELOG.md | 24 - node_modules/math-intrinsics/LICENSE | 21 - node_modules/math-intrinsics/README.md | 50 - node_modules/math-intrinsics/abs.d.ts | 1 - node_modules/math-intrinsics/abs.js | 4 - .../constants/maxArrayLength.d.ts | 3 - .../constants/maxArrayLength.js | 4 - .../constants/maxSafeInteger.d.ts | 3 - .../constants/maxSafeInteger.js | 5 - .../math-intrinsics/constants/maxValue.d.ts | 3 - .../math-intrinsics/constants/maxValue.js | 5 - node_modules/math-intrinsics/floor.d.ts | 1 - node_modules/math-intrinsics/floor.js | 4 - node_modules/math-intrinsics/isFinite.d.ts | 3 - node_modules/math-intrinsics/isFinite.js | 12 - node_modules/math-intrinsics/isInteger.d.ts | 3 - node_modules/math-intrinsics/isInteger.js | 16 - node_modules/math-intrinsics/isNaN.d.ts | 1 - node_modules/math-intrinsics/isNaN.js | 6 - .../math-intrinsics/isNegativeZero.d.ts | 3 - .../math-intrinsics/isNegativeZero.js | 6 - node_modules/math-intrinsics/max.d.ts | 1 - node_modules/math-intrinsics/max.js | 4 - node_modules/math-intrinsics/min.d.ts | 1 - node_modules/math-intrinsics/min.js | 4 - node_modules/math-intrinsics/mod.d.ts | 3 - node_modules/math-intrinsics/mod.js | 9 - node_modules/math-intrinsics/package.json | 86 - node_modules/math-intrinsics/pow.d.ts | 1 - node_modules/math-intrinsics/pow.js | 4 - node_modules/math-intrinsics/round.d.ts | 1 - node_modules/math-intrinsics/round.js | 4 - node_modules/math-intrinsics/sign.d.ts | 3 - node_modules/math-intrinsics/sign.js | 11 - node_modules/math-intrinsics/test/index.js | 192 - node_modules/math-intrinsics/tsconfig.json | 3 - node_modules/media-typer/HISTORY.md | 22 - node_modules/media-typer/LICENSE | 22 - node_modules/media-typer/README.md | 81 - node_modules/media-typer/index.js | 270 - node_modules/media-typer/package.json | 26 - node_modules/merge-descriptors/HISTORY.md | 21 - node_modules/merge-descriptors/LICENSE | 23 - node_modules/merge-descriptors/README.md | 49 - node_modules/merge-descriptors/index.js | 60 - node_modules/merge-descriptors/package.json | 39 - node_modules/methods/HISTORY.md | 29 - node_modules/methods/LICENSE | 24 - node_modules/methods/README.md | 51 - node_modules/methods/index.js | 69 - node_modules/methods/package.json | 36 - node_modules/mime-db/HISTORY.md | 507 - node_modules/mime-db/LICENSE | 23 - node_modules/mime-db/README.md | 100 - node_modules/mime-db/db.json | 8519 - node_modules/mime-db/index.js | 12 - node_modules/mime-db/package.json | 60 - node_modules/mime-types/HISTORY.md | 397 - node_modules/mime-types/LICENSE | 23 - node_modules/mime-types/README.md | 113 - node_modules/mime-types/index.js | 188 - node_modules/mime-types/package.json | 44 - node_modules/mime/.npmignore | 0 node_modules/mime/CHANGELOG.md | 164 - node_modules/mime/LICENSE | 21 - node_modules/mime/README.md | 90 - node_modules/mime/cli.js | 8 - node_modules/mime/mime.js | 108 - node_modules/mime/package.json | 44 - node_modules/mime/src/build.js | 53 - node_modules/mime/src/test.js | 60 - node_modules/mime/types.json | 1 - node_modules/ms/index.js | 152 - node_modules/ms/license.md | 21 - node_modules/ms/package.json | 37 - node_modules/ms/readme.md | 51 - node_modules/negotiator/HISTORY.md | 108 - node_modules/negotiator/LICENSE | 24 - node_modules/negotiator/README.md | 203 - node_modules/negotiator/index.js | 82 - node_modules/negotiator/lib/charset.js | 169 - node_modules/negotiator/lib/encoding.js | 184 - node_modules/negotiator/lib/language.js | 179 - node_modules/negotiator/lib/mediaType.js | 294 - node_modules/negotiator/package.json | 42 - node_modules/node-addon-api/LICENSE.md | 9 - node_modules/node-addon-api/README.md | 319 - node_modules/node-addon-api/common.gypi | 20 - node_modules/node-addon-api/except.gypi | 25 - node_modules/node-addon-api/index.js | 12 - .../node-addon-api/napi-inl.deprecated.h | 186 - node_modules/node-addon-api/napi-inl.h | 6607 - node_modules/node-addon-api/napi.h | 3201 - .../node-addon-api/node_addon_api.gyp | 32 - node_modules/node-addon-api/node_api.gyp | 9 - node_modules/node-addon-api/noexcept.gypi | 26 - node_modules/node-addon-api/nothing.c | 0 .../node-addon-api/package-support.json | 21 - node_modules/node-addon-api/package.json | 480 - node_modules/node-addon-api/tools/README.md | 73 - .../node-addon-api/tools/check-napi.js | 99 - .../node-addon-api/tools/clang-format.js | 71 - .../node-addon-api/tools/conversion.js | 301 - .../node-addon-api/tools/eslint-format.js | 79 - node_modules/object-inspect/.eslintrc | 53 - .../object-inspect/.github/FUNDING.yml | 12 - node_modules/object-inspect/.nycrc | 13 - node_modules/object-inspect/CHANGELOG.md | 424 - node_modules/object-inspect/LICENSE | 21 - node_modules/object-inspect/example/all.js | 23 - .../object-inspect/example/circular.js | 6 - node_modules/object-inspect/example/fn.js | 5 - .../object-inspect/example/inspect.js | 10 - node_modules/object-inspect/index.js | 544 - .../object-inspect/package-support.json | 20 - node_modules/object-inspect/package.json | 105 - node_modules/object-inspect/readme.markdown | 84 - node_modules/object-inspect/test-core-js.js | 26 - node_modules/object-inspect/test/bigint.js | 58 - .../object-inspect/test/browser/dom.js | 15 - node_modules/object-inspect/test/circular.js | 16 - node_modules/object-inspect/test/deep.js | 12 - node_modules/object-inspect/test/element.js | 53 - node_modules/object-inspect/test/err.js | 48 - node_modules/object-inspect/test/fakes.js | 29 - node_modules/object-inspect/test/fn.js | 76 - node_modules/object-inspect/test/global.js | 17 - node_modules/object-inspect/test/has.js | 15 - node_modules/object-inspect/test/holes.js | 15 - .../object-inspect/test/indent-option.js | 271 - node_modules/object-inspect/test/inspect.js | 139 - node_modules/object-inspect/test/lowbyte.js | 12 - node_modules/object-inspect/test/number.js | 58 - .../object-inspect/test/quoteStyle.js | 26 - .../object-inspect/test/toStringTag.js | 40 - node_modules/object-inspect/test/undef.js | 12 - node_modules/object-inspect/test/values.js | 261 - node_modules/object-inspect/util.inspect.js | 1 - node_modules/on-finished/HISTORY.md | 98 - node_modules/on-finished/LICENSE | 23 - node_modules/on-finished/README.md | 162 - node_modules/on-finished/index.js | 234 - node_modules/on-finished/package.json | 39 - node_modules/parseurl/HISTORY.md | 58 - node_modules/parseurl/LICENSE | 24 - node_modules/parseurl/README.md | 133 - node_modules/parseurl/index.js | 158 - node_modules/parseurl/package.json | 40 - node_modules/path-to-regexp/LICENSE | 21 - node_modules/path-to-regexp/Readme.md | 35 - node_modules/path-to-regexp/index.js | 158 - node_modules/path-to-regexp/package.json | 30 - node_modules/picomatch/LICENSE | 21 - node_modules/picomatch/README.md | 749 - node_modules/picomatch/index.js | 17 - node_modules/picomatch/lib/constants.js | 184 - node_modules/picomatch/lib/parse.js | 1386 - node_modules/picomatch/lib/picomatch.js | 349 - node_modules/picomatch/lib/scan.js | 391 - node_modules/picomatch/lib/utils.js | 72 - node_modules/picomatch/package.json | 82 - node_modules/picomatch/posix.js | 3 - node_modules/proxy-addr/HISTORY.md | 161 - node_modules/proxy-addr/LICENSE | 22 - node_modules/proxy-addr/README.md | 139 - node_modules/proxy-addr/index.js | 327 - node_modules/proxy-addr/package.json | 47 - node_modules/qs/.editorconfig | 46 - node_modules/qs/.github/FUNDING.yml | 12 - node_modules/qs/.github/SECURITY.md | 11 - node_modules/qs/.github/THREAT_MODEL.md | 78 - node_modules/qs/.nycrc | 13 - node_modules/qs/CHANGELOG.md | 644 - node_modules/qs/LICENSE.md | 29 - node_modules/qs/README.md | 740 - node_modules/qs/dist/qs.js | 141 - node_modules/qs/eslint.config.mjs | 56 - node_modules/qs/lib/formats.js | 23 - node_modules/qs/lib/index.js | 11 - node_modules/qs/lib/parse.js | 371 - node_modules/qs/lib/stringify.js | 356 - node_modules/qs/lib/utils.js | 340 - node_modules/qs/package.json | 94 - node_modules/qs/test/empty-keys-cases.js | 267 - node_modules/qs/test/parse.js | 1512 - node_modules/qs/test/stringify.js | 1310 - node_modules/qs/test/utils.js | 397 - node_modules/range-parser/HISTORY.md | 56 - node_modules/range-parser/LICENSE | 23 - node_modules/range-parser/README.md | 84 - node_modules/range-parser/index.js | 162 - node_modules/range-parser/package.json | 44 - node_modules/raw-body/LICENSE | 22 - node_modules/raw-body/README.md | 223 - node_modules/raw-body/index.d.ts | 87 - node_modules/raw-body/index.js | 336 - node_modules/raw-body/package.json | 47 - node_modules/readdirp/LICENSE | 21 - node_modules/readdirp/README.md | 120 - node_modules/readdirp/esm/index.d.ts | 108 - node_modules/readdirp/esm/index.js | 257 - node_modules/readdirp/esm/package.json | 1 - node_modules/readdirp/index.d.ts | 108 - node_modules/readdirp/index.js | 263 - node_modules/readdirp/package.json | 70 - node_modules/safe-buffer/LICENSE | 21 - node_modules/safe-buffer/README.md | 584 - node_modules/safe-buffer/index.d.ts | 187 - node_modules/safe-buffer/index.js | 65 - node_modules/safe-buffer/package.json | 51 - node_modules/safer-buffer/LICENSE | 21 - node_modules/safer-buffer/Porting-Buffer.md | 268 - node_modules/safer-buffer/Readme.md | 156 - node_modules/safer-buffer/dangerous.js | 58 - node_modules/safer-buffer/package.json | 34 - node_modules/safer-buffer/safer.js | 77 - node_modules/safer-buffer/tests.js | 406 - node_modules/sass/LICENSE | 1720 - node_modules/sass/README.md | 173 - node_modules/sass/package.json | 1 - node_modules/sass/sass.dart.js | 133104 --------------- node_modules/sass/sass.default.cjs | 8 - node_modules/sass/sass.default.js | 48 - node_modules/sass/sass.js | 18 - node_modules/sass/sass.node.js | 12 - node_modules/sass/sass.node.mjs | 214 - node_modules/sass/types/compile.d.ts | 342 - node_modules/sass/types/deprecations.d.ts | 305 - node_modules/sass/types/exception.d.ts | 41 - node_modules/sass/types/importer.d.ts | 471 - node_modules/sass/types/index.d.ts | 122 - node_modules/sass/types/legacy/exception.d.ts | 55 - node_modules/sass/types/legacy/function.d.ts | 757 - node_modules/sass/types/legacy/importer.d.ts | 169 - node_modules/sass/types/legacy/options.d.ts | 700 - .../sass/types/legacy/plugin_this.d.ts | 74 - node_modules/sass/types/legacy/render.d.ts | 144 - node_modules/sass/types/logger/index.d.ts | 115 - .../sass/types/logger/source_location.d.ts | 21 - .../sass/types/logger/source_span.d.ts | 34 - node_modules/sass/types/options.d.ts | 468 - node_modules/sass/types/util/promise_or.d.ts | 17 - .../sass/types/value/argument_list.d.ts | 47 - node_modules/sass/types/value/boolean.d.ts | 29 - .../sass/types/value/calculation.d.ts | 137 - node_modules/sass/types/value/color.d.ts | 567 - node_modules/sass/types/value/function.d.ts | 22 - node_modules/sass/types/value/index.d.ts | 219 - node_modules/sass/types/value/list.d.ts | 54 - node_modules/sass/types/value/map.d.ts | 41 - node_modules/sass/types/value/mixin.d.ts | 14 - node_modules/sass/types/value/number.d.ts | 305 - node_modules/sass/types/value/string.d.ts | 84 - node_modules/send/HISTORY.md | 538 - node_modules/send/LICENSE | 23 - node_modules/send/README.md | 327 - node_modules/send/SECURITY.md | 24 - node_modules/send/index.js | 1142 - node_modules/send/node_modules/ms/index.js | 162 - node_modules/send/node_modules/ms/license.md | 21 - .../send/node_modules/ms/package.json | 38 - node_modules/send/node_modules/ms/readme.md | 59 - node_modules/send/package.json | 62 - node_modules/serve-static/HISTORY.md | 493 - node_modules/serve-static/LICENSE | 25 - node_modules/serve-static/README.md | 257 - node_modules/serve-static/index.js | 209 - node_modules/serve-static/package.json | 42 - node_modules/setprototypeof/LICENSE | 13 - node_modules/setprototypeof/README.md | 31 - node_modules/setprototypeof/index.d.ts | 2 - node_modules/setprototypeof/index.js | 17 - node_modules/setprototypeof/package.json | 38 - node_modules/setprototypeof/test/index.js | 24 - node_modules/side-channel-list/.editorconfig | 9 - node_modules/side-channel-list/.eslintrc | 11 - .../side-channel-list/.github/FUNDING.yml | 12 - node_modules/side-channel-list/.nycrc | 13 - node_modules/side-channel-list/CHANGELOG.md | 36 - node_modules/side-channel-list/LICENSE | 21 - node_modules/side-channel-list/README.md | 62 - node_modules/side-channel-list/index.d.ts | 13 - node_modules/side-channel-list/index.js | 111 - node_modules/side-channel-list/list.d.ts | 14 - node_modules/side-channel-list/package.json | 77 - node_modules/side-channel-list/test/index.js | 154 - node_modules/side-channel-list/tsconfig.json | 9 - node_modules/side-channel-map/.editorconfig | 9 - node_modules/side-channel-map/.eslintrc | 11 - .../side-channel-map/.github/FUNDING.yml | 12 - node_modules/side-channel-map/.nycrc | 13 - node_modules/side-channel-map/CHANGELOG.md | 22 - node_modules/side-channel-map/LICENSE | 21 - node_modules/side-channel-map/README.md | 62 - node_modules/side-channel-map/index.d.ts | 15 - node_modules/side-channel-map/index.js | 68 - node_modules/side-channel-map/package.json | 80 - node_modules/side-channel-map/test/index.js | 114 - node_modules/side-channel-map/tsconfig.json | 9 - .../side-channel-weakmap/.editorconfig | 9 - node_modules/side-channel-weakmap/.eslintrc | 12 - .../side-channel-weakmap/.github/FUNDING.yml | 12 - node_modules/side-channel-weakmap/.nycrc | 13 - .../side-channel-weakmap/CHANGELOG.md | 28 - node_modules/side-channel-weakmap/LICENSE | 21 - node_modules/side-channel-weakmap/README.md | 62 - node_modules/side-channel-weakmap/index.d.ts | 15 - node_modules/side-channel-weakmap/index.js | 84 - .../side-channel-weakmap/package.json | 87 - .../side-channel-weakmap/test/index.js | 114 - .../side-channel-weakmap/tsconfig.json | 9 - node_modules/side-channel/.editorconfig | 9 - node_modules/side-channel/.eslintrc | 12 - node_modules/side-channel/.github/FUNDING.yml | 12 - node_modules/side-channel/.nycrc | 13 - node_modules/side-channel/CHANGELOG.md | 110 - node_modules/side-channel/LICENSE | 21 - node_modules/side-channel/README.md | 61 - node_modules/side-channel/index.d.ts | 14 - node_modules/side-channel/index.js | 43 - node_modules/side-channel/package.json | 85 - node_modules/side-channel/test/index.js | 104 - node_modules/side-channel/tsconfig.json | 9 - node_modules/source-map-js/LICENSE | 28 - node_modules/source-map-js/README.md | 765 - node_modules/source-map-js/lib/array-set.js | 121 - node_modules/source-map-js/lib/base64-vlq.js | 140 - node_modules/source-map-js/lib/base64.js | 67 - .../source-map-js/lib/binary-search.js | 111 - .../source-map-js/lib/mapping-list.js | 79 - node_modules/source-map-js/lib/quick-sort.js | 132 - .../lib/source-map-consumer.d.ts | 1 - .../source-map-js/lib/source-map-consumer.js | 1188 - .../lib/source-map-generator.d.ts | 1 - .../source-map-js/lib/source-map-generator.js | 444 - .../source-map-js/lib/source-node.d.ts | 1 - node_modules/source-map-js/lib/source-node.js | 413 - node_modules/source-map-js/lib/util.js | 594 - node_modules/source-map-js/package.json | 71 - node_modules/source-map-js/source-map.d.ts | 104 - node_modules/source-map-js/source-map.js | 8 - node_modules/statuses/HISTORY.md | 87 - node_modules/statuses/LICENSE | 23 - node_modules/statuses/README.md | 139 - node_modules/statuses/codes.json | 65 - node_modules/statuses/index.js | 146 - node_modules/statuses/package.json | 49 - node_modules/toidentifier/HISTORY.md | 9 - node_modules/toidentifier/LICENSE | 21 - node_modules/toidentifier/README.md | 61 - node_modules/toidentifier/index.js | 32 - node_modules/toidentifier/package.json | 38 - node_modules/type-is/HISTORY.md | 259 - node_modules/type-is/LICENSE | 23 - node_modules/type-is/README.md | 170 - node_modules/type-is/index.js | 266 - node_modules/type-is/package.json | 45 - node_modules/unpipe/HISTORY.md | 4 - node_modules/unpipe/LICENSE | 22 - node_modules/unpipe/README.md | 43 - node_modules/unpipe/index.js | 69 - node_modules/unpipe/package.json | 27 - node_modules/utils-merge/.npmignore | 9 - node_modules/utils-merge/LICENSE | 20 - node_modules/utils-merge/README.md | 34 - node_modules/utils-merge/index.js | 23 - node_modules/utils-merge/package.json | 40 - node_modules/vary/HISTORY.md | 39 - node_modules/vary/LICENSE | 22 - node_modules/vary/README.md | 101 - node_modules/vary/index.js | 149 - node_modules/vary/package.json | 43 - public/.DS_Store | Bin 8196 -> 0 bytes 설문 세트.xlsx | Bin 10181 -> 0 bytes 820 files changed, 6 insertions(+), 265633 deletions(-) delete mode 100644 .DS_Store create mode 100644 .gitignore delete mode 100644 data/responses.csv delete mode 100644 data/responses.json create mode 100644 mise.toml delete mode 120000 node_modules/.bin/mime delete mode 120000 node_modules/.bin/sass delete mode 100644 node_modules/.package-lock.json delete mode 100644 node_modules/@parcel/watcher-darwin-arm64/LICENSE delete mode 100644 node_modules/@parcel/watcher-darwin-arm64/README.md delete mode 100644 node_modules/@parcel/watcher-darwin-arm64/package.json delete mode 100644 node_modules/@parcel/watcher-darwin-arm64/watcher.node delete mode 100644 node_modules/@parcel/watcher/LICENSE delete mode 100644 node_modules/@parcel/watcher/README.md delete mode 100644 node_modules/@parcel/watcher/binding.gyp delete mode 100644 node_modules/@parcel/watcher/index.d.ts delete mode 100644 node_modules/@parcel/watcher/index.js delete mode 100644 node_modules/@parcel/watcher/index.js.flow delete mode 100644 node_modules/@parcel/watcher/package.json delete mode 100644 node_modules/@parcel/watcher/scripts/build-from-source.js delete mode 100644 node_modules/@parcel/watcher/src/Backend.cc delete mode 100644 node_modules/@parcel/watcher/src/Backend.hh delete mode 100644 node_modules/@parcel/watcher/src/Debounce.cc delete mode 100644 node_modules/@parcel/watcher/src/Debounce.hh delete mode 100644 node_modules/@parcel/watcher/src/DirTree.cc delete mode 100644 node_modules/@parcel/watcher/src/DirTree.hh delete mode 100644 node_modules/@parcel/watcher/src/Event.hh delete mode 100644 node_modules/@parcel/watcher/src/Glob.cc delete mode 100644 node_modules/@parcel/watcher/src/Glob.hh delete mode 100644 node_modules/@parcel/watcher/src/PromiseRunner.hh delete mode 100644 node_modules/@parcel/watcher/src/Signal.hh delete mode 100644 node_modules/@parcel/watcher/src/Watcher.cc delete mode 100644 node_modules/@parcel/watcher/src/Watcher.hh delete mode 100644 node_modules/@parcel/watcher/src/binding.cc delete mode 100644 node_modules/@parcel/watcher/src/kqueue/KqueueBackend.cc delete mode 100644 node_modules/@parcel/watcher/src/kqueue/KqueueBackend.hh delete mode 100644 node_modules/@parcel/watcher/src/linux/InotifyBackend.cc delete mode 100644 node_modules/@parcel/watcher/src/linux/InotifyBackend.hh delete mode 100644 node_modules/@parcel/watcher/src/macos/FSEventsBackend.cc delete mode 100644 node_modules/@parcel/watcher/src/macos/FSEventsBackend.hh delete mode 100644 node_modules/@parcel/watcher/src/shared/BruteForceBackend.cc delete mode 100644 node_modules/@parcel/watcher/src/shared/BruteForceBackend.hh delete mode 100644 node_modules/@parcel/watcher/src/unix/fts.cc delete mode 100644 node_modules/@parcel/watcher/src/unix/legacy.cc delete mode 100644 node_modules/@parcel/watcher/src/wasm/WasmBackend.cc delete mode 100644 node_modules/@parcel/watcher/src/wasm/WasmBackend.hh delete mode 100644 node_modules/@parcel/watcher/src/wasm/include.h delete mode 100644 node_modules/@parcel/watcher/src/watchman/BSER.cc delete mode 100644 node_modules/@parcel/watcher/src/watchman/BSER.hh delete mode 100644 node_modules/@parcel/watcher/src/watchman/IPC.hh delete mode 100644 node_modules/@parcel/watcher/src/watchman/WatchmanBackend.cc delete mode 100644 node_modules/@parcel/watcher/src/watchman/WatchmanBackend.hh delete mode 100644 node_modules/@parcel/watcher/src/windows/WindowsBackend.cc delete mode 100644 node_modules/@parcel/watcher/src/windows/WindowsBackend.hh delete mode 100644 node_modules/@parcel/watcher/src/windows/win_utils.cc delete mode 100644 node_modules/@parcel/watcher/src/windows/win_utils.hh delete mode 100644 node_modules/@parcel/watcher/wrapper.js delete mode 100644 node_modules/accepts/HISTORY.md delete mode 100644 node_modules/accepts/LICENSE delete mode 100644 node_modules/accepts/README.md delete mode 100644 node_modules/accepts/index.js delete mode 100644 node_modules/accepts/package.json delete mode 100644 node_modules/array-flatten/LICENSE delete mode 100644 node_modules/array-flatten/README.md delete mode 100644 node_modules/array-flatten/array-flatten.js delete mode 100644 node_modules/array-flatten/package.json delete mode 100644 node_modules/body-parser/HISTORY.md delete mode 100644 node_modules/body-parser/LICENSE delete mode 100644 node_modules/body-parser/README.md delete mode 100644 node_modules/body-parser/index.js delete mode 100644 node_modules/body-parser/lib/read.js delete mode 100644 node_modules/body-parser/lib/types/json.js delete mode 100644 node_modules/body-parser/lib/types/raw.js delete mode 100644 node_modules/body-parser/lib/types/text.js delete mode 100644 node_modules/body-parser/lib/types/urlencoded.js delete mode 100644 node_modules/body-parser/node_modules/qs/.editorconfig delete mode 100644 node_modules/body-parser/node_modules/qs/.github/FUNDING.yml delete mode 100644 node_modules/body-parser/node_modules/qs/.github/SECURITY.md delete mode 100644 node_modules/body-parser/node_modules/qs/.github/THREAT_MODEL.md delete mode 100644 node_modules/body-parser/node_modules/qs/.nycrc delete mode 100644 node_modules/body-parser/node_modules/qs/CHANGELOG.md delete mode 100644 node_modules/body-parser/node_modules/qs/LICENSE.md delete mode 100644 node_modules/body-parser/node_modules/qs/README.md delete mode 100644 node_modules/body-parser/node_modules/qs/dist/qs.js delete mode 100644 node_modules/body-parser/node_modules/qs/eslint.config.mjs delete mode 100644 node_modules/body-parser/node_modules/qs/lib/formats.js delete mode 100644 node_modules/body-parser/node_modules/qs/lib/index.js delete mode 100644 node_modules/body-parser/node_modules/qs/lib/parse.js delete mode 100644 node_modules/body-parser/node_modules/qs/lib/stringify.js delete mode 100644 node_modules/body-parser/node_modules/qs/lib/utils.js delete mode 100644 node_modules/body-parser/node_modules/qs/package.json delete mode 100644 node_modules/body-parser/node_modules/qs/test/empty-keys-cases.js delete mode 100644 node_modules/body-parser/node_modules/qs/test/parse.js delete mode 100644 node_modules/body-parser/node_modules/qs/test/stringify.js delete mode 100644 node_modules/body-parser/node_modules/qs/test/utils.js delete mode 100644 node_modules/body-parser/package.json delete mode 100644 node_modules/bytes/History.md delete mode 100644 node_modules/bytes/LICENSE delete mode 100644 node_modules/bytes/Readme.md delete mode 100644 node_modules/bytes/index.js delete mode 100644 node_modules/bytes/package.json delete mode 100644 node_modules/call-bind-apply-helpers/.eslintrc delete mode 100644 node_modules/call-bind-apply-helpers/.github/FUNDING.yml delete mode 100644 node_modules/call-bind-apply-helpers/.nycrc delete mode 100644 node_modules/call-bind-apply-helpers/CHANGELOG.md delete mode 100644 node_modules/call-bind-apply-helpers/LICENSE delete mode 100644 node_modules/call-bind-apply-helpers/README.md delete mode 100644 node_modules/call-bind-apply-helpers/actualApply.d.ts delete mode 100644 node_modules/call-bind-apply-helpers/actualApply.js delete mode 100644 node_modules/call-bind-apply-helpers/applyBind.d.ts delete mode 100644 node_modules/call-bind-apply-helpers/applyBind.js delete mode 100644 node_modules/call-bind-apply-helpers/functionApply.d.ts delete mode 100644 node_modules/call-bind-apply-helpers/functionApply.js delete mode 100644 node_modules/call-bind-apply-helpers/functionCall.d.ts delete mode 100644 node_modules/call-bind-apply-helpers/functionCall.js delete mode 100644 node_modules/call-bind-apply-helpers/index.d.ts delete mode 100644 node_modules/call-bind-apply-helpers/index.js delete mode 100644 node_modules/call-bind-apply-helpers/package.json delete mode 100644 node_modules/call-bind-apply-helpers/reflectApply.d.ts delete mode 100644 node_modules/call-bind-apply-helpers/reflectApply.js delete mode 100644 node_modules/call-bind-apply-helpers/test/index.js delete mode 100644 node_modules/call-bind-apply-helpers/tsconfig.json delete mode 100644 node_modules/call-bound/.eslintrc delete mode 100644 node_modules/call-bound/.github/FUNDING.yml delete mode 100644 node_modules/call-bound/.nycrc delete mode 100644 node_modules/call-bound/CHANGELOG.md delete mode 100644 node_modules/call-bound/LICENSE delete mode 100644 node_modules/call-bound/README.md delete mode 100644 node_modules/call-bound/index.d.ts delete mode 100644 node_modules/call-bound/index.js delete mode 100644 node_modules/call-bound/package.json delete mode 100644 node_modules/call-bound/test/index.js delete mode 100644 node_modules/call-bound/tsconfig.json delete mode 100644 node_modules/chokidar/LICENSE delete mode 100644 node_modules/chokidar/README.md delete mode 100644 node_modules/chokidar/esm/handler.d.ts delete mode 100644 node_modules/chokidar/esm/handler.js delete mode 100644 node_modules/chokidar/esm/index.d.ts delete mode 100644 node_modules/chokidar/esm/index.js delete mode 100644 node_modules/chokidar/esm/package.json delete mode 100644 node_modules/chokidar/handler.d.ts delete mode 100644 node_modules/chokidar/handler.js delete mode 100644 node_modules/chokidar/index.d.ts delete mode 100644 node_modules/chokidar/index.js delete mode 100644 node_modules/chokidar/package.json delete mode 100644 node_modules/content-disposition/HISTORY.md delete mode 100644 node_modules/content-disposition/LICENSE delete mode 100644 node_modules/content-disposition/README.md delete mode 100644 node_modules/content-disposition/index.js delete mode 100644 node_modules/content-disposition/package.json delete mode 100644 node_modules/content-type/HISTORY.md delete mode 100644 node_modules/content-type/LICENSE delete mode 100644 node_modules/content-type/README.md delete mode 100644 node_modules/content-type/index.js delete mode 100644 node_modules/content-type/package.json delete mode 100644 node_modules/cookie-signature/History.md delete mode 100644 node_modules/cookie-signature/Readme.md delete mode 100644 node_modules/cookie-signature/index.js delete mode 100644 node_modules/cookie-signature/package.json delete mode 100644 node_modules/cookie/LICENSE delete mode 100644 node_modules/cookie/README.md delete mode 100644 node_modules/cookie/SECURITY.md delete mode 100644 node_modules/cookie/index.js delete mode 100644 node_modules/cookie/package.json delete mode 100644 node_modules/debug/.coveralls.yml delete mode 100644 node_modules/debug/.eslintrc delete mode 100644 node_modules/debug/.npmignore delete mode 100644 node_modules/debug/.travis.yml delete mode 100644 node_modules/debug/CHANGELOG.md delete mode 100644 node_modules/debug/LICENSE delete mode 100644 node_modules/debug/Makefile delete mode 100644 node_modules/debug/README.md delete mode 100644 node_modules/debug/component.json delete mode 100644 node_modules/debug/karma.conf.js delete mode 100644 node_modules/debug/node.js delete mode 100644 node_modules/debug/package.json delete mode 100644 node_modules/debug/src/browser.js delete mode 100644 node_modules/debug/src/debug.js delete mode 100644 node_modules/debug/src/index.js delete mode 100644 node_modules/debug/src/inspector-log.js delete mode 100644 node_modules/debug/src/node.js delete mode 100644 node_modules/depd/History.md delete mode 100644 node_modules/depd/LICENSE delete mode 100644 node_modules/depd/Readme.md delete mode 100644 node_modules/depd/index.js delete mode 100644 node_modules/depd/lib/browser/index.js delete mode 100644 node_modules/depd/package.json delete mode 100644 node_modules/destroy/LICENSE delete mode 100644 node_modules/destroy/README.md delete mode 100644 node_modules/destroy/index.js delete mode 100644 node_modules/destroy/package.json delete mode 100644 node_modules/detect-libc/LICENSE delete mode 100644 node_modules/detect-libc/README.md delete mode 100644 node_modules/detect-libc/index.d.ts delete mode 100644 node_modules/detect-libc/lib/detect-libc.js delete mode 100644 node_modules/detect-libc/lib/elf.js delete mode 100644 node_modules/detect-libc/lib/filesystem.js delete mode 100644 node_modules/detect-libc/lib/process.js delete mode 100644 node_modules/detect-libc/package.json delete mode 100644 node_modules/dunder-proto/.eslintrc delete mode 100644 node_modules/dunder-proto/.github/FUNDING.yml delete mode 100644 node_modules/dunder-proto/.nycrc delete mode 100644 node_modules/dunder-proto/CHANGELOG.md delete mode 100644 node_modules/dunder-proto/LICENSE delete mode 100644 node_modules/dunder-proto/README.md delete mode 100644 node_modules/dunder-proto/get.d.ts delete mode 100644 node_modules/dunder-proto/get.js delete mode 100644 node_modules/dunder-proto/package.json delete mode 100644 node_modules/dunder-proto/set.d.ts delete mode 100644 node_modules/dunder-proto/set.js delete mode 100644 node_modules/dunder-proto/test/get.js delete mode 100644 node_modules/dunder-proto/test/index.js delete mode 100644 node_modules/dunder-proto/test/set.js delete mode 100644 node_modules/dunder-proto/tsconfig.json delete mode 100644 node_modules/ee-first/LICENSE delete mode 100644 node_modules/ee-first/README.md delete mode 100644 node_modules/ee-first/index.js delete mode 100644 node_modules/ee-first/package.json delete mode 100644 node_modules/encodeurl/LICENSE delete mode 100644 node_modules/encodeurl/README.md delete mode 100644 node_modules/encodeurl/index.js delete mode 100644 node_modules/encodeurl/package.json delete mode 100644 node_modules/es-define-property/.eslintrc delete mode 100644 node_modules/es-define-property/.github/FUNDING.yml delete mode 100644 node_modules/es-define-property/.nycrc delete mode 100644 node_modules/es-define-property/CHANGELOG.md delete mode 100644 node_modules/es-define-property/LICENSE delete mode 100644 node_modules/es-define-property/README.md delete mode 100644 node_modules/es-define-property/index.d.ts delete mode 100644 node_modules/es-define-property/index.js delete mode 100644 node_modules/es-define-property/package.json delete mode 100644 node_modules/es-define-property/test/index.js delete mode 100644 node_modules/es-define-property/tsconfig.json delete mode 100644 node_modules/es-errors/.eslintrc delete mode 100644 node_modules/es-errors/.github/FUNDING.yml delete mode 100644 node_modules/es-errors/CHANGELOG.md delete mode 100644 node_modules/es-errors/LICENSE delete mode 100644 node_modules/es-errors/README.md delete mode 100644 node_modules/es-errors/eval.d.ts delete mode 100644 node_modules/es-errors/eval.js delete mode 100644 node_modules/es-errors/index.d.ts delete mode 100644 node_modules/es-errors/index.js delete mode 100644 node_modules/es-errors/package.json delete mode 100644 node_modules/es-errors/range.d.ts delete mode 100644 node_modules/es-errors/range.js delete mode 100644 node_modules/es-errors/ref.d.ts delete mode 100644 node_modules/es-errors/ref.js delete mode 100644 node_modules/es-errors/syntax.d.ts delete mode 100644 node_modules/es-errors/syntax.js delete mode 100644 node_modules/es-errors/test/index.js delete mode 100644 node_modules/es-errors/tsconfig.json delete mode 100644 node_modules/es-errors/type.d.ts delete mode 100644 node_modules/es-errors/type.js delete mode 100644 node_modules/es-errors/uri.d.ts delete mode 100644 node_modules/es-errors/uri.js delete mode 100644 node_modules/es-object-atoms/.eslintrc delete mode 100644 node_modules/es-object-atoms/.github/FUNDING.yml delete mode 100644 node_modules/es-object-atoms/CHANGELOG.md delete mode 100644 node_modules/es-object-atoms/LICENSE delete mode 100644 node_modules/es-object-atoms/README.md delete mode 100644 node_modules/es-object-atoms/RequireObjectCoercible.d.ts delete mode 100644 node_modules/es-object-atoms/RequireObjectCoercible.js delete mode 100644 node_modules/es-object-atoms/ToObject.d.ts delete mode 100644 node_modules/es-object-atoms/ToObject.js delete mode 100644 node_modules/es-object-atoms/index.d.ts delete mode 100644 node_modules/es-object-atoms/index.js delete mode 100644 node_modules/es-object-atoms/isObject.d.ts delete mode 100644 node_modules/es-object-atoms/isObject.js delete mode 100644 node_modules/es-object-atoms/package.json delete mode 100644 node_modules/es-object-atoms/test/index.js delete mode 100644 node_modules/es-object-atoms/tsconfig.json delete mode 100644 node_modules/escape-html/LICENSE delete mode 100644 node_modules/escape-html/Readme.md delete mode 100644 node_modules/escape-html/index.js delete mode 100644 node_modules/escape-html/package.json delete mode 100644 node_modules/etag/HISTORY.md delete mode 100644 node_modules/etag/LICENSE delete mode 100644 node_modules/etag/README.md delete mode 100644 node_modules/etag/index.js delete mode 100644 node_modules/etag/package.json delete mode 100644 node_modules/express/History.md delete mode 100644 node_modules/express/LICENSE delete mode 100644 node_modules/express/Readme.md delete mode 100644 node_modules/express/index.js delete mode 100644 node_modules/express/lib/application.js delete mode 100644 node_modules/express/lib/express.js delete mode 100644 node_modules/express/lib/middleware/init.js delete mode 100644 node_modules/express/lib/middleware/query.js delete mode 100644 node_modules/express/lib/request.js delete mode 100644 node_modules/express/lib/response.js delete mode 100644 node_modules/express/lib/router/index.js delete mode 100644 node_modules/express/lib/router/layer.js delete mode 100644 node_modules/express/lib/router/route.js delete mode 100644 node_modules/express/lib/utils.js delete mode 100644 node_modules/express/lib/view.js delete mode 100644 node_modules/express/package.json delete mode 100644 node_modules/finalhandler/HISTORY.md delete mode 100644 node_modules/finalhandler/LICENSE delete mode 100644 node_modules/finalhandler/README.md delete mode 100644 node_modules/finalhandler/SECURITY.md delete mode 100644 node_modules/finalhandler/index.js delete mode 100644 node_modules/finalhandler/package.json delete mode 100644 node_modules/forwarded/HISTORY.md delete mode 100644 node_modules/forwarded/LICENSE delete mode 100644 node_modules/forwarded/README.md delete mode 100644 node_modules/forwarded/index.js delete mode 100644 node_modules/forwarded/package.json delete mode 100644 node_modules/fresh/HISTORY.md delete mode 100644 node_modules/fresh/LICENSE delete mode 100644 node_modules/fresh/README.md delete mode 100644 node_modules/fresh/index.js delete mode 100644 node_modules/fresh/package.json delete mode 100644 node_modules/function-bind/.eslintrc delete mode 100644 node_modules/function-bind/.github/FUNDING.yml delete mode 100644 node_modules/function-bind/.github/SECURITY.md delete mode 100644 node_modules/function-bind/.nycrc delete mode 100644 node_modules/function-bind/CHANGELOG.md delete mode 100644 node_modules/function-bind/LICENSE delete mode 100644 node_modules/function-bind/README.md delete mode 100644 node_modules/function-bind/implementation.js delete mode 100644 node_modules/function-bind/index.js delete mode 100644 node_modules/function-bind/package.json delete mode 100644 node_modules/function-bind/test/.eslintrc delete mode 100644 node_modules/function-bind/test/index.js delete mode 100644 node_modules/get-intrinsic/.eslintrc delete mode 100644 node_modules/get-intrinsic/.github/FUNDING.yml delete mode 100644 node_modules/get-intrinsic/.nycrc delete mode 100644 node_modules/get-intrinsic/CHANGELOG.md delete mode 100644 node_modules/get-intrinsic/LICENSE delete mode 100644 node_modules/get-intrinsic/README.md delete mode 100644 node_modules/get-intrinsic/index.js delete mode 100644 node_modules/get-intrinsic/package.json delete mode 100644 node_modules/get-intrinsic/test/GetIntrinsic.js delete mode 100644 node_modules/get-proto/.eslintrc delete mode 100644 node_modules/get-proto/.github/FUNDING.yml delete mode 100644 node_modules/get-proto/.nycrc delete mode 100644 node_modules/get-proto/CHANGELOG.md delete mode 100644 node_modules/get-proto/LICENSE delete mode 100644 node_modules/get-proto/Object.getPrototypeOf.d.ts delete mode 100644 node_modules/get-proto/Object.getPrototypeOf.js delete mode 100644 node_modules/get-proto/README.md delete mode 100644 node_modules/get-proto/Reflect.getPrototypeOf.d.ts delete mode 100644 node_modules/get-proto/Reflect.getPrototypeOf.js delete mode 100644 node_modules/get-proto/index.d.ts delete mode 100644 node_modules/get-proto/index.js delete mode 100644 node_modules/get-proto/package.json delete mode 100644 node_modules/get-proto/test/index.js delete mode 100644 node_modules/get-proto/tsconfig.json delete mode 100644 node_modules/gopd/.eslintrc delete mode 100644 node_modules/gopd/.github/FUNDING.yml delete mode 100644 node_modules/gopd/CHANGELOG.md delete mode 100644 node_modules/gopd/LICENSE delete mode 100644 node_modules/gopd/README.md delete mode 100644 node_modules/gopd/gOPD.d.ts delete mode 100644 node_modules/gopd/gOPD.js delete mode 100644 node_modules/gopd/index.d.ts delete mode 100644 node_modules/gopd/index.js delete mode 100644 node_modules/gopd/package.json delete mode 100644 node_modules/gopd/test/index.js delete mode 100644 node_modules/gopd/tsconfig.json delete mode 100644 node_modules/has-symbols/.eslintrc delete mode 100644 node_modules/has-symbols/.github/FUNDING.yml delete mode 100644 node_modules/has-symbols/.nycrc delete mode 100644 node_modules/has-symbols/CHANGELOG.md delete mode 100644 node_modules/has-symbols/LICENSE delete mode 100644 node_modules/has-symbols/README.md delete mode 100644 node_modules/has-symbols/index.d.ts delete mode 100644 node_modules/has-symbols/index.js delete mode 100644 node_modules/has-symbols/package.json delete mode 100644 node_modules/has-symbols/shams.d.ts delete mode 100644 node_modules/has-symbols/shams.js delete mode 100644 node_modules/has-symbols/test/index.js delete mode 100644 node_modules/has-symbols/test/shams/core-js.js delete mode 100644 node_modules/has-symbols/test/shams/get-own-property-symbols.js delete mode 100644 node_modules/has-symbols/test/tests.js delete mode 100644 node_modules/has-symbols/tsconfig.json delete mode 100644 node_modules/hasown/.github/FUNDING.yml delete mode 100644 node_modules/hasown/.nycrc delete mode 100644 node_modules/hasown/CHANGELOG.md delete mode 100644 node_modules/hasown/LICENSE delete mode 100644 node_modules/hasown/README.md delete mode 100644 node_modules/hasown/eslint.config.mjs delete mode 100644 node_modules/hasown/index.d.ts delete mode 100644 node_modules/hasown/index.js delete mode 100644 node_modules/hasown/package.json delete mode 100644 node_modules/hasown/tsconfig.json delete mode 100644 node_modules/http-errors/HISTORY.md delete mode 100644 node_modules/http-errors/LICENSE delete mode 100644 node_modules/http-errors/README.md delete mode 100644 node_modules/http-errors/index.js delete mode 100644 node_modules/http-errors/package.json delete mode 100644 node_modules/iconv-lite/Changelog.md delete mode 100644 node_modules/iconv-lite/LICENSE delete mode 100644 node_modules/iconv-lite/README.md delete mode 100644 node_modules/iconv-lite/encodings/dbcs-codec.js delete mode 100644 node_modules/iconv-lite/encodings/dbcs-data.js delete mode 100644 node_modules/iconv-lite/encodings/index.js delete mode 100644 node_modules/iconv-lite/encodings/internal.js delete mode 100644 node_modules/iconv-lite/encodings/sbcs-codec.js delete mode 100644 node_modules/iconv-lite/encodings/sbcs-data-generated.js delete mode 100644 node_modules/iconv-lite/encodings/sbcs-data.js delete mode 100644 node_modules/iconv-lite/encodings/tables/big5-added.json delete mode 100644 node_modules/iconv-lite/encodings/tables/cp936.json delete mode 100644 node_modules/iconv-lite/encodings/tables/cp949.json delete mode 100644 node_modules/iconv-lite/encodings/tables/cp950.json delete mode 100644 node_modules/iconv-lite/encodings/tables/eucjp.json delete mode 100644 node_modules/iconv-lite/encodings/tables/gb18030-ranges.json delete mode 100644 node_modules/iconv-lite/encodings/tables/gbk-added.json delete mode 100644 node_modules/iconv-lite/encodings/tables/shiftjis.json delete mode 100644 node_modules/iconv-lite/encodings/utf16.js delete mode 100644 node_modules/iconv-lite/encodings/utf7.js delete mode 100644 node_modules/iconv-lite/lib/bom-handling.js delete mode 100644 node_modules/iconv-lite/lib/extend-node.js delete mode 100644 node_modules/iconv-lite/lib/index.d.ts delete mode 100644 node_modules/iconv-lite/lib/index.js delete mode 100644 node_modules/iconv-lite/lib/streams.js delete mode 100644 node_modules/iconv-lite/package.json delete mode 100644 node_modules/immutable/LICENSE delete mode 100644 node_modules/immutable/README.md delete mode 100644 node_modules/immutable/dist/immutable.d.ts delete mode 100644 node_modules/immutable/dist/immutable.es.js delete mode 100644 node_modules/immutable/dist/immutable.js delete mode 100644 node_modules/immutable/dist/immutable.js.flow delete mode 100644 node_modules/immutable/dist/immutable.min.js delete mode 100644 node_modules/immutable/package.json delete mode 100644 node_modules/inherits/LICENSE delete mode 100644 node_modules/inherits/README.md delete mode 100644 node_modules/inherits/inherits.js delete mode 100644 node_modules/inherits/inherits_browser.js delete mode 100644 node_modules/inherits/package.json delete mode 100644 node_modules/ipaddr.js/LICENSE delete mode 100644 node_modules/ipaddr.js/README.md delete mode 100644 node_modules/ipaddr.js/ipaddr.min.js delete mode 100644 node_modules/ipaddr.js/lib/ipaddr.js delete mode 100644 node_modules/ipaddr.js/lib/ipaddr.js.d.ts delete mode 100644 node_modules/ipaddr.js/package.json delete mode 100644 node_modules/is-extglob/LICENSE delete mode 100644 node_modules/is-extglob/README.md delete mode 100644 node_modules/is-extglob/index.js delete mode 100644 node_modules/is-extglob/package.json delete mode 100644 node_modules/is-glob/LICENSE delete mode 100644 node_modules/is-glob/README.md delete mode 100644 node_modules/is-glob/index.js delete mode 100644 node_modules/is-glob/package.json delete mode 100644 node_modules/math-intrinsics/.eslintrc delete mode 100644 node_modules/math-intrinsics/.github/FUNDING.yml delete mode 100644 node_modules/math-intrinsics/CHANGELOG.md delete mode 100644 node_modules/math-intrinsics/LICENSE delete mode 100644 node_modules/math-intrinsics/README.md delete mode 100644 node_modules/math-intrinsics/abs.d.ts delete mode 100644 node_modules/math-intrinsics/abs.js delete mode 100644 node_modules/math-intrinsics/constants/maxArrayLength.d.ts delete mode 100644 node_modules/math-intrinsics/constants/maxArrayLength.js delete mode 100644 node_modules/math-intrinsics/constants/maxSafeInteger.d.ts delete mode 100644 node_modules/math-intrinsics/constants/maxSafeInteger.js delete mode 100644 node_modules/math-intrinsics/constants/maxValue.d.ts delete mode 100644 node_modules/math-intrinsics/constants/maxValue.js delete mode 100644 node_modules/math-intrinsics/floor.d.ts delete mode 100644 node_modules/math-intrinsics/floor.js delete mode 100644 node_modules/math-intrinsics/isFinite.d.ts delete mode 100644 node_modules/math-intrinsics/isFinite.js delete mode 100644 node_modules/math-intrinsics/isInteger.d.ts delete mode 100644 node_modules/math-intrinsics/isInteger.js delete mode 100644 node_modules/math-intrinsics/isNaN.d.ts delete mode 100644 node_modules/math-intrinsics/isNaN.js delete mode 100644 node_modules/math-intrinsics/isNegativeZero.d.ts delete mode 100644 node_modules/math-intrinsics/isNegativeZero.js delete mode 100644 node_modules/math-intrinsics/max.d.ts delete mode 100644 node_modules/math-intrinsics/max.js delete mode 100644 node_modules/math-intrinsics/min.d.ts delete mode 100644 node_modules/math-intrinsics/min.js delete mode 100644 node_modules/math-intrinsics/mod.d.ts delete mode 100644 node_modules/math-intrinsics/mod.js delete mode 100644 node_modules/math-intrinsics/package.json delete mode 100644 node_modules/math-intrinsics/pow.d.ts delete mode 100644 node_modules/math-intrinsics/pow.js delete mode 100644 node_modules/math-intrinsics/round.d.ts delete mode 100644 node_modules/math-intrinsics/round.js delete mode 100644 node_modules/math-intrinsics/sign.d.ts delete mode 100644 node_modules/math-intrinsics/sign.js delete mode 100644 node_modules/math-intrinsics/test/index.js delete mode 100644 node_modules/math-intrinsics/tsconfig.json delete mode 100644 node_modules/media-typer/HISTORY.md delete mode 100644 node_modules/media-typer/LICENSE delete mode 100644 node_modules/media-typer/README.md delete mode 100644 node_modules/media-typer/index.js delete mode 100644 node_modules/media-typer/package.json delete mode 100644 node_modules/merge-descriptors/HISTORY.md delete mode 100644 node_modules/merge-descriptors/LICENSE delete mode 100644 node_modules/merge-descriptors/README.md delete mode 100644 node_modules/merge-descriptors/index.js delete mode 100644 node_modules/merge-descriptors/package.json delete mode 100644 node_modules/methods/HISTORY.md delete mode 100644 node_modules/methods/LICENSE delete mode 100644 node_modules/methods/README.md delete mode 100644 node_modules/methods/index.js delete mode 100644 node_modules/methods/package.json delete mode 100644 node_modules/mime-db/HISTORY.md delete mode 100644 node_modules/mime-db/LICENSE delete mode 100644 node_modules/mime-db/README.md delete mode 100644 node_modules/mime-db/db.json delete mode 100644 node_modules/mime-db/index.js delete mode 100644 node_modules/mime-db/package.json delete mode 100644 node_modules/mime-types/HISTORY.md delete mode 100644 node_modules/mime-types/LICENSE delete mode 100644 node_modules/mime-types/README.md delete mode 100644 node_modules/mime-types/index.js delete mode 100644 node_modules/mime-types/package.json delete mode 100644 node_modules/mime/.npmignore delete mode 100644 node_modules/mime/CHANGELOG.md delete mode 100644 node_modules/mime/LICENSE delete mode 100644 node_modules/mime/README.md delete mode 100755 node_modules/mime/cli.js delete mode 100644 node_modules/mime/mime.js delete mode 100644 node_modules/mime/package.json delete mode 100755 node_modules/mime/src/build.js delete mode 100644 node_modules/mime/src/test.js delete mode 100644 node_modules/mime/types.json delete mode 100644 node_modules/ms/index.js delete mode 100644 node_modules/ms/license.md delete mode 100644 node_modules/ms/package.json delete mode 100644 node_modules/ms/readme.md delete mode 100644 node_modules/negotiator/HISTORY.md delete mode 100644 node_modules/negotiator/LICENSE delete mode 100644 node_modules/negotiator/README.md delete mode 100644 node_modules/negotiator/index.js delete mode 100644 node_modules/negotiator/lib/charset.js delete mode 100644 node_modules/negotiator/lib/encoding.js delete mode 100644 node_modules/negotiator/lib/language.js delete mode 100644 node_modules/negotiator/lib/mediaType.js delete mode 100644 node_modules/negotiator/package.json delete mode 100644 node_modules/node-addon-api/LICENSE.md delete mode 100644 node_modules/node-addon-api/README.md delete mode 100644 node_modules/node-addon-api/common.gypi delete mode 100644 node_modules/node-addon-api/except.gypi delete mode 100644 node_modules/node-addon-api/index.js delete mode 100644 node_modules/node-addon-api/napi-inl.deprecated.h delete mode 100644 node_modules/node-addon-api/napi-inl.h delete mode 100644 node_modules/node-addon-api/napi.h delete mode 100644 node_modules/node-addon-api/node_addon_api.gyp delete mode 100644 node_modules/node-addon-api/node_api.gyp delete mode 100644 node_modules/node-addon-api/noexcept.gypi delete mode 100644 node_modules/node-addon-api/nothing.c delete mode 100644 node_modules/node-addon-api/package-support.json delete mode 100644 node_modules/node-addon-api/package.json delete mode 100644 node_modules/node-addon-api/tools/README.md delete mode 100644 node_modules/node-addon-api/tools/check-napi.js delete mode 100644 node_modules/node-addon-api/tools/clang-format.js delete mode 100755 node_modules/node-addon-api/tools/conversion.js delete mode 100644 node_modules/node-addon-api/tools/eslint-format.js delete mode 100644 node_modules/object-inspect/.eslintrc delete mode 100644 node_modules/object-inspect/.github/FUNDING.yml delete mode 100644 node_modules/object-inspect/.nycrc delete mode 100644 node_modules/object-inspect/CHANGELOG.md delete mode 100644 node_modules/object-inspect/LICENSE delete mode 100644 node_modules/object-inspect/example/all.js delete mode 100644 node_modules/object-inspect/example/circular.js delete mode 100644 node_modules/object-inspect/example/fn.js delete mode 100644 node_modules/object-inspect/example/inspect.js delete mode 100644 node_modules/object-inspect/index.js delete mode 100644 node_modules/object-inspect/package-support.json delete mode 100644 node_modules/object-inspect/package.json delete mode 100644 node_modules/object-inspect/readme.markdown delete mode 100644 node_modules/object-inspect/test-core-js.js delete mode 100644 node_modules/object-inspect/test/bigint.js delete mode 100644 node_modules/object-inspect/test/browser/dom.js delete mode 100644 node_modules/object-inspect/test/circular.js delete mode 100644 node_modules/object-inspect/test/deep.js delete mode 100644 node_modules/object-inspect/test/element.js delete mode 100644 node_modules/object-inspect/test/err.js delete mode 100644 node_modules/object-inspect/test/fakes.js delete mode 100644 node_modules/object-inspect/test/fn.js delete mode 100644 node_modules/object-inspect/test/global.js delete mode 100644 node_modules/object-inspect/test/has.js delete mode 100644 node_modules/object-inspect/test/holes.js delete mode 100644 node_modules/object-inspect/test/indent-option.js delete mode 100644 node_modules/object-inspect/test/inspect.js delete mode 100644 node_modules/object-inspect/test/lowbyte.js delete mode 100644 node_modules/object-inspect/test/number.js delete mode 100644 node_modules/object-inspect/test/quoteStyle.js delete mode 100644 node_modules/object-inspect/test/toStringTag.js delete mode 100644 node_modules/object-inspect/test/undef.js delete mode 100644 node_modules/object-inspect/test/values.js delete mode 100644 node_modules/object-inspect/util.inspect.js delete mode 100644 node_modules/on-finished/HISTORY.md delete mode 100644 node_modules/on-finished/LICENSE delete mode 100644 node_modules/on-finished/README.md delete mode 100644 node_modules/on-finished/index.js delete mode 100644 node_modules/on-finished/package.json delete mode 100644 node_modules/parseurl/HISTORY.md delete mode 100644 node_modules/parseurl/LICENSE delete mode 100644 node_modules/parseurl/README.md delete mode 100644 node_modules/parseurl/index.js delete mode 100644 node_modules/parseurl/package.json delete mode 100644 node_modules/path-to-regexp/LICENSE delete mode 100644 node_modules/path-to-regexp/Readme.md delete mode 100644 node_modules/path-to-regexp/index.js delete mode 100644 node_modules/path-to-regexp/package.json delete mode 100644 node_modules/picomatch/LICENSE delete mode 100644 node_modules/picomatch/README.md delete mode 100644 node_modules/picomatch/index.js delete mode 100644 node_modules/picomatch/lib/constants.js delete mode 100644 node_modules/picomatch/lib/parse.js delete mode 100644 node_modules/picomatch/lib/picomatch.js delete mode 100644 node_modules/picomatch/lib/scan.js delete mode 100644 node_modules/picomatch/lib/utils.js delete mode 100644 node_modules/picomatch/package.json delete mode 100644 node_modules/picomatch/posix.js delete mode 100644 node_modules/proxy-addr/HISTORY.md delete mode 100644 node_modules/proxy-addr/LICENSE delete mode 100644 node_modules/proxy-addr/README.md delete mode 100644 node_modules/proxy-addr/index.js delete mode 100644 node_modules/proxy-addr/package.json delete mode 100644 node_modules/qs/.editorconfig delete mode 100644 node_modules/qs/.github/FUNDING.yml delete mode 100644 node_modules/qs/.github/SECURITY.md delete mode 100644 node_modules/qs/.github/THREAT_MODEL.md delete mode 100644 node_modules/qs/.nycrc delete mode 100644 node_modules/qs/CHANGELOG.md delete mode 100644 node_modules/qs/LICENSE.md delete mode 100644 node_modules/qs/README.md delete mode 100644 node_modules/qs/dist/qs.js delete mode 100644 node_modules/qs/eslint.config.mjs delete mode 100644 node_modules/qs/lib/formats.js delete mode 100644 node_modules/qs/lib/index.js delete mode 100644 node_modules/qs/lib/parse.js delete mode 100644 node_modules/qs/lib/stringify.js delete mode 100644 node_modules/qs/lib/utils.js delete mode 100644 node_modules/qs/package.json delete mode 100644 node_modules/qs/test/empty-keys-cases.js delete mode 100644 node_modules/qs/test/parse.js delete mode 100644 node_modules/qs/test/stringify.js delete mode 100644 node_modules/qs/test/utils.js delete mode 100644 node_modules/range-parser/HISTORY.md delete mode 100644 node_modules/range-parser/LICENSE delete mode 100644 node_modules/range-parser/README.md delete mode 100644 node_modules/range-parser/index.js delete mode 100644 node_modules/range-parser/package.json delete mode 100644 node_modules/raw-body/LICENSE delete mode 100644 node_modules/raw-body/README.md delete mode 100644 node_modules/raw-body/index.d.ts delete mode 100644 node_modules/raw-body/index.js delete mode 100644 node_modules/raw-body/package.json delete mode 100644 node_modules/readdirp/LICENSE delete mode 100644 node_modules/readdirp/README.md delete mode 100644 node_modules/readdirp/esm/index.d.ts delete mode 100644 node_modules/readdirp/esm/index.js delete mode 100644 node_modules/readdirp/esm/package.json delete mode 100644 node_modules/readdirp/index.d.ts delete mode 100644 node_modules/readdirp/index.js delete mode 100644 node_modules/readdirp/package.json delete mode 100644 node_modules/safe-buffer/LICENSE delete mode 100644 node_modules/safe-buffer/README.md delete mode 100644 node_modules/safe-buffer/index.d.ts delete mode 100644 node_modules/safe-buffer/index.js delete mode 100644 node_modules/safe-buffer/package.json delete mode 100644 node_modules/safer-buffer/LICENSE delete mode 100644 node_modules/safer-buffer/Porting-Buffer.md delete mode 100644 node_modules/safer-buffer/Readme.md delete mode 100644 node_modules/safer-buffer/dangerous.js delete mode 100644 node_modules/safer-buffer/package.json delete mode 100644 node_modules/safer-buffer/safer.js delete mode 100644 node_modules/safer-buffer/tests.js delete mode 100644 node_modules/sass/LICENSE delete mode 100644 node_modules/sass/README.md delete mode 100644 node_modules/sass/package.json delete mode 100644 node_modules/sass/sass.dart.js delete mode 100644 node_modules/sass/sass.default.cjs delete mode 100644 node_modules/sass/sass.default.js delete mode 100755 node_modules/sass/sass.js delete mode 100644 node_modules/sass/sass.node.js delete mode 100644 node_modules/sass/sass.node.mjs delete mode 100644 node_modules/sass/types/compile.d.ts delete mode 100644 node_modules/sass/types/deprecations.d.ts delete mode 100644 node_modules/sass/types/exception.d.ts delete mode 100644 node_modules/sass/types/importer.d.ts delete mode 100644 node_modules/sass/types/index.d.ts delete mode 100644 node_modules/sass/types/legacy/exception.d.ts delete mode 100644 node_modules/sass/types/legacy/function.d.ts delete mode 100644 node_modules/sass/types/legacy/importer.d.ts delete mode 100644 node_modules/sass/types/legacy/options.d.ts delete mode 100644 node_modules/sass/types/legacy/plugin_this.d.ts delete mode 100644 node_modules/sass/types/legacy/render.d.ts delete mode 100644 node_modules/sass/types/logger/index.d.ts delete mode 100644 node_modules/sass/types/logger/source_location.d.ts delete mode 100644 node_modules/sass/types/logger/source_span.d.ts delete mode 100644 node_modules/sass/types/options.d.ts delete mode 100644 node_modules/sass/types/util/promise_or.d.ts delete mode 100644 node_modules/sass/types/value/argument_list.d.ts delete mode 100644 node_modules/sass/types/value/boolean.d.ts delete mode 100644 node_modules/sass/types/value/calculation.d.ts delete mode 100644 node_modules/sass/types/value/color.d.ts delete mode 100644 node_modules/sass/types/value/function.d.ts delete mode 100644 node_modules/sass/types/value/index.d.ts delete mode 100644 node_modules/sass/types/value/list.d.ts delete mode 100644 node_modules/sass/types/value/map.d.ts delete mode 100644 node_modules/sass/types/value/mixin.d.ts delete mode 100644 node_modules/sass/types/value/number.d.ts delete mode 100644 node_modules/sass/types/value/string.d.ts delete mode 100644 node_modules/send/HISTORY.md delete mode 100644 node_modules/send/LICENSE delete mode 100644 node_modules/send/README.md delete mode 100644 node_modules/send/SECURITY.md delete mode 100644 node_modules/send/index.js delete mode 100644 node_modules/send/node_modules/ms/index.js delete mode 100644 node_modules/send/node_modules/ms/license.md delete mode 100644 node_modules/send/node_modules/ms/package.json delete mode 100644 node_modules/send/node_modules/ms/readme.md delete mode 100644 node_modules/send/package.json delete mode 100644 node_modules/serve-static/HISTORY.md delete mode 100644 node_modules/serve-static/LICENSE delete mode 100644 node_modules/serve-static/README.md delete mode 100644 node_modules/serve-static/index.js delete mode 100644 node_modules/serve-static/package.json delete mode 100644 node_modules/setprototypeof/LICENSE delete mode 100644 node_modules/setprototypeof/README.md delete mode 100644 node_modules/setprototypeof/index.d.ts delete mode 100644 node_modules/setprototypeof/index.js delete mode 100644 node_modules/setprototypeof/package.json delete mode 100644 node_modules/setprototypeof/test/index.js delete mode 100644 node_modules/side-channel-list/.editorconfig delete mode 100644 node_modules/side-channel-list/.eslintrc delete mode 100644 node_modules/side-channel-list/.github/FUNDING.yml delete mode 100644 node_modules/side-channel-list/.nycrc delete mode 100644 node_modules/side-channel-list/CHANGELOG.md delete mode 100644 node_modules/side-channel-list/LICENSE delete mode 100644 node_modules/side-channel-list/README.md delete mode 100644 node_modules/side-channel-list/index.d.ts delete mode 100644 node_modules/side-channel-list/index.js delete mode 100644 node_modules/side-channel-list/list.d.ts delete mode 100644 node_modules/side-channel-list/package.json delete mode 100644 node_modules/side-channel-list/test/index.js delete mode 100644 node_modules/side-channel-list/tsconfig.json delete mode 100644 node_modules/side-channel-map/.editorconfig delete mode 100644 node_modules/side-channel-map/.eslintrc delete mode 100644 node_modules/side-channel-map/.github/FUNDING.yml delete mode 100644 node_modules/side-channel-map/.nycrc delete mode 100644 node_modules/side-channel-map/CHANGELOG.md delete mode 100644 node_modules/side-channel-map/LICENSE delete mode 100644 node_modules/side-channel-map/README.md delete mode 100644 node_modules/side-channel-map/index.d.ts delete mode 100644 node_modules/side-channel-map/index.js delete mode 100644 node_modules/side-channel-map/package.json delete mode 100644 node_modules/side-channel-map/test/index.js delete mode 100644 node_modules/side-channel-map/tsconfig.json delete mode 100644 node_modules/side-channel-weakmap/.editorconfig delete mode 100644 node_modules/side-channel-weakmap/.eslintrc delete mode 100644 node_modules/side-channel-weakmap/.github/FUNDING.yml delete mode 100644 node_modules/side-channel-weakmap/.nycrc delete mode 100644 node_modules/side-channel-weakmap/CHANGELOG.md delete mode 100644 node_modules/side-channel-weakmap/LICENSE delete mode 100644 node_modules/side-channel-weakmap/README.md delete mode 100644 node_modules/side-channel-weakmap/index.d.ts delete mode 100644 node_modules/side-channel-weakmap/index.js delete mode 100644 node_modules/side-channel-weakmap/package.json delete mode 100644 node_modules/side-channel-weakmap/test/index.js delete mode 100644 node_modules/side-channel-weakmap/tsconfig.json delete mode 100644 node_modules/side-channel/.editorconfig delete mode 100644 node_modules/side-channel/.eslintrc delete mode 100644 node_modules/side-channel/.github/FUNDING.yml delete mode 100644 node_modules/side-channel/.nycrc delete mode 100644 node_modules/side-channel/CHANGELOG.md delete mode 100644 node_modules/side-channel/LICENSE delete mode 100644 node_modules/side-channel/README.md delete mode 100644 node_modules/side-channel/index.d.ts delete mode 100644 node_modules/side-channel/index.js delete mode 100644 node_modules/side-channel/package.json delete mode 100644 node_modules/side-channel/test/index.js delete mode 100644 node_modules/side-channel/tsconfig.json delete mode 100644 node_modules/source-map-js/LICENSE delete mode 100644 node_modules/source-map-js/README.md delete mode 100644 node_modules/source-map-js/lib/array-set.js delete mode 100644 node_modules/source-map-js/lib/base64-vlq.js delete mode 100644 node_modules/source-map-js/lib/base64.js delete mode 100644 node_modules/source-map-js/lib/binary-search.js delete mode 100644 node_modules/source-map-js/lib/mapping-list.js delete mode 100644 node_modules/source-map-js/lib/quick-sort.js delete mode 100644 node_modules/source-map-js/lib/source-map-consumer.d.ts delete mode 100644 node_modules/source-map-js/lib/source-map-consumer.js delete mode 100644 node_modules/source-map-js/lib/source-map-generator.d.ts delete mode 100644 node_modules/source-map-js/lib/source-map-generator.js delete mode 100644 node_modules/source-map-js/lib/source-node.d.ts delete mode 100644 node_modules/source-map-js/lib/source-node.js delete mode 100644 node_modules/source-map-js/lib/util.js delete mode 100644 node_modules/source-map-js/package.json delete mode 100644 node_modules/source-map-js/source-map.d.ts delete mode 100644 node_modules/source-map-js/source-map.js delete mode 100644 node_modules/statuses/HISTORY.md delete mode 100644 node_modules/statuses/LICENSE delete mode 100644 node_modules/statuses/README.md delete mode 100644 node_modules/statuses/codes.json delete mode 100644 node_modules/statuses/index.js delete mode 100644 node_modules/statuses/package.json delete mode 100644 node_modules/toidentifier/HISTORY.md delete mode 100644 node_modules/toidentifier/LICENSE delete mode 100644 node_modules/toidentifier/README.md delete mode 100644 node_modules/toidentifier/index.js delete mode 100644 node_modules/toidentifier/package.json delete mode 100644 node_modules/type-is/HISTORY.md delete mode 100644 node_modules/type-is/LICENSE delete mode 100644 node_modules/type-is/README.md delete mode 100644 node_modules/type-is/index.js delete mode 100644 node_modules/type-is/package.json delete mode 100644 node_modules/unpipe/HISTORY.md delete mode 100644 node_modules/unpipe/LICENSE delete mode 100644 node_modules/unpipe/README.md delete mode 100644 node_modules/unpipe/index.js delete mode 100644 node_modules/unpipe/package.json delete mode 100644 node_modules/utils-merge/.npmignore delete mode 100644 node_modules/utils-merge/LICENSE delete mode 100644 node_modules/utils-merge/README.md delete mode 100644 node_modules/utils-merge/index.js delete mode 100644 node_modules/utils-merge/package.json delete mode 100644 node_modules/vary/HISTORY.md delete mode 100644 node_modules/vary/LICENSE delete mode 100644 node_modules/vary/README.md delete mode 100644 node_modules/vary/index.js delete mode 100644 node_modules/vary/package.json delete mode 100644 public/.DS_Store delete mode 100644 설문 세트.xlsx diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 23101f140e1cac73fdeed2457f95e71fb7cd4a86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}T>S5T3QM#6M_nUW8nFw?08E@dDTfEWtqj5vd)KLS<;?Not3Rp1N5o{e$< diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a714dc2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +node_modules/ +data/ +.vscode diff --git a/data/responses.csv b/data/responses.csv deleted file mode 100644 index a1a99bd..0000000 --- a/data/responses.csv +++ /dev/null @@ -1,2 +0,0 @@ -timestamp,grade,case_1_likert,case_2_likert,case_3_likert,case_4_likert,case_5_likert,case_6_likert,case_7_likert,case_8_likert,case_9_likert,case_10_likert,case_11_likert,case_12_likert,case_13_likert,case_14_likert,case_15_likert,case_1_order,case_2_order,case_3_order,case_4_order,case_5_order,case_6_order,case_7_order,case_8_order,case_9_order,case_10_order,case_11_order,case_12_order,case_13_order,case_14_order,case_15_order,case_1_ms,case_2_ms,case_3_ms,case_4_ms,case_5_ms,case_6_ms,case_7_ms,case_8_ms,case_9_ms,case_10_ms,case_11_ms,case_12_ms,case_13_ms,case_14_ms,case_15_ms,ahp_w_stability,ahp_w_revenue,ahp_w_capital,ahp_w_plan,ahp_w_social,ahp_lambda_max,ahp_CI,ahp_CR,ahp_cr_warning,match_case_1,match_case_2,match_case_3,match_case_4,match_case_5,match_case_6,match_case_7,match_case_8,match_case_9,match_case_10,match_case_11,match_case_12,match_case_13,match_case_14,match_case_15,post_q1,post_q2,post_q3,post_q4,open_response -1778506748375,3학년,5,5,5,5,5,5,4,5,2,5,5,5,5,5,5,4,12,14,8,3,10,2,11,1,15,9,5,6,13,7,781,699,717,1448,1449,767,1533,832,2814,1315,848,818,681,665,733,0.2770,0.1510,0.1906,0.1906,0.1906,5.2453,0.0613,0.0495,0,1,0,1,0,1,1,1,1,0,1,0,1,0,1,0,5,5,5,5, diff --git a/data/responses.json b/data/responses.json deleted file mode 100644 index c82898d..0000000 --- a/data/responses.json +++ /dev/null @@ -1,285 +0,0 @@ -[ - { - "meta": { - "timestamp": 1778506748375, - "grade": "3학년" - }, - "intuitive_judgments": [ - { - "case_id": 9, - "presented_order": 1, - "judgment": 2, - "response_time_ms": 2814 - }, - { - "case_id": 7, - "presented_order": 2, - "judgment": 4, - "response_time_ms": 1533 - }, - { - "case_id": 5, - "presented_order": 3, - "judgment": 5, - "response_time_ms": 1449 - }, - { - "case_id": 1, - "presented_order": 4, - "judgment": 5, - "response_time_ms": 781 - }, - { - "case_id": 12, - "presented_order": 5, - "judgment": 5, - "response_time_ms": 818 - }, - { - "case_id": 13, - "presented_order": 6, - "judgment": 5, - "response_time_ms": 681 - }, - { - "case_id": 15, - "presented_order": 7, - "judgment": 5, - "response_time_ms": 733 - }, - { - "case_id": 4, - "presented_order": 8, - "judgment": 5, - "response_time_ms": 1448 - }, - { - "case_id": 11, - "presented_order": 9, - "judgment": 5, - "response_time_ms": 848 - }, - { - "case_id": 6, - "presented_order": 10, - "judgment": 5, - "response_time_ms": 767 - }, - { - "case_id": 8, - "presented_order": 11, - "judgment": 5, - "response_time_ms": 832 - }, - { - "case_id": 2, - "presented_order": 12, - "judgment": 5, - "response_time_ms": 699 - }, - { - "case_id": 14, - "presented_order": 13, - "judgment": 5, - "response_time_ms": 665 - }, - { - "case_id": 3, - "presented_order": 14, - "judgment": 5, - "response_time_ms": 717 - }, - { - "case_id": 10, - "presented_order": 15, - "judgment": 5, - "response_time_ms": 1315 - } - ], - "ahp": { - "pairwise_raw": [ - 4, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1 - ], - "weights": [ - 0.27702821819618745, - 0.15103495945577752, - 0.190645607449345, - 0.190645607449345, - 0.190645607449345 - ], - "lambda_max": 5.245333922288061, - "CI": 0.06133348057201515, - "CR": 0.04946248433227029, - "cr_warning_shown": false - }, - "comparison": [ - { - "case_id": 9, - "team": "A", - "type": "spike", - "model_score": 57.1, - "model_judgment": "select", - "intuitive_likert": 2, - "intuitive_category": "reject", - "match": false - }, - { - "case_id": 7, - "team": "B", - "type": "spike", - "model_score": 56, - "model_judgment": "select", - "intuitive_likert": 4, - "intuitive_category": "select", - "match": true - }, - { - "case_id": 5, - "team": "C", - "type": "spike", - "model_score": 51.1, - "model_judgment": "select", - "intuitive_likert": 5, - "intuitive_category": "select", - "match": true - }, - { - "case_id": 1, - "team": "D", - "type": "baseline", - "model_score": 84, - "model_judgment": "select", - "intuitive_likert": 5, - "intuitive_category": "select", - "match": true - }, - { - "case_id": 12, - "team": "E", - "type": "conflict", - "model_score": 74.2, - "model_judgment": "select", - "intuitive_likert": 5, - "intuitive_category": "select", - "match": true - }, - { - "case_id": 13, - "team": "F", - "type": "conflict", - "model_score": 42.1, - "model_judgment": "reject", - "intuitive_likert": 5, - "intuitive_category": "select", - "match": false - }, - { - "case_id": 15, - "team": "G", - "type": "conflict", - "model_score": 49.7, - "model_judgment": "reject", - "intuitive_likert": 5, - "intuitive_category": "select", - "match": false - }, - { - "case_id": 4, - "team": "H", - "type": "baseline", - "model_score": 35.8, - "model_judgment": "reject", - "intuitive_likert": 5, - "intuitive_category": "select", - "match": false - }, - { - "case_id": 11, - "team": "I", - "type": "conflict", - "model_score": 35.3, - "model_judgment": "reject", - "intuitive_likert": 5, - "intuitive_category": "select", - "match": false - }, - { - "case_id": 6, - "team": "J", - "type": "spike", - "model_score": 73.1, - "model_judgment": "select", - "intuitive_likert": 5, - "intuitive_category": "select", - "match": true - }, - { - "case_id": 8, - "team": "K", - "type": "spike", - "model_score": 72.9, - "model_judgment": "select", - "intuitive_likert": 5, - "intuitive_category": "select", - "match": true - }, - { - "case_id": 2, - "team": "L", - "type": "baseline", - "model_score": 19.7, - "model_judgment": "reject", - "intuitive_likert": 5, - "intuitive_category": "select", - "match": false - }, - { - "case_id": 14, - "team": "M", - "type": "conflict", - "model_score": 76.9, - "model_judgment": "select", - "intuitive_likert": 5, - "intuitive_category": "select", - "match": true - }, - { - "case_id": 3, - "team": "N", - "type": "baseline", - "model_score": 68, - "model_judgment": "select", - "intuitive_likert": 5, - "intuitive_category": "select", - "match": true - }, - { - "case_id": 10, - "team": "O", - "type": "conflict", - "model_score": 52.1, - "model_judgment": "select", - "intuitive_likert": 5, - "intuitive_category": "select", - "match": true - } - ], - "post_survey": { - "q1": 5, - "q2": 5, - "q3": 5, - "q4": 5, - "open_response": "" - }, - "server_timestamp": 1778506789232 - } -] \ No newline at end of file diff --git a/mise.toml b/mise.toml new file mode 100644 index 0000000..6ea5a7e --- /dev/null +++ b/mise.toml @@ -0,0 +1,2 @@ +[tools] +node = "24" diff --git a/node_modules/.bin/mime b/node_modules/.bin/mime deleted file mode 120000 index fbb7ee0..0000000 --- a/node_modules/.bin/mime +++ /dev/null @@ -1 +0,0 @@ -../mime/cli.js \ No newline at end of file diff --git a/node_modules/.bin/sass b/node_modules/.bin/sass deleted file mode 120000 index 4bda500..0000000 --- a/node_modules/.bin/sass +++ /dev/null @@ -1 +0,0 @@ -../sass/sass.js \ No newline at end of file diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json deleted file mode 100644 index efb508c..0000000 --- a/node_modules/.package-lock.json +++ /dev/null @@ -1,1007 +0,0 @@ -{ - "name": "startup-survey", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "node_modules/@parcel/watcher": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", - "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "dependencies": { - "detect-libc": "^2.0.3", - "is-glob": "^4.0.3", - "node-addon-api": "^7.0.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.6", - "@parcel/watcher-darwin-arm64": "2.5.6", - "@parcel/watcher-darwin-x64": "2.5.6", - "@parcel/watcher-freebsd-x64": "2.5.6", - "@parcel/watcher-linux-arm-glibc": "2.5.6", - "@parcel/watcher-linux-arm-musl": "2.5.6", - "@parcel/watcher-linux-arm64-glibc": "2.5.6", - "@parcel/watcher-linux-arm64-musl": "2.5.6", - "@parcel/watcher-linux-x64-glibc": "2.5.6", - "@parcel/watcher-linux-x64-musl": "2.5.6", - "@parcel/watcher-win32-arm64": "2.5.6", - "@parcel/watcher-win32-ia32": "2.5.6", - "@parcel/watcher-win32-x64": "2.5.6" - } - }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz", - "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "license": "MIT" - }, - "node_modules/body-parser": { - "version": "1.20.5", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz", - "integrity": "sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==", - "license": "MIT", - "dependencies": { - "bytes": "~3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "~1.2.0", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "on-finished": "~2.4.1", - "qs": "~6.15.1", - "raw-body": "~2.5.3", - "type-is": "~1.6.18", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.15.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", - "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", - "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", - "license": "MIT" - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "license": "MIT" - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", - "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "~1.20.3", - "content-disposition": "~0.5.4", - "content-type": "~1.0.4", - "cookie": "~0.7.1", - "cookie-signature": "~1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.3.1", - "fresh": "~0.5.2", - "http-errors": "~2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "~2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "~0.1.12", - "proxy-addr": "~2.0.7", - "qs": "~6.14.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "~0.19.0", - "serve-static": "~1.16.2", - "setprototypeof": "1.2.0", - "statuses": "~2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/finalhandler": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", - "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "~2.4.1", - "parseurl": "~1.3.3", - "statuses": "~2.0.2", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.3.tgz", - "integrity": "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "license": "MIT", - "dependencies": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/immutable": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz", - "integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==", - "license": "MIT" - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "license": "MIT", - "optional": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "license": "MIT", - "optional": true - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", - "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==", - "license": "MIT" - }, - "node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/qs": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", - "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", - "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", - "license": "MIT", - "dependencies": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", - "license": "MIT", - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/sass": { - "version": "1.99.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.99.0.tgz", - "integrity": "sha512-kgW13M54DUB7IsIRM5LvJkNlpH+WhMpooUcaWGFARkF1Tc82v9mIWkCbCYf+MBvpIUBSeSOTilpZjEPr2VYE6Q==", - "license": "MIT", - "dependencies": { - "chokidar": "^4.0.0", - "immutable": "^5.1.5", - "source-map-js": ">=0.6.2 <2.0.0" - }, - "bin": { - "sass": "sass.js" - }, - "engines": { - "node": ">=14.0.0" - }, - "optionalDependencies": { - "@parcel/watcher": "^2.4.1" - } - }, - "node_modules/send": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", - "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "~0.5.2", - "http-errors": "~2.0.1", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "~2.4.1", - "range-parser": "~1.2.1", - "statuses": "~2.0.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/serve-static": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", - "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", - "license": "MIT", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "~0.19.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC" - }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", - "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - } - } -} diff --git a/node_modules/@parcel/watcher-darwin-arm64/LICENSE b/node_modules/@parcel/watcher-darwin-arm64/LICENSE deleted file mode 100644 index 7fb9bc9..0000000 --- a/node_modules/@parcel/watcher-darwin-arm64/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017-present Devon Govett - -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. diff --git a/node_modules/@parcel/watcher-darwin-arm64/README.md b/node_modules/@parcel/watcher-darwin-arm64/README.md deleted file mode 100644 index d426ec6..0000000 --- a/node_modules/@parcel/watcher-darwin-arm64/README.md +++ /dev/null @@ -1 +0,0 @@ -This is the darwin-arm64 build of @parcel/watcher. See https://github.com/parcel-bundler/watcher for details. \ No newline at end of file diff --git a/node_modules/@parcel/watcher-darwin-arm64/package.json b/node_modules/@parcel/watcher-darwin-arm64/package.json deleted file mode 100644 index 7e107c3..0000000 --- a/node_modules/@parcel/watcher-darwin-arm64/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "@parcel/watcher-darwin-arm64", - "version": "2.5.6", - "main": "watcher.node", - "repository": { - "type": "git", - "url": "https://github.com/parcel-bundler/watcher.git" - }, - "description": "A native C++ Node module for querying and subscribing to filesystem events. Used by Parcel 2.", - "license": "MIT", - "publishConfig": { - "access": "public" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "files": [ - "watcher.node" - ], - "engines": { - "node": ">= 10.0.0" - }, - "os": [ - "darwin" - ], - "cpu": [ - "arm64" - ] -} diff --git a/node_modules/@parcel/watcher-darwin-arm64/watcher.node b/node_modules/@parcel/watcher-darwin-arm64/watcher.node deleted file mode 100644 index 6004afd0b4cd0a496b84fedf2cd33878818d288e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 326112 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

7pC|87UUZt@k{EUceX+1L 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 { - console.log(events); -}); - -// later on... -await subscription.unsubscribe(); - -// Get events since some saved snapshot in the past -let snapshotPath = path.join(process.cwd(), 'snapshot.txt'); -let events = await watcher.getEventsSince(process.cwd(), snapshotPath); - -// Save a snapshot for later -await watcher.writeSnapshot(process.cwd(), snapshotPath); -``` - -## Watching - -`@parcel/watcher` supports subscribing to realtime notifications of changes in a directory. It works recursively, so changes in sub-directories will also be emitted. - -Events are throttled and coalesced for performance during large changes like `git checkout` or `npm install`, and a single notification will be emitted with all of the events at the end. - -Only one notification will be emitted per file. For example, if a file was both created and updated since the last event, you'll get only a `create` event. If a file is both created and deleted, you will not be notifed of that file. Renames cause two events: a `delete` for the old name, and a `create` for the new name. - -```javascript -let subscription = await watcher.subscribe(process.cwd(), (err, events) => { - console.log(events); -}); -``` - -Events have two properties: - -- `type` - the event type: `create`, `update`, or `delete`. -- `path` - the absolute path to the file or directory. - -To unsubscribe from change notifications, call the `unsubscribe` method on the returned subscription object. - -```javascript -await subscription.unsubscribe(); -``` - -`@parcel/watcher` has the following watcher backends, listed in priority order: - -- [FSEvents](https://developer.apple.com/documentation/coreservices/file_system_events) on macOS -- [Watchman](https://facebook.github.io/watchman/) if installed -- [inotify](http://man7.org/linux/man-pages/man7/inotify.7.html) on Linux -- [ReadDirectoryChangesW](https://msdn.microsoft.com/en-us/library/windows/desktop/aa365465%28v%3Dvs.85%29.aspx) on Windows -- [kqueue](https://man.freebsd.org/cgi/man.cgi?kqueue) on FreeBSD, or as an alternative to FSEvents on macOS - -You can specify the exact backend you wish to use by passing the `backend` option. If that backend is not available on the current platform, the default backend will be used instead. See below for the list of backend names that can be passed to the options. - -## Querying - -`@parcel/watcher` also supports querying for historical changes made in a directory, even when your program is not running. This makes it easy to invalidate a cache and re-build only the files that have changed, for example. It can be **significantly** faster than traversing the entire filesystem to determine what files changed, depending on the platform. - -In order to query for historical changes, you first need a previous snapshot to compare to. This can be saved to a file with the `writeSnapshot` function, e.g. just before your program exits. - -```javascript -await watcher.writeSnapshot(dirPath, snapshotPath); -``` - -When your program starts up, you can query for changes that have occurred since that snapshot using the `getEventsSince` function. - -```javascript -let events = await watcher.getEventsSince(dirPath, snapshotPath); -``` - -The events returned are exactly the same as the events that would be passed to the `subscribe` callback (see above). - -`@parcel/watcher` has the following watcher backends, listed in priority order: - -- [FSEvents](https://developer.apple.com/documentation/coreservices/file_system_events) on macOS -- [Watchman](https://facebook.github.io/watchman/) if installed -- [fts](http://man7.org/linux/man-pages/man3/fts.3.html) (brute force) on Linux and FreeBSD -- [FindFirstFile](https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-findfirstfilea) (brute force) on Windows - -The FSEvents (macOS) and Watchman backends are significantly more performant than the brute force backends used by default on Linux and Windows, for example returning results in miliseconds instead of seconds for large directory trees. This is because a background daemon monitoring filesystem changes on those platforms allows us to query cached data rather than traversing the filesystem manually (brute force). - -macOS has good performance with FSEvents by default. For the best performance on other platforms, install [Watchman](https://facebook.github.io/watchman/) and it will be used by `@parcel/watcher` automatically. - -You can specify the exact backend you wish to use by passing the `backend` option. If that backend is not available on the current platform, the default backend will be used instead. See below for the list of backend names that can be passed to the options. - -## Options - -All of the APIs in `@parcel/watcher` support the following options, which are passed as an object as the last function argument. - -- `ignore` - an array of paths or glob patterns to ignore. uses [`is-glob`](https://github.com/micromatch/is-glob) to distinguish paths from globs. glob patterns are parsed with [`picomatch`](https://github.com/micromatch/picomatch) (see [features](https://github.com/micromatch/picomatch#globbing-features)). - - paths can be relative or absolute and can either be files or directories. No events will be emitted about these files or directories or their children. - - glob patterns match on relative paths from the root that is watched. No events will be emitted for matching paths. -- `backend` - the name of an explicitly chosen backend to use. Allowed options are `"fs-events"`, `"watchman"`, `"inotify"`, `"kqueue"`, `"windows"`, or `"brute-force"` (only for querying). If the specified backend is not available on the current platform, the default backend will be used instead. - -## WASM - -The `@parcel/watcher-wasm` package can be used in place of `@parcel/watcher` on unsupported platforms. It relies on the Node `fs` module, so in non-Node environments such as browsers, an `fs` polyfill will be needed. - -**Note**: the WASM implementation is significantly less efficient than the native implementations because it must crawl the file system to watch each directory individually. Use the native `@parcel/watcher` package wherever possible. - -```js -import {subscribe} from '@parcel/watcher-wasm'; - -// Use the module as documented above. -subscribe(/* ... */); -``` - -## Who is using this? - -- [Parcel 2](https://parceljs.org/) -- [VSCode](https://code.visualstudio.com/updates/v1_62#_file-watching-changes) -- [Tailwind CSS Intellisense](https://github.com/tailwindlabs/tailwindcss-intellisense) -- [Gatsby Cloud](https://twitter.com/chatsidhartha/status/1435647412828196867) -- [Nx](https://nx.dev) -- [Nuxt](https://nuxt.com) -- [Meteor](https://github.com/meteor/meteor) - -## License - -MIT diff --git a/node_modules/@parcel/watcher/binding.gyp b/node_modules/@parcel/watcher/binding.gyp deleted file mode 100644 index 3c12d52..0000000 --- a/node_modules/@parcel/watcher/binding.gyp +++ /dev/null @@ -1,109 +0,0 @@ -{ - "targets": [ - { - "target_name": "watcher", - "defines": [ "NAPI_DISABLE_CPP_EXCEPTIONS" ], - "sources": [ "src/binding.cc", "src/Watcher.cc", "src/Backend.cc", "src/DirTree.cc", "src/Glob.cc", "src/Debounce.cc" ], - "include_dirs" : [" unknown; - export interface AsyncSubscription { - unsubscribe(): Promise; - } - export interface Event { - path: FilePath; - type: EventType; - } - export function getEventsSince( - dir: FilePath, - snapshot: FilePath, - opts?: Options - ): Promise; - export function subscribe( - dir: FilePath, - fn: SubscribeCallback, - opts?: Options - ): Promise; - export function unsubscribe( - dir: FilePath, - fn: SubscribeCallback, - opts?: Options - ): Promise; - export function writeSnapshot( - dir: FilePath, - snapshot: FilePath, - opts?: Options - ): Promise; -} - -export = ParcelWatcher; \ No newline at end of file diff --git a/node_modules/@parcel/watcher/index.js b/node_modules/@parcel/watcher/index.js deleted file mode 100644 index 31aba4f..0000000 --- a/node_modules/@parcel/watcher/index.js +++ /dev/null @@ -1,42 +0,0 @@ -const {createWrapper} = require('./wrapper'); - -let name = `@parcel/watcher-${process.platform}-${process.arch}`; -if (process.platform === 'linux') { - const { MUSL, familySync } = require('detect-libc'); - const family = familySync(); - if (family === MUSL) { - name += '-musl'; - } else { - name += '-glibc'; - } -} - -let binding; -try { - binding = require(name); -} catch (err) { - handleError(err); - try { - binding = require('./build/Release/watcher.node'); - } catch (err) { - handleError(err); - try { - binding = require('./build/Debug/watcher.node'); - } catch (err) { - handleError(err); - throw new Error(`No prebuild or local build of @parcel/watcher found. Tried ${name}. Please ensure it is installed (don't use --no-optional when installing with npm). Otherwise it is possible we don't support your platform yet. If this is the case, please report an issue to https://github.com/parcel-bundler/watcher.`); - } - } -} - -function handleError(err) { - if (err?.code !== 'MODULE_NOT_FOUND') { - throw err; - } -} - -const wrapper = createWrapper(binding); -exports.writeSnapshot = wrapper.writeSnapshot; -exports.getEventsSince = wrapper.getEventsSince; -exports.subscribe = wrapper.subscribe; -exports.unsubscribe = wrapper.unsubscribe; diff --git a/node_modules/@parcel/watcher/index.js.flow b/node_modules/@parcel/watcher/index.js.flow deleted file mode 100644 index d75da93..0000000 --- a/node_modules/@parcel/watcher/index.js.flow +++ /dev/null @@ -1,48 +0,0 @@ -// @flow -declare type FilePath = string; -declare type GlobPattern = string; - -export type BackendType = - | 'fs-events' - | 'watchman' - | 'inotify' - | 'windows' - | 'brute-force'; -export type EventType = 'create' | 'update' | 'delete'; -export interface Options { - ignore?: Array, - backend?: BackendType -} -export type SubscribeCallback = ( - err: ?Error, - events: Array -) => mixed; -export interface AsyncSubscription { - unsubscribe(): Promise -} -export interface Event { - path: FilePath, - type: EventType -} -declare module.exports: { - getEventsSince( - dir: FilePath, - snapshot: FilePath, - opts?: Options - ): Promise>, - subscribe( - dir: FilePath, - fn: SubscribeCallback, - opts?: Options - ): Promise, - unsubscribe( - dir: FilePath, - fn: SubscribeCallback, - opts?: Options - ): Promise, - writeSnapshot( - dir: FilePath, - snapshot: FilePath, - opts?: Options - ): Promise -} \ No newline at end of file diff --git a/node_modules/@parcel/watcher/package.json b/node_modules/@parcel/watcher/package.json deleted file mode 100644 index 995149d..0000000 --- a/node_modules/@parcel/watcher/package.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "name": "@parcel/watcher", - "version": "2.5.6", - "main": "index.js", - "types": "index.d.ts", - "repository": { - "type": "git", - "url": "https://github.com/parcel-bundler/watcher.git" - }, - "description": "A native C++ Node module for querying and subscribing to filesystem events. Used by Parcel 2.", - "license": "MIT", - "publishConfig": { - "access": "public" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "files": [ - "index.js", - "index.js.flow", - "index.d.ts", - "wrapper.js", - "package.json", - "README.md", - "LICENSE", - "src", - "scripts/build-from-source.js", - "binding.gyp" - ], - "scripts": { - "prebuild": "prebuildify --napi --strip --tag-libc", - "format": "prettier --write \"./**/*.{js,json,md}\"", - "build": "node-gyp rebuild", - "install": "node scripts/build-from-source.js", - "test": "mocha" - }, - "engines": { - "node": ">= 10.0.0" - }, - "husky": { - "hooks": { - "pre-commit": "lint-staged" - } - }, - "lint-staged": { - "*.{js,json,md}": [ - "prettier --write", - "git add" - ] - }, - "dependencies": { - "detect-libc": "^2.0.3", - "is-glob": "^4.0.3", - "node-addon-api": "^7.0.0", - "picomatch": "^4.0.3" - }, - "devDependencies": { - "esbuild": "^0.19.8", - "fs-extra": "^10.0.0", - "husky": "^7.0.2", - "lint-staged": "^11.1.2", - "mocha": "^9.1.1", - "napi-wasm": "^1.1.0", - "prebuildify": "^6.0.1", - "prettier": "^2.3.2" - }, - "binary": { - "napi_versions": [ - 3 - ] - }, - "optionalDependencies": { - "@parcel/watcher-darwin-x64": "2.5.6", - "@parcel/watcher-darwin-arm64": "2.5.6", - "@parcel/watcher-win32-x64": "2.5.6", - "@parcel/watcher-win32-arm64": "2.5.6", - "@parcel/watcher-win32-ia32": "2.5.6", - "@parcel/watcher-linux-x64-glibc": "2.5.6", - "@parcel/watcher-linux-x64-musl": "2.5.6", - "@parcel/watcher-linux-arm64-glibc": "2.5.6", - "@parcel/watcher-linux-arm64-musl": "2.5.6", - "@parcel/watcher-linux-arm-glibc": "2.5.6", - "@parcel/watcher-linux-arm-musl": "2.5.6", - "@parcel/watcher-android-arm64": "2.5.6", - "@parcel/watcher-freebsd-x64": "2.5.6" - } -} diff --git a/node_modules/@parcel/watcher/scripts/build-from-source.js b/node_modules/@parcel/watcher/scripts/build-from-source.js deleted file mode 100644 index 4602008..0000000 --- a/node_modules/@parcel/watcher/scripts/build-from-source.js +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env node - -const {spawn} = require('child_process'); - -if (process.env.npm_config_build_from_source === 'true') { - build(); -} - -function build() { - spawn('node-gyp', ['rebuild'], { stdio: 'inherit', shell: true }).on('exit', function (code) { - process.exit(code); - }); -} diff --git a/node_modules/@parcel/watcher/src/Backend.cc b/node_modules/@parcel/watcher/src/Backend.cc deleted file mode 100644 index 09a53d5..0000000 --- a/node_modules/@parcel/watcher/src/Backend.cc +++ /dev/null @@ -1,186 +0,0 @@ -#ifdef FS_EVENTS -#include "macos/FSEventsBackend.hh" -#endif -#ifdef WATCHMAN -#include "watchman/WatchmanBackend.hh" -#endif -#ifdef WINDOWS -#include "windows/WindowsBackend.hh" -#endif -#ifdef INOTIFY -#include "linux/InotifyBackend.hh" -#endif -#ifdef KQUEUE -#include "kqueue/KqueueBackend.hh" -#endif -#ifdef __wasm32__ -#include "wasm/WasmBackend.hh" -#endif -#include "shared/BruteForceBackend.hh" - -#include "Backend.hh" -#include - -static std::unordered_map>& getSharedBackends() { - static std::unordered_map>* sharedBackends = - new std::unordered_map>(); - return *sharedBackends; -} - -std::shared_ptr getBackend(std::string backend) { - // Use FSEvents on macOS by default. - // Use watchman by default if available on other platforms. - // Fall back to brute force. - #ifdef FS_EVENTS - if (backend == "fs-events" || backend == "default") { - return std::make_shared(); - } - #endif - #ifdef WATCHMAN - if ((backend == "watchman" || backend == "default") && WatchmanBackend::checkAvailable()) { - return std::make_shared(); - } - #endif - #ifdef WINDOWS - if (backend == "windows" || backend == "default") { - return std::make_shared(); - } - #endif - #ifdef INOTIFY - if (backend == "inotify" || backend == "default") { - return std::make_shared(); - } - #endif - #ifdef KQUEUE - if (backend == "kqueue" || backend == "default") { - return std::make_shared(); - } - #endif - #ifdef __wasm32__ - if (backend == "wasm" || backend == "default") { - return std::make_shared(); - } - #endif - if (backend == "brute-force" || backend == "default") { - return std::make_shared(); - } - - return nullptr; -} - -std::shared_ptr Backend::getShared(std::string backend) { - auto found = getSharedBackends().find(backend); - if (found != getSharedBackends().end()) { - return found->second; - } - - auto result = getBackend(backend); - if (!result) { - return getShared("default"); - } - - result->run(); - getSharedBackends().emplace(backend, result); - return result; -} - -void removeShared(Backend *backend) { - for (auto it = getSharedBackends().begin(); it != getSharedBackends().end(); it++) { - if (it->second.get() == backend) { - getSharedBackends().erase(it); - break; - } - } - - // Free up memory. - if (getSharedBackends().size() == 0) { - getSharedBackends().rehash(0); - } -} - -void Backend::run() { - #ifndef __wasm32__ - mThread = std::thread([this] () { - try { - start(); - } catch (std::exception &err) { - handleError(err); - } - }); - - if (mThread.joinable()) { - mStartedSignal.wait(); - } - #else - try { - start(); - } catch (std::exception &err) { - handleError(err); - } - #endif -} - -void Backend::notifyStarted() { - mStartedSignal.notify(); -} - -void Backend::start() { - notifyStarted(); -} - -Backend::~Backend() { - #ifndef __wasm32__ - // Wait for thread to stop - if (mThread.joinable()) { - // If the backend is being destroyed from the thread itself, detach, otherwise join. - if (mThread.get_id() == std::this_thread::get_id()) { - mThread.detach(); - } else { - mThread.join(); - } - } - #endif -} - -void Backend::watch(WatcherRef watcher) { - std::unique_lock lock(mMutex); - auto res = mSubscriptions.find(watcher); - if (res == mSubscriptions.end()) { - try { - this->subscribe(watcher); - mSubscriptions.insert(watcher); - } catch (std::exception&) { - unref(); - throw; - } - } -} - -void Backend::unwatch(WatcherRef watcher) { - std::unique_lock lock(mMutex); - size_t deleted = mSubscriptions.erase(watcher); - if (deleted > 0) { - this->unsubscribe(watcher); - unref(); - } -} - -void Backend::unref() { - if (mSubscriptions.size() == 0) { - removeShared(this); - } -} - -void Backend::handleWatcherError(WatcherError &err) { - unwatch(err.mWatcher); - err.mWatcher->notifyError(err); -} - -void Backend::handleError(std::exception &err) { - std::unique_lock lock(mMutex); - for (auto it = mSubscriptions.begin(); it != mSubscriptions.end(); it++) { - (*it)->notifyError(err); - } - - removeShared(this); -} diff --git a/node_modules/@parcel/watcher/src/Backend.hh b/node_modules/@parcel/watcher/src/Backend.hh deleted file mode 100644 index d673bd1..0000000 --- a/node_modules/@parcel/watcher/src/Backend.hh +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef BACKEND_H -#define BACKEND_H - -#include "Event.hh" -#include "Watcher.hh" -#include "Signal.hh" -#include - -class Backend { -public: - virtual ~Backend(); - void run(); - void notifyStarted(); - - virtual void start(); - virtual void writeSnapshot(WatcherRef watcher, std::string *snapshotPath) = 0; - virtual void getEventsSince(WatcherRef watcher, std::string *snapshotPath) = 0; - virtual void subscribe(WatcherRef watcher) = 0; - virtual void unsubscribe(WatcherRef watcher) = 0; - - static std::shared_ptr getShared(std::string backend); - - void watch(WatcherRef watcher); - void unwatch(WatcherRef watcher); - void unref(); - void handleWatcherError(WatcherError &err); - - std::mutex mMutex; - std::thread mThread; -private: - std::unordered_set mSubscriptions; - Signal mStartedSignal; - - void handleError(std::exception &err); -}; - -#endif diff --git a/node_modules/@parcel/watcher/src/Debounce.cc b/node_modules/@parcel/watcher/src/Debounce.cc deleted file mode 100644 index be07e78..0000000 --- a/node_modules/@parcel/watcher/src/Debounce.cc +++ /dev/null @@ -1,113 +0,0 @@ -#include "Debounce.hh" - -#ifdef __wasm32__ -extern "C" void on_timeout(void *ctx) { - Debounce *debounce = (Debounce *)ctx; - debounce->notify(); -} -#endif - -std::shared_ptr Debounce::getShared() { - static std::weak_ptr sharedInstance; - std::shared_ptr shared = sharedInstance.lock(); - if (!shared) { - shared = std::make_shared(); - sharedInstance = shared; - } - - return shared; -} - -Debounce::Debounce() { - mRunning = true; - #ifndef __wasm32__ - mThread = std::thread([this] () { - loop(); - }); - #endif -} - -Debounce::~Debounce() { - mRunning = false; - #ifndef __wasm32__ - mWaitSignal.notify(); - mThread.join(); - #endif -} - -void Debounce::add(void *key, std::function cb) { - std::unique_lock lock(mMutex); - mCallbacks.emplace(key, cb); -} - -void Debounce::remove(void *key) { - std::unique_lock lock(mMutex); - mCallbacks.erase(key); -} - -void Debounce::trigger() { - std::unique_lock lock(mMutex); - #ifdef __wasm32__ - notifyIfReady(); - #else - mWaitSignal.notify(); - #endif -} - -#ifndef __wasm32__ -void Debounce::loop() { - while (mRunning) { - mWaitSignal.wait(); - if (!mRunning) { - break; - } - - notifyIfReady(); - } -} -#endif - -void Debounce::notifyIfReady() { - if (!mRunning) { - return; - } - - // If we haven't seen an event in more than the maximum wait time, notify callbacks immediately - // to ensure that we don't wait forever. Otherwise, wait for the minimum wait time and batch - // subsequent fast changes. This also means the first file change in a batch is notified immediately, - // separately from the rest of the batch. This seems like an acceptable tradeoff if the common case - // is that only a single file was updated at a time. - auto time = std::chrono::steady_clock::now(); - if ((time - mLastTime) > std::chrono::milliseconds(MAX_WAIT_TIME)) { - mLastTime = time; - notify(); - } else { - wait(); - } -} - -void Debounce::wait() { - #ifdef __wasm32__ - clear_timeout(mTimeout); - mTimeout = set_timeout(MIN_WAIT_TIME, this); - #else - auto status = mWaitSignal.waitFor(std::chrono::milliseconds(MIN_WAIT_TIME)); - if (mRunning && (status == std::cv_status::timeout)) { - notify(); - } - #endif -} - -void Debounce::notify() { - std::unique_lock lock(mMutex); - - mLastTime = std::chrono::steady_clock::now(); - for (auto it = mCallbacks.begin(); it != mCallbacks.end(); it++) { - auto cb = it->second; - cb(); - } - - #ifndef __wasm32__ - mWaitSignal.reset(); - #endif -} diff --git a/node_modules/@parcel/watcher/src/Debounce.hh b/node_modules/@parcel/watcher/src/Debounce.hh deleted file mode 100644 index a17fdef..0000000 --- a/node_modules/@parcel/watcher/src/Debounce.hh +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef DEBOUNCE_H -#define DEBOUNCE_H - -#include -#include -#include -#include "Signal.hh" - -#define MIN_WAIT_TIME 50 -#define MAX_WAIT_TIME 500 - -#ifdef __wasm32__ -extern "C" { - int set_timeout(int ms, void *ctx); - void clear_timeout(int timeout); - void on_timeout(void *ctx); -}; -#endif - -class Debounce { -public: - static std::shared_ptr getShared(); - - Debounce(); - ~Debounce(); - - void add(void *key, std::function cb); - void remove(void *key); - void trigger(); - void notify(); - -private: - bool mRunning; - std::mutex mMutex; - #ifdef __wasm32__ - int mTimeout; - #else - Signal mWaitSignal; - std::thread mThread; - #endif - std::unordered_map> mCallbacks; - std::chrono::time_point mLastTime; - - void loop(); - void notifyIfReady(); - void wait(); -}; - -#endif diff --git a/node_modules/@parcel/watcher/src/DirTree.cc b/node_modules/@parcel/watcher/src/DirTree.cc deleted file mode 100644 index b7eddd8..0000000 --- a/node_modules/@parcel/watcher/src/DirTree.cc +++ /dev/null @@ -1,164 +0,0 @@ -#include "DirTree.hh" -#include - -// "Meyer's singleton", construction is ordered by use, likewise (reverse) for destruction. -// https://stackoverflow.com/a/17713799 -// https://laristra.github.io/flecsi/src/developer-guide/patterns/meyers_singleton.html -static std::mutex& mDirCacheMutex() { - static std::mutex mutex; - return mutex; -} - -static std::unordered_map>& dirTreeCache() { - static std::unordered_map> cache; - return cache; -} - -struct DirTreeDeleter { - void operator()(DirTree *tree) { - std::lock_guard lock(mDirCacheMutex()); - std::unordered_map> &cache = dirTreeCache(); - cache.erase(tree->root); - delete tree; - - // Free up memory. - if (cache.size() == 0) { - cache.rehash(0); - } - } -}; - -std::shared_ptr DirTree::getCached(std::string root) { - std::lock_guard lock(mDirCacheMutex()); - std::unordered_map> &cache = dirTreeCache(); - - auto found = cache.find(root); - std::shared_ptr tree; - - // Use cached tree, or create an empty one. - if (found != cache.end()) { - tree = found->second.lock(); - } else { - tree = std::shared_ptr(new DirTree(root), DirTreeDeleter()); - cache.emplace(root, tree); - } - - return tree; -} - -DirTree::DirTree(std::string root, FILE *f) : root(root), isComplete(true) { - size_t size; - if (fscanf(f, "%zu", &size)) { - for (size_t i = 0; i < size; i++) { - DirEntry entry(f); - entries.emplace(entry.path, entry); - } - } -} - -// Internal find method that has no lock -DirEntry *DirTree::_find(std::string path) { - auto found = entries.find(path); - if (found == entries.end()) { - return NULL; - } - - return &found->second; -} - -DirEntry *DirTree::add(std::string path, uint64_t mtime, bool isDir) { - std::lock_guard lock(mDirCacheMutex()); - - DirEntry entry(path, mtime, isDir); - auto it = entries.emplace(entry.path, entry); - return &it.first->second; -} - -DirEntry *DirTree::find(std::string path) { - std::lock_guard lock(mDirCacheMutex()); - return _find(path); -} - -DirEntry *DirTree::update(std::string path, uint64_t mtime) { - std::lock_guard lock(mDirCacheMutex()); - - DirEntry *found = _find(path); - if (found) { - found->mtime = mtime; - } - - return found; -} - -void DirTree::remove(std::string path) { - std::lock_guard lock(mDirCacheMutex()); - - DirEntry *found = _find(path); - - // Remove all sub-entries if this is a directory - if (found && found->isDir) { - std::string pathStart = path + DIR_SEP; - for (auto it = entries.begin(); it != entries.end();) { - if (it->first.rfind(pathStart, 0) == 0) { - it = entries.erase(it); - } else { - it++; - } - } - } - - entries.erase(path); -} - -void DirTree::write(FILE *f) { - std::lock_guard lock(mDirCacheMutex()); - - fprintf(f, "%zu\n", entries.size()); - for (auto it = entries.begin(); it != entries.end(); it++) { - it->second.write(f); - } -} - -void DirTree::getChanges(DirTree *snapshot, EventList &events) { - std::lock_guard lock(mDirCacheMutex()); - std::lock_guard snapshotLock(snapshot->mMutex); - - for (auto it = entries.begin(); it != entries.end(); it++) { - auto found = snapshot->entries.find(it->first); - if (found == snapshot->entries.end()) { - events.create(it->second.path); - } else if (found->second.mtime != it->second.mtime && !found->second.isDir && !it->second.isDir) { - events.update(it->second.path); - } - } - - for (auto it = snapshot->entries.begin(); it != snapshot->entries.end(); it++) { - size_t count = entries.count(it->first); - if (count == 0) { - events.remove(it->second.path); - } - } -} - -DirEntry::DirEntry(std::string p, uint64_t t, bool d) { - path = p; - mtime = t; - isDir = d; - state = NULL; -} - -DirEntry::DirEntry(FILE *f) { - size_t size; - if (fscanf(f, "%zu", &size)) { - path.resize(size); - if (fread(&path[0], sizeof(char), size, f)) { - int d = 0; - fscanf(f, "%" PRIu64 " %d\n", &mtime, &d); - isDir = d == 1; - } - } -} - -void DirEntry::write(FILE *f) const { - fprintf(f, "%zu%s%" PRIu64 " %d\n", path.size(), path.c_str(), mtime, isDir); -} diff --git a/node_modules/@parcel/watcher/src/DirTree.hh b/node_modules/@parcel/watcher/src/DirTree.hh deleted file mode 100644 index 328f469..0000000 --- a/node_modules/@parcel/watcher/src/DirTree.hh +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef DIR_TREE_H -#define DIR_TREE_H - -#include -#include -#include -#include "Event.hh" - -#ifdef _WIN32 -#define DIR_SEP "\\" -#else -#define DIR_SEP "/" -#endif - -struct DirEntry { - std::string path; - uint64_t mtime; - bool isDir; - mutable void *state; - - DirEntry(std::string p, uint64_t t, bool d); - DirEntry(FILE *f); - void write(FILE *f) const; - bool operator==(const DirEntry &other) const { - return path == other.path; - } -}; - -class DirTree { -public: - static std::shared_ptr getCached(std::string root); - DirTree(std::string root) : root(root), isComplete(false) {} - DirTree(std::string root, FILE *f); - DirEntry *add(std::string path, uint64_t mtime, bool isDir); - DirEntry *find(std::string path); - DirEntry *update(std::string path, uint64_t mtime); - void remove(std::string path); - void write(FILE *f); - void getChanges(DirTree *snapshot, EventList &events); - - std::mutex mMutex; - std::string root; - bool isComplete; - std::unordered_map entries; - -private: - DirEntry *_find(std::string path); -}; - -#endif diff --git a/node_modules/@parcel/watcher/src/Event.hh b/node_modules/@parcel/watcher/src/Event.hh deleted file mode 100644 index 8d09712..0000000 --- a/node_modules/@parcel/watcher/src/Event.hh +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef EVENT_H -#define EVENT_H - -#include -#include -#include "wasm/include.h" -#include -#include -#include -#include - -using namespace Napi; - -struct Event { - std::string path; - bool isCreated; - bool isDeleted; - Event(std::string path) : path(path), isCreated(false), isDeleted(false) {} - - Value toJS(const Env& env) { - EscapableHandleScope scope(env); - Object res = Object::New(env); - std::string type = isCreated ? "create" : isDeleted ? "delete" : "update"; - res.Set(String::New(env, "path"), String::New(env, path.c_str())); - res.Set(String::New(env, "type"), String::New(env, type.c_str())); - return scope.Escape(res); - } -}; - -class EventList { -public: - void create(std::string path) { - std::lock_guard l(mMutex); - Event *event = internalUpdate(path); - if (event->isDeleted) { - // Assume update event when rapidly removed and created - // https://github.com/parcel-bundler/watcher/issues/72 - event->isDeleted = false; - } else { - event->isCreated = true; - } - } - - Event *update(std::string path) { - std::lock_guard l(mMutex); - return internalUpdate(path); - } - - void remove(std::string path) { - std::lock_guard l(mMutex); - Event *event = internalUpdate(path); - event->isDeleted = true; - } - - size_t size() { - std::lock_guard l(mMutex); - return mEvents.size(); - } - - std::vector getEvents() { - std::lock_guard l(mMutex); - std::vector eventsCloneVector; - for(auto it = mEvents.begin(); it != mEvents.end(); ++it) { - if (!(it->second.isCreated && it->second.isDeleted)) { - eventsCloneVector.push_back(it->second); - } - } - return eventsCloneVector; - } - - void clear() { - std::lock_guard l(mMutex); - mEvents.clear(); - mError.reset(); - } - - void error(std::string err) { - std::lock_guard l(mMutex); - if (!mError.has_value()) { - mError.emplace(err); - } - } - - bool hasError() { - std::lock_guard l(mMutex); - return mError.has_value(); - } - - std::string getError() { - std::lock_guard l(mMutex); - return mError.value_or(""); - } - -private: - mutable std::mutex mMutex; - std::map mEvents; - std::optional mError; - Event *internalUpdate(std::string path) { - auto found = mEvents.find(path); - if (found == mEvents.end()) { - auto it = mEvents.emplace(path, Event(path)); - return &it.first->second; - } - - return &found->second; - } -}; - -#endif diff --git a/node_modules/@parcel/watcher/src/Glob.cc b/node_modules/@parcel/watcher/src/Glob.cc deleted file mode 100644 index a4a1722..0000000 --- a/node_modules/@parcel/watcher/src/Glob.cc +++ /dev/null @@ -1,22 +0,0 @@ -#include "Glob.hh" - -#ifdef __wasm32__ -extern "C" bool wasm_regex_match(const char *s, const char *regex); -#endif - -Glob::Glob(std::string raw) { - mRaw = raw; - mHash = std::hash()(raw); - #ifndef __wasm32__ - mRegex = std::regex(raw); - #endif -} - -bool Glob::isIgnored(std::string relative_path) const { - // Use native JS regex engine for wasm to reduce binary size. - #ifdef __wasm32__ - return wasm_regex_match(relative_path.c_str(), mRaw.c_str()); - #else - return std::regex_match(relative_path, mRegex); - #endif -} diff --git a/node_modules/@parcel/watcher/src/Glob.hh b/node_modules/@parcel/watcher/src/Glob.hh deleted file mode 100644 index b5fc375..0000000 --- a/node_modules/@parcel/watcher/src/Glob.hh +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef GLOB_H -#define GLOB_H - -#include -#include - -struct Glob { - std::size_t mHash; - std::string mRaw; - #ifndef __wasm32__ - std::regex mRegex; - #endif - - Glob(std::string raw); - - bool operator==(const Glob &other) const { - return mHash == other.mHash && mRaw == other.mRaw; - } - - bool isIgnored(std::string relative_path) const; -}; - -namespace std -{ - template <> - struct hash - { - size_t operator()(const Glob& g) const { - return g.mHash; - } - }; -} - -#endif diff --git a/node_modules/@parcel/watcher/src/PromiseRunner.hh b/node_modules/@parcel/watcher/src/PromiseRunner.hh deleted file mode 100644 index 4ca3bb6..0000000 --- a/node_modules/@parcel/watcher/src/PromiseRunner.hh +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef PROMISE_RUNNER_H -#define PROMISE_RUNNER_H - -#include -#include "wasm/include.h" -#include - -using namespace Napi; - -class PromiseRunner { -public: - const Env env; - Promise::Deferred deferred; - - PromiseRunner(Env env) : env(env), deferred(Promise::Deferred::New(env)) { - napi_status status = napi_create_async_work(env, nullptr, env.Undefined(), - onExecute, onWorkComplete, this, &work); - if (status != napi_ok) { - work = nullptr; - const napi_extended_error_info *error_info = 0; - napi_get_last_error_info(env, &error_info); - if (error_info->error_message) { - Error::New(env, error_info->error_message).ThrowAsJavaScriptException(); - } else { - Error::New(env).ThrowAsJavaScriptException(); - } - } - } - - virtual ~PromiseRunner() {} - - Value queue() { - if (work) { - napi_status status = napi_queue_async_work(env, work); - if (status != napi_ok) { - onError(Error::New(env)); - } - } - - return deferred.Promise(); - } - -private: - napi_async_work work; - std::string error; - - static void onExecute(napi_env env, void *this_pointer) { - PromiseRunner* self = (PromiseRunner*) this_pointer; - try { - self->execute(); - } catch (std::exception &err) { - self->error = err.what(); - } - } - - static void onWorkComplete(napi_env env, napi_status status, void *this_pointer) { - PromiseRunner* self = (PromiseRunner*) this_pointer; - if (status != napi_cancelled) { - HandleScope scope(self->env); - if (status == napi_ok) { - status = napi_delete_async_work(self->env, self->work); - if (status == napi_ok) { - if (self->error.size() == 0) { - self->onOK(); - } else { - self->onError(Error::New(self->env, self->error)); - } - delete self; - return; - } - } - } - - // fallthrough for error handling - const napi_extended_error_info *error_info = 0; - napi_get_last_error_info(env, &error_info); - if (error_info->error_message){ - self->onError(Error::New(env, error_info->error_message)); - } else { - self->onError(Error::New(env)); - } - delete self; - } - - virtual void execute() {} - virtual Value getResult() { - return env.Null(); - } - - void onOK() { - HandleScope scope(env); - Value result = getResult(); - deferred.Resolve(result); - } - - void onError(const Error &e) { - deferred.Reject(e.Value()); - } -}; - -#endif diff --git a/node_modules/@parcel/watcher/src/Signal.hh b/node_modules/@parcel/watcher/src/Signal.hh deleted file mode 100644 index e577319..0000000 --- a/node_modules/@parcel/watcher/src/Signal.hh +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef SIGNAL_H -#define SIGNAL_H - -#include -#include - -class Signal { -public: - Signal() : mFlag(false), mWaiting(false) {} - void wait() { - std::unique_lock lock(mMutex); - while (!mFlag) { - mWaiting = true; - mCond.wait(lock); - } - } - - std::cv_status waitFor(std::chrono::milliseconds ms) { - std::unique_lock lock(mMutex); - return mCond.wait_for(lock, ms); - } - - void notify() { - std::unique_lock lock(mMutex); - mFlag = true; - mCond.notify_all(); - } - - void reset() { - std::unique_lock lock(mMutex); - mFlag = false; - mWaiting = false; - } - - bool isWaiting() { - return mWaiting; - } - -private: - bool mFlag; - bool mWaiting; - std::mutex mMutex; - std::condition_variable mCond; -}; - -#endif diff --git a/node_modules/@parcel/watcher/src/Watcher.cc b/node_modules/@parcel/watcher/src/Watcher.cc deleted file mode 100644 index a58ff37..0000000 --- a/node_modules/@parcel/watcher/src/Watcher.cc +++ /dev/null @@ -1,241 +0,0 @@ -#include "Watcher.hh" -#include - -using namespace Napi; - -struct WatcherHash { - std::size_t operator() (WatcherRef const &k) const { - return std::hash()(k->mDir); - } -}; - -struct WatcherCompare { - size_t operator() (WatcherRef const &a, WatcherRef const &b) const { - return *a == *b; - } -}; - -static std::unordered_set& getSharedWatchers() { - static std::unordered_set* sharedWatchers = - new std::unordered_set(); - return *sharedWatchers; -} - -WatcherRef Watcher::getShared(std::string dir, std::unordered_set ignorePaths, std::unordered_set ignoreGlobs) { - WatcherRef watcher = std::make_shared(dir, ignorePaths, ignoreGlobs); - auto found = getSharedWatchers().find(watcher); - if (found != getSharedWatchers().end()) { - return *found; - } - - getSharedWatchers().insert(watcher); - return watcher; -} - -void removeShared(Watcher *watcher) { - for (auto it = getSharedWatchers().begin(); it != getSharedWatchers().end(); it++) { - if (it->get() == watcher) { - getSharedWatchers().erase(it); - break; - } - } - - // Free up memory. - if (getSharedWatchers().size() == 0) { - getSharedWatchers().rehash(0); - } -} - -Watcher::Watcher(std::string dir, std::unordered_set ignorePaths, std::unordered_set ignoreGlobs) - : mDir(dir), - mIgnorePaths(ignorePaths), - mIgnoreGlobs(ignoreGlobs) { - mDebounce = Debounce::getShared(); - mDebounce->add(this, [this] () { - triggerCallbacks(); - }); - } - -Watcher::~Watcher() { - mDebounce->remove(this); -} - -void Watcher::wait() { - std::unique_lock lk(mMutex); - mCond.wait(lk); -} - -void Watcher::notify() { - std::unique_lock lk(mMutex); - mCond.notify_all(); - - if (mCallbacks.size() > 0 && mEvents.size() > 0) { - // We must release our lock before calling into the debouncer - // to avoid a deadlock: the debouncer thread itself will require - // our lock from its thread when calling into `triggerCallbacks` - // while holding its own debouncer lock. - lk.unlock(); - mDebounce->trigger(); - } -} - -struct CallbackData { - std::string error; - std::vector events; - CallbackData(std::string error, std::vector events) : error(error), events(events) {} -}; - -Value callbackEventsToJS(const Env &env, std::vector &events) { - EscapableHandleScope scope(env); - Array arr = Array::New(env, events.size()); - uint32_t currentEventIndex = 0; - for (auto eventIterator = events.begin(); eventIterator != events.end(); eventIterator++) { - arr.Set(currentEventIndex++, eventIterator->toJS(env)); - } - return scope.Escape(arr); -} - -void callJSFunction(Napi::Env env, Function jsCallback, CallbackData *data) { - HandleScope scope(env); - auto err = data->error.size() > 0 ? Error::New(env, data->error).Value() : env.Null(); - auto events = callbackEventsToJS(env, data->events); - jsCallback.Call({err, events}); - delete data; - - // Throw errors from the callback as fatal exceptions - // If we don't handle these node segfaults... - if (env.IsExceptionPending()) { - Napi::Error err = env.GetAndClearPendingException(); - napi_fatal_exception(env, err.Value()); - } -} - -void Watcher::notifyError(std::exception &err) { - std::unique_lock lk(mMutex); - for (auto it = mCallbacks.begin(); it != mCallbacks.end(); it++) { - CallbackData *data = new CallbackData(err.what(), {}); - it->tsfn.BlockingCall(data, callJSFunction); - } - - clearCallbacks(); -} - -// This function is called from the debounce thread. -void Watcher::triggerCallbacks() { - std::unique_lock lk(mMutex); - if (mCallbacks.size() > 0 && (mEvents.size() > 0 || mEvents.hasError())) { - auto error = mEvents.getError(); - auto events = mEvents.getEvents(); - mEvents.clear(); - - for (auto it = mCallbacks.begin(); it != mCallbacks.end(); it++) { - it->tsfn.BlockingCall(new CallbackData(error, events), callJSFunction); - } - } -} - -// This should be called from the JavaScript thread. -bool Watcher::watch(Function callback) { - std::unique_lock lk(mMutex); - - auto it = findCallback(callback); - if (it != mCallbacks.end()) { - return false; - } - - auto tsfn = ThreadSafeFunction::New( - callback.Env(), - callback, - "Watcher callback", - 0, // Unlimited queue - 1 // Initial thread count - ); - - mCallbacks.push_back(Callback { - tsfn, - Napi::Persistent(callback), - std::this_thread::get_id() - }); - - return true; -} - -// This should be called from the JavaScript thread. -std::vector::iterator Watcher::findCallback(Function callback) { - for (auto it = mCallbacks.begin(); it != mCallbacks.end(); it++) { - // Only consider callbacks created by the same thread, or V8 will panic. - if (it->threadId == std::this_thread::get_id() && it->ref.Value() == callback) { - return it; - } - } - - return mCallbacks.end(); -} - -// This should be called from the JavaScript thread. -bool Watcher::unwatch(Function callback) { - std::unique_lock lk(mMutex); - - bool removed = false; - auto it = findCallback(callback); - if (it != mCallbacks.end()) { - it->tsfn.Release(); - it->ref.Unref(); - mCallbacks.erase(it); - removed = true; - } - - if (removed && mCallbacks.size() == 0) { - unref(); - return true; - } - - return false; -} - -void Watcher::unref() { - if (mCallbacks.size() == 0) { - removeShared(this); - } -} - -void Watcher::destroy() { - std::unique_lock lk(mMutex); - clearCallbacks(); -} - -// Private because it doesn't lock. -void Watcher::clearCallbacks() { - for (auto it = mCallbacks.begin(); it != mCallbacks.end(); it++) { - it->tsfn.Release(); - it->ref.Unref(); - } - - mCallbacks.clear(); - unref(); -} - -bool Watcher::isIgnored(std::string path) { - for (auto it = mIgnorePaths.begin(); it != mIgnorePaths.end(); it++) { - auto dir = *it + DIR_SEP; - if (*it == path || path.compare(0, dir.size(), dir) == 0) { - return true; - } - } - - auto basePath = mDir + DIR_SEP; - - if (path.rfind(basePath, 0) != 0) { - return false; - } - - auto relativePath = path.substr(basePath.size()); - - for (auto it = mIgnoreGlobs.begin(); it != mIgnoreGlobs.end(); it++) { - if (it->isIgnored(relativePath)) { - return true; - } - } - - return false; -} diff --git a/node_modules/@parcel/watcher/src/Watcher.hh b/node_modules/@parcel/watcher/src/Watcher.hh deleted file mode 100644 index f89e9f5..0000000 --- a/node_modules/@parcel/watcher/src/Watcher.hh +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef WATCHER_H -#define WATCHER_H - -#include -#include -#include -#include -#include "Glob.hh" -#include "Event.hh" -#include "Debounce.hh" -#include "DirTree.hh" -#include "Signal.hh" - -using namespace Napi; - -struct Watcher; -using WatcherRef = std::shared_ptr; - -struct Callback { - Napi::ThreadSafeFunction tsfn; - Napi::FunctionReference ref; - std::thread::id threadId; -}; - -class WatcherState { -public: - virtual ~WatcherState() = default; -}; - -struct Watcher { - std::string mDir; - std::unordered_set mIgnorePaths; - std::unordered_set mIgnoreGlobs; - EventList mEvents; - std::shared_ptr state; - - Watcher(std::string dir, std::unordered_set ignorePaths, std::unordered_set ignoreGlobs); - ~Watcher(); - - bool operator==(const Watcher &other) const { - return mDir == other.mDir && mIgnorePaths == other.mIgnorePaths && mIgnoreGlobs == other.mIgnoreGlobs; - } - - void wait(); - void notify(); - void notifyError(std::exception &err); - bool watch(Function callback); - bool unwatch(Function callback); - void unref(); - bool isIgnored(std::string path); - void destroy(); - - static WatcherRef getShared(std::string dir, std::unordered_set ignorePaths, std::unordered_set ignoreGlobs); - -private: - std::mutex mMutex; - std::condition_variable mCond; - std::vector mCallbacks; - std::shared_ptr mDebounce; - - std::vector::iterator findCallback(Function callback); - void clearCallbacks(); - void triggerCallbacks(); -}; - -class WatcherError : public std::runtime_error { -public: - WatcherRef mWatcher; - WatcherError(std::string msg, WatcherRef watcher) : std::runtime_error(msg), mWatcher(watcher) {} - WatcherError(const char *msg, WatcherRef watcher) : std::runtime_error(msg), mWatcher(watcher) {} -}; - -#endif diff --git a/node_modules/@parcel/watcher/src/binding.cc b/node_modules/@parcel/watcher/src/binding.cc deleted file mode 100644 index 057b61b..0000000 --- a/node_modules/@parcel/watcher/src/binding.cc +++ /dev/null @@ -1,268 +0,0 @@ -#include -#include -#include "wasm/include.h" -#include -#include "Glob.hh" -#include "Event.hh" -#include "Backend.hh" -#include "Watcher.hh" -#include "PromiseRunner.hh" - -using namespace Napi; - -std::unordered_set getIgnorePaths(Env env, Value opts) { - std::unordered_set result; - - if (opts.IsObject()) { - Value v = opts.As().Get(String::New(env, "ignorePaths")); - if (v.IsArray()) { - Array items = v.As(); - for (size_t i = 0; i < items.Length(); i++) { - Value item = items.Get(Number::New(env, static_cast(i))); - if (item.IsString()) { - result.insert(std::string(item.As().Utf8Value().c_str())); - } - } - } - } - - return result; -} - -std::unordered_set getIgnoreGlobs(Env env, Value opts) { - std::unordered_set result; - - if (opts.IsObject()) { - Value v = opts.As().Get(String::New(env, "ignoreGlobs")); - if (v.IsArray()) { - Array items = v.As(); - for (size_t i = 0; i < items.Length(); i++) { - Value item = items.Get(Number::New(env, static_cast(i))); - if (item.IsString()) { - auto key = item.As().Utf8Value(); - try { - result.emplace(key); - } catch (const std::regex_error& e) { - Error::New(env, e.what()).ThrowAsJavaScriptException(); - } - } - } - } - } - - return result; -} - -std::shared_ptr getBackend(Env env, Value opts) { - Value b = opts.As().Get(String::New(env, "backend")); - std::string backendName; - if (b.IsString()) { - backendName = std::string(b.As().Utf8Value().c_str()); - } - - return Backend::getShared(backendName); -} - -class WriteSnapshotRunner : public PromiseRunner { -public: - WriteSnapshotRunner(Env env, Value dir, Value snap, Value opts) - : PromiseRunner(env), - snapshotPath(std::string(snap.As().Utf8Value().c_str())) { - watcher = Watcher::getShared( - std::string(dir.As().Utf8Value().c_str()), - getIgnorePaths(env, opts), - getIgnoreGlobs(env, opts) - ); - - backend = getBackend(env, opts); - } - - ~WriteSnapshotRunner() { - watcher->unref(); - backend->unref(); - } -private: - std::shared_ptr backend; - WatcherRef watcher; - std::string snapshotPath; - - void execute() override { - backend->writeSnapshot(watcher, &snapshotPath); - } -}; - -class GetEventsSinceRunner : public PromiseRunner { -public: - GetEventsSinceRunner(Env env, Value dir, Value snap, Value opts) - : PromiseRunner(env), - snapshotPath(std::string(snap.As().Utf8Value().c_str())) { - watcher = std::make_shared( - std::string(dir.As().Utf8Value().c_str()), - getIgnorePaths(env, opts), - getIgnoreGlobs(env, opts) - ); - - backend = getBackend(env, opts); - } - - ~GetEventsSinceRunner() { - watcher->unref(); - backend->unref(); - } -private: - std::shared_ptr backend; - WatcherRef watcher; - std::string snapshotPath; - - void execute() override { - backend->getEventsSince(watcher, &snapshotPath); - if (watcher->mEvents.hasError()) { - throw std::runtime_error(watcher->mEvents.getError()); - } - } - - Value getResult() override { - std::vector events = watcher->mEvents.getEvents(); - Array eventsArray = Array::New(env, events.size()); - uint32_t i = 0; - for (auto it = events.begin(); it != events.end(); it++) { - eventsArray.Set(i++, it->toJS(env)); - } - return eventsArray; - } -}; - -template -Value queueSnapshotWork(const CallbackInfo& info) { - Env env = info.Env(); - if (info.Length() < 1 || !info[0].IsString()) { - TypeError::New(env, "Expected a string").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (info.Length() < 2 || !info[1].IsString()) { - TypeError::New(env, "Expected a string").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (info.Length() >= 3 && !info[2].IsObject()) { - TypeError::New(env, "Expected an object").ThrowAsJavaScriptException(); - return env.Null(); - } - - Runner *runner = new Runner(info.Env(), info[0], info[1], info[2]); - return runner->queue(); -} - -Value writeSnapshot(const CallbackInfo& info) { - return queueSnapshotWork(info); -} - -Value getEventsSince(const CallbackInfo& info) { - return queueSnapshotWork(info); -} - -class SubscribeRunner : public PromiseRunner { -public: - SubscribeRunner(Env env, Value dir, Value fn, Value opts) : PromiseRunner(env) { - watcher = Watcher::getShared( - std::string(dir.As().Utf8Value().c_str()), - getIgnorePaths(env, opts), - getIgnoreGlobs(env, opts) - ); - - backend = getBackend(env, opts); - watcher->watch(fn.As()); - } - -private: - WatcherRef watcher; - std::shared_ptr backend; - FunctionReference callback; - - void execute() override { - try { - backend->watch(watcher); - } catch (std::exception&) { - watcher->destroy(); - throw; - } - } -}; - -class UnsubscribeRunner : public PromiseRunner { -public: - UnsubscribeRunner(Env env, Value dir, Value fn, Value opts) : PromiseRunner(env) { - watcher = Watcher::getShared( - std::string(dir.As().Utf8Value().c_str()), - getIgnorePaths(env, opts), - getIgnoreGlobs(env, opts) - ); - - backend = getBackend(env, opts); - shouldUnwatch = watcher->unwatch(fn.As()); - } - -private: - WatcherRef watcher; - std::shared_ptr backend; - bool shouldUnwatch; - - void execute() override { - if (shouldUnwatch) { - backend->unwatch(watcher); - } - } -}; - -template -Value queueSubscriptionWork(const CallbackInfo& info) { - Env env = info.Env(); - if (info.Length() < 1 || !info[0].IsString()) { - TypeError::New(env, "Expected a string").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (info.Length() < 2 || !info[1].IsFunction()) { - TypeError::New(env, "Expected a function").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (info.Length() >= 3 && !info[2].IsObject()) { - TypeError::New(env, "Expected an object").ThrowAsJavaScriptException(); - return env.Null(); - } - - Runner *runner = new Runner(info.Env(), info[0], info[1], info[2]); - return runner->queue(); -} - -Value subscribe(const CallbackInfo& info) { - return queueSubscriptionWork(info); -} - -Value unsubscribe(const CallbackInfo& info) { - return queueSubscriptionWork(info); -} - -Object Init(Env env, Object exports) { - exports.Set( - String::New(env, "writeSnapshot"), - Function::New(env, writeSnapshot) - ); - exports.Set( - String::New(env, "getEventsSince"), - Function::New(env, getEventsSince) - ); - exports.Set( - String::New(env, "subscribe"), - Function::New(env, subscribe) - ); - exports.Set( - String::New(env, "unsubscribe"), - Function::New(env, unsubscribe) - ); - return exports; -} - -NODE_API_MODULE(watcher, Init) diff --git a/node_modules/@parcel/watcher/src/kqueue/KqueueBackend.cc b/node_modules/@parcel/watcher/src/kqueue/KqueueBackend.cc deleted file mode 100644 index 2991c32..0000000 --- a/node_modules/@parcel/watcher/src/kqueue/KqueueBackend.cc +++ /dev/null @@ -1,306 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "KqueueBackend.hh" - -#if __APPLE__ -#define st_mtim st_mtimespec -#endif - -#if !defined(O_EVTONLY) -#define O_EVTONLY O_RDONLY -#endif - -#define CONVERT_TIME(ts) ((uint64_t)ts.tv_sec * 1000000000 + ts.tv_nsec) - -void KqueueBackend::start() { - if ((mKqueue = kqueue()) < 0) { - throw std::runtime_error(std::string("Unable to open kqueue: ") + strerror(errno)); - } - - // Create a pipe that we will write to when we want to end the thread. - int err = pipe(mPipe); - if (err == -1) { - throw std::runtime_error(std::string("Unable to open pipe: ") + strerror(errno)); - } - - // Subscribe kqueue to this pipe. - struct kevent ev; - EV_SET( - &ev, - mPipe[0], - EVFILT_READ, - EV_ADD | EV_CLEAR, - 0, - 0, - 0 - ); - - if (kevent(mKqueue, &ev, 1, NULL, 0, 0)) { - close(mPipe[0]); - close(mPipe[1]); - throw std::runtime_error(std::string("Unable to watch pipe: ") + strerror(errno)); - } - - notifyStarted(); - - struct kevent events[128]; - - while (true) { - int event_count = kevent(mKqueue, NULL, 0, events, 128, 0); - if (event_count < 0 || events[0].flags == EV_ERROR) { - throw std::runtime_error(std::string("kevent error: ") + strerror(errno)); - } - - // Track all of the watchers that are touched so we can notify them at the end of the events. - std::unordered_set watchers; - - for (int i = 0; i < event_count; i++) { - int flags = events[i].fflags; - int fd = events[i].ident; - if (fd == mPipe[0]) { - // pipe was written to. break out of the loop. - goto done; - } - - auto it = mFdToEntry.find(fd); - if (it == mFdToEntry.end()) { - // If fd wasn't in our map, we may have already stopped watching it. Ignore the event. - continue; - } - - DirEntry *entry = it->second; - - if (flags & NOTE_WRITE && entry && entry->isDir) { - // If a write occurred on a directory, we have to diff the contents of that - // directory to determine what file was added/deleted. - compareDir(fd, entry->path, watchers); - } else { - std::vector subs = findSubscriptions(entry->path); - for (auto it = subs.begin(); it != subs.end(); it++) { - KqueueSubscription *sub = *it; - watchers.insert(sub->watcher); - if (flags & (NOTE_DELETE | NOTE_RENAME | NOTE_REVOKE)) { - sub->watcher->mEvents.remove(sub->path); - sub->tree->remove(sub->path); - mFdToEntry.erase((int)(size_t)entry->state); - mSubscriptions.erase(sub->path); - } else if (flags & (NOTE_WRITE | NOTE_ATTRIB | NOTE_EXTEND)) { - struct stat st; - lstat(sub->path.c_str(), &st); - if (entry->mtime != CONVERT_TIME(st.st_mtim)) { - entry->mtime = CONVERT_TIME(st.st_mtim); - sub->watcher->mEvents.update(sub->path); - } - } - } - } - } - - for (auto it = watchers.begin(); it != watchers.end(); it++) { - (*it)->notify(); - } - } - -done: - close(mPipe[0]); - close(mPipe[1]); - mEndedSignal.notify(); -} - -KqueueBackend::~KqueueBackend() { - write(mPipe[1], "X", 1); - mEndedSignal.wait(); -} - -void KqueueBackend::subscribe(WatcherRef watcher) { - // Build a full directory tree recursively, and watch each directory. - std::shared_ptr tree = getTree(watcher); - - for (auto it = tree->entries.begin(); it != tree->entries.end(); it++) { - bool success = watchDir(watcher, it->second.path, tree); - if (!success) { - throw WatcherError(std::string("error watching " + watcher->mDir + ": " + strerror(errno)), watcher); - } - } -} - -bool KqueueBackend::watchDir(WatcherRef watcher, std::string path, std::shared_ptr tree) { - if (watcher->isIgnored(path)) { - return false; - } - - DirEntry *entry = tree->find(path); - if (!entry) { - return false; - } - - KqueueSubscription sub = { - .watcher = watcher, - .path = path, - .tree = tree - }; - - if (!entry->state) { - int fd = open(path.c_str(), O_EVTONLY); - if (fd <= 0) { - return false; - } - - struct kevent event; - EV_SET( - &event, - fd, - EVFILT_VNODE, - EV_ADD | EV_CLEAR | EV_ENABLE, - NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE, - 0, - 0 - ); - - if (kevent(mKqueue, &event, 1, NULL, 0, 0)) { - close(fd); - return false; - } - - entry->state = (void *)(size_t)fd; - mFdToEntry.emplace(fd, entry); - } - - sub.fd = (int)(size_t)entry->state; - mSubscriptions.emplace(path, sub); - return true; -} - -std::vector KqueueBackend::findSubscriptions(std::string &path) { - // Find the subscriptions affected by this path. - // Copy pointers to them into a vector so that modifying mSubscriptions doesn't invalidate the iterator. - auto range = mSubscriptions.equal_range(path); - std::vector subs; - for (auto it = range.first; it != range.second; it++) { - subs.push_back(&it->second); - } - - return subs; -} - -bool KqueueBackend::compareDir(int fd, std::string &path, std::unordered_set &watchers) { - // macOS doesn't support fdclosedir, so we have to duplicate the file descriptor - // to ensure the closedir doesn't also stop watching. - #if __APPLE__ - fd = dup(fd); - #endif - - DIR *dir = fdopendir(fd); - if (dir == NULL) { - return false; - } - - // fdopendir doesn't rewind to the beginning. - rewinddir(dir); - - std::vector subs = findSubscriptions(path); - std::string dirStart = path + DIR_SEP; - - std::unordered_set> trees; - for (auto it = subs.begin(); it != subs.end(); it++) { - trees.emplace((*it)->tree); - } - - std::unordered_set entries; - struct dirent *entry; - while ((entry = readdir(dir))) { - if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { - continue; - } - - std::string fullpath = dirStart + entry->d_name; - entries.emplace(fullpath); - - for (auto it = trees.begin(); it != trees.end(); it++) { - std::shared_ptr tree = *it; - if (!tree->find(fullpath)) { - struct stat st; - fstatat(fd, entry->d_name, &st, AT_SYMLINK_NOFOLLOW); - tree->add(fullpath, CONVERT_TIME(st.st_mtim), S_ISDIR(st.st_mode)); - - // Notify all watchers with the same tree. - for (auto i = subs.begin(); i != subs.end(); i++) { - KqueueSubscription *sub = *i; - if (sub->tree == tree) { - if (sub->watcher->isIgnored(fullpath)) { - continue; - } - - sub->watcher->mEvents.create(fullpath); - watchers.emplace(sub->watcher); - - bool success = watchDir(sub->watcher, fullpath, sub->tree); - if (!success) { - sub->tree->remove(fullpath); - return false; - } - } - } - } - } - } - - for (auto it = trees.begin(); it != trees.end(); it++) { - std::shared_ptr tree = *it; - for (auto entry = tree->entries.begin(); entry != tree->entries.end();) { - - if ( - entry->first.rfind(dirStart, 0) == 0 && - entry->first.find(DIR_SEP, dirStart.length()) == std::string::npos && - entries.count(entry->first) == 0 - ) { - // Notify all watchers with the same tree. - for (auto i = subs.begin(); i != subs.end(); i++) { - if ((*i)->tree == tree) { - KqueueSubscription *sub = *i; - if (!sub->watcher->isIgnored(entry->first)) { - sub->watcher->mEvents.remove(entry->first); - watchers.emplace(sub->watcher); - } - } - } - - mFdToEntry.erase((int)(size_t)entry->second.state); - mSubscriptions.erase(entry->first); - entry = tree->entries.erase(entry); - } else { - entry++; - } - } - } - - #if __APPLE__ - closedir(dir); - #else - fdclosedir(dir); - #endif - - return true; -} - -void KqueueBackend::unsubscribe(WatcherRef watcher) { - // Find any subscriptions pointing to this watcher, and remove them. - for (auto it = mSubscriptions.begin(); it != mSubscriptions.end();) { - if (it->second.watcher.get() == watcher.get()) { - if (mSubscriptions.count(it->first) == 1) { - // Closing the file descriptor automatically unwatches it in the kqueue. - close(it->second.fd); - mFdToEntry.erase(it->second.fd); - } - - it = mSubscriptions.erase(it); - } else { - it++; - } - } -} diff --git a/node_modules/@parcel/watcher/src/kqueue/KqueueBackend.hh b/node_modules/@parcel/watcher/src/kqueue/KqueueBackend.hh deleted file mode 100644 index 3c6a9cd..0000000 --- a/node_modules/@parcel/watcher/src/kqueue/KqueueBackend.hh +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef KQUEUE_H -#define KQUEUE_H - -#include -#include -#include "../shared/BruteForceBackend.hh" -#include "../DirTree.hh" -#include "../Signal.hh" - -struct KqueueSubscription { - WatcherRef watcher; - std::string path; - std::shared_ptr tree; - int fd; -}; - -class KqueueBackend : public BruteForceBackend { -public: - void start() override; - ~KqueueBackend(); - void subscribe(WatcherRef watcher) override; - void unsubscribe(WatcherRef watcher) override; -private: - int mKqueue; - int mPipe[2]; - std::unordered_multimap mSubscriptions; - std::unordered_map mFdToEntry; - Signal mEndedSignal; - - bool watchDir(WatcherRef watcher, std::string path, std::shared_ptr tree); - bool compareDir(int fd, std::string &dir, std::unordered_set &watchers); - std::vector findSubscriptions(std::string &path); -}; - -#endif diff --git a/node_modules/@parcel/watcher/src/linux/InotifyBackend.cc b/node_modules/@parcel/watcher/src/linux/InotifyBackend.cc deleted file mode 100644 index 949f498..0000000 --- a/node_modules/@parcel/watcher/src/linux/InotifyBackend.cc +++ /dev/null @@ -1,236 +0,0 @@ -#include -#include -#include -#include -#include -#include "InotifyBackend.hh" - -#define INOTIFY_MASK \ - IN_ATTRIB | IN_CREATE | IN_DELETE | \ - IN_DELETE_SELF | IN_MODIFY | IN_MOVE_SELF | IN_MOVED_FROM | \ - IN_MOVED_TO | IN_DONT_FOLLOW | IN_ONLYDIR | IN_EXCL_UNLINK -#define BUFFER_SIZE 8192 -#define CONVERT_TIME(ts) ((uint64_t)ts.tv_sec * 1000000000 + ts.tv_nsec) - -void InotifyBackend::start() { - // Create a pipe that we will write to when we want to end the thread. - int err = pipe2(mPipe, O_CLOEXEC | O_NONBLOCK); - if (err == -1) { - throw std::runtime_error(std::string("Unable to open pipe: ") + strerror(errno)); - } - - // Init inotify file descriptor. - mInotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); - if (mInotify == -1) { - throw std::runtime_error(std::string("Unable to initialize inotify: ") + strerror(errno)); - } - - pollfd pollfds[2]; - pollfds[0].fd = mPipe[0]; - pollfds[0].events = POLLIN; - pollfds[0].revents = 0; - pollfds[1].fd = mInotify; - pollfds[1].events = POLLIN; - pollfds[1].revents = 0; - - notifyStarted(); - - // Loop until we get an event from the pipe. - while (true) { - int result = poll(pollfds, 2, 500); - if (result < 0) { - throw std::runtime_error(std::string("Unable to poll: ") + strerror(errno)); - } - - if (pollfds[0].revents) { - break; - } - - if (pollfds[1].revents) { - handleEvents(); - } - } - - close(mPipe[0]); - close(mPipe[1]); - close(mInotify); - - mEndedSignal.notify(); -} - -InotifyBackend::~InotifyBackend() { - write(mPipe[1], "X", 1); - mEndedSignal.wait(); -} - -// This function is called by Backend::watch which takes a lock on mMutex -void InotifyBackend::subscribe(WatcherRef watcher) { - // Build a full directory tree recursively, and watch each directory. - std::shared_ptr tree = getTree(watcher); - - for (auto it = tree->entries.begin(); it != tree->entries.end(); it++) { - if (it->second.isDir) { - bool success = watchDir(watcher, it->second.path, tree); - if (!success) { - throw WatcherError(std::string("inotify_add_watch on '") + it->second.path + std::string("' failed: ") + strerror(errno), watcher); - } - } - } -} - -bool InotifyBackend::watchDir(WatcherRef watcher, std::string path, std::shared_ptr tree) { - int wd = inotify_add_watch(mInotify, path.c_str(), INOTIFY_MASK); - if (wd == -1) { - return false; - } - - std::shared_ptr sub = std::make_shared(); - sub->tree = tree; - sub->path = path; - sub->watcher = watcher; - mSubscriptions.emplace(wd, sub); - - return true; -} - -void InotifyBackend::handleEvents() { - char buf[BUFFER_SIZE] __attribute__ ((aligned(__alignof__(struct inotify_event))));; - struct inotify_event *event; - - // Track all of the watchers that are touched so we can notify them at the end of the events. - std::unordered_set watchers; - - while (true) { - int n = read(mInotify, &buf, BUFFER_SIZE); - if (n < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - break; - } - - throw std::runtime_error(std::string("Error reading from inotify: ") + strerror(errno)); - } - - if (n == 0) { - break; - } - - for (char *ptr = buf; ptr < buf + n; ptr += sizeof(*event) + event->len) { - event = (struct inotify_event *)ptr; - - if ((event->mask & IN_Q_OVERFLOW) == IN_Q_OVERFLOW) { - // overflow - continue; - } - - handleEvent(event, watchers); - } - } - - for (auto it = watchers.begin(); it != watchers.end(); it++) { - (*it)->notify(); - } -} - -void InotifyBackend::handleEvent(struct inotify_event *event, std::unordered_set &watchers) { - std::unique_lock lock(mMutex); - - // Find the subscriptions for this watch descriptor - auto range = mSubscriptions.equal_range(event->wd); - std::unordered_set> set; - for (auto it = range.first; it != range.second; it++) { - set.insert(it->second); - } - - for (auto it = set.begin(); it != set.end(); it++) { - if (handleSubscription(event, *it)) { - watchers.insert((*it)->watcher); - } - } -} - -bool InotifyBackend::handleSubscription(struct inotify_event *event, std::shared_ptr sub) { - // Build full path and check if its in our ignore list. - std::shared_ptr watcher = sub->watcher; - std::string path = std::string(sub->path); - bool isDir = event->mask & IN_ISDIR; - - if (event->len > 0) { - path += "/" + std::string(event->name); - } - - if (watcher->isIgnored(path)) { - return false; - } - - // If this is a create, check if it's a directory and start watching if it is. - // In any case, keep the directory tree up to date. - if (event->mask & (IN_CREATE | IN_MOVED_TO)) { - watcher->mEvents.create(path); - - struct stat st; - // Use lstat to avoid resolving symbolic links that we cannot watch anyway - // https://github.com/parcel-bundler/watcher/issues/76 - if (lstat(path.c_str(), &st) != 0) { - return false; - } - DirEntry *entry = sub->tree->add(path, CONVERT_TIME(st.st_mtim), S_ISDIR(st.st_mode)); - - if (entry->isDir) { - bool success = watchDir(watcher, path, sub->tree); - if (!success) { - sub->tree->remove(path); - return false; - } - } - } else if (event->mask & (IN_MODIFY | IN_ATTRIB)) { - watcher->mEvents.update(path); - - struct stat st; - if (stat(path.c_str(), &st) != 0) { - return false; - } - sub->tree->update(path, CONVERT_TIME(st.st_mtim)); - } else if (event->mask & (IN_DELETE | IN_DELETE_SELF | IN_MOVED_FROM | IN_MOVE_SELF)) { - bool isSelfEvent = (event->mask & (IN_DELETE_SELF | IN_MOVE_SELF)); - // Ignore delete/move self events unless this is the recursive watch root - if (isSelfEvent && path != watcher->mDir) { - return false; - } - - // If the entry being deleted/moved is a directory, remove it from the list of subscriptions - // XXX: self events don't have the IN_ISDIR mask - if (isSelfEvent || isDir) { - for (auto it = mSubscriptions.begin(); it != mSubscriptions.end();) { - if (it->second->path == path) { - it = mSubscriptions.erase(it); - } else { - ++it; - } - } - } - - watcher->mEvents.remove(path); - sub->tree->remove(path); - } - - return true; -} - -// This function is called by Backend::unwatch which takes a lock on mMutex -void InotifyBackend::unsubscribe(WatcherRef watcher) { - // Find any subscriptions pointing to this watcher, and remove them. - for (auto it = mSubscriptions.begin(); it != mSubscriptions.end();) { - if (it->second->watcher.get() == watcher.get()) { - if (mSubscriptions.count(it->first) == 1) { - int err = inotify_rm_watch(mInotify, it->first); - if (err == -1) { - throw WatcherError(std::string("Unable to remove watcher: ") + strerror(errno), watcher); - } - } - - it = mSubscriptions.erase(it); - } else { - it++; - } - } -} diff --git a/node_modules/@parcel/watcher/src/linux/InotifyBackend.hh b/node_modules/@parcel/watcher/src/linux/InotifyBackend.hh deleted file mode 100644 index f34cd1f..0000000 --- a/node_modules/@parcel/watcher/src/linux/InotifyBackend.hh +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef INOTIFY_H -#define INOTIFY_H - -#include -#include -#include "../shared/BruteForceBackend.hh" -#include "../DirTree.hh" -#include "../Signal.hh" - -struct InotifySubscription { - std::shared_ptr tree; - std::string path; - WatcherRef watcher; -}; - -class InotifyBackend : public BruteForceBackend { -public: - void start() override; - ~InotifyBackend(); - void subscribe(WatcherRef watcher) override; - void unsubscribe(WatcherRef watcher) override; -private: - int mPipe[2]; - int mInotify; - std::unordered_multimap> mSubscriptions; - Signal mEndedSignal; - - bool watchDir(WatcherRef watcher, std::string path, std::shared_ptr tree); - void handleEvents(); - void handleEvent(struct inotify_event *event, std::unordered_set &watchers); - bool handleSubscription(struct inotify_event *event, std::shared_ptr sub); -}; - -#endif diff --git a/node_modules/@parcel/watcher/src/macos/FSEventsBackend.cc b/node_modules/@parcel/watcher/src/macos/FSEventsBackend.cc deleted file mode 100644 index cfda962..0000000 --- a/node_modules/@parcel/watcher/src/macos/FSEventsBackend.cc +++ /dev/null @@ -1,338 +0,0 @@ -#include -#include -#include -#include -#include -#include "../Event.hh" -#include "../Backend.hh" -#include "./FSEventsBackend.hh" -#include "../Watcher.hh" - -#define CONVERT_TIME(ts) ((uint64_t)ts.tv_sec * 1000000000 + ts.tv_nsec) -#define IGNORED_FLAGS (kFSEventStreamEventFlagItemIsHardlink | kFSEventStreamEventFlagItemIsLastHardlink | kFSEventStreamEventFlagItemIsSymlink | kFSEventStreamEventFlagItemIsDir | kFSEventStreamEventFlagItemIsFile) - -void stopStream(FSEventStreamRef stream, CFRunLoopRef runLoop) { - FSEventStreamStop(stream); - FSEventStreamUnscheduleFromRunLoop(stream, runLoop, kCFRunLoopDefaultMode); - FSEventStreamInvalidate(stream); - FSEventStreamRelease(stream); -} - -// macOS has a case insensitive file system by default. In order to detect -// file renames that only affect case, we need to get the canonical path -// and compare it with the input path to determine if a file was created or deleted. -bool pathExists(char *path) { - int fd = open(path, O_RDONLY | O_SYMLINK); - if (fd == -1) { - return false; - } - - char buf[PATH_MAX]; - if (fcntl(fd, F_GETPATH, buf) == -1) { - close(fd); - return false; - } - - bool res = strncmp(path, buf, PATH_MAX) == 0; - close(fd); - return res; -} - -class State: public WatcherState { -public: - FSEventStreamRef stream; - std::shared_ptr tree; - uint64_t since; -}; - -void FSEventsCallback( - ConstFSEventStreamRef streamRef, - void *clientCallBackInfo, - size_t numEvents, - void *eventPaths, - const FSEventStreamEventFlags eventFlags[], - const FSEventStreamEventId eventIds[] -) { - char **paths = (char **)eventPaths; - std::shared_ptr& watcher = *static_cast *>(clientCallBackInfo); - - EventList& list = watcher->mEvents; - if (watcher->state == nullptr) { - return; - } - - auto stateGuard = watcher->state; - auto* state = static_cast(stateGuard.get()); - uint64_t since = state->since; - bool deletedRoot = false; - - for (size_t i = 0; i < numEvents; ++i) { - bool isCreated = (eventFlags[i] & kFSEventStreamEventFlagItemCreated) == kFSEventStreamEventFlagItemCreated; - bool isRemoved = (eventFlags[i] & kFSEventStreamEventFlagItemRemoved) == kFSEventStreamEventFlagItemRemoved; - bool isModified = (eventFlags[i] & kFSEventStreamEventFlagItemModified) == kFSEventStreamEventFlagItemModified || - (eventFlags[i] & kFSEventStreamEventFlagItemInodeMetaMod) == kFSEventStreamEventFlagItemInodeMetaMod || - (eventFlags[i] & kFSEventStreamEventFlagItemFinderInfoMod) == kFSEventStreamEventFlagItemFinderInfoMod || - (eventFlags[i] & kFSEventStreamEventFlagItemChangeOwner) == kFSEventStreamEventFlagItemChangeOwner || - (eventFlags[i] & kFSEventStreamEventFlagItemXattrMod) == kFSEventStreamEventFlagItemXattrMod; - bool isRenamed = (eventFlags[i] & kFSEventStreamEventFlagItemRenamed) == kFSEventStreamEventFlagItemRenamed; - bool isDone = (eventFlags[i] & kFSEventStreamEventFlagHistoryDone) == kFSEventStreamEventFlagHistoryDone; - bool isDir = (eventFlags[i] & kFSEventStreamEventFlagItemIsDir) == kFSEventStreamEventFlagItemIsDir; - - - if (eventFlags[i] & kFSEventStreamEventFlagMustScanSubDirs) { - if (eventFlags[i] & kFSEventStreamEventFlagUserDropped) { - list.error("Events were dropped by the FSEvents client. File system must be re-scanned."); - } else if (eventFlags[i] & kFSEventStreamEventFlagKernelDropped) { - list.error("Events were dropped by the kernel. File system must be re-scanned."); - } else { - list.error("Too many events. File system must be re-scanned."); - } - } - - if (isDone) { - watcher->notify(); - break; - } - - auto ignoredFlags = IGNORED_FLAGS; - if (__builtin_available(macOS 10.13, *)) { - ignoredFlags |= kFSEventStreamEventFlagItemCloned; - } - - // If we don't care about any of the flags that are set, ignore this event. - if ((eventFlags[i] & ~ignoredFlags) == 0) { - continue; - } - - // FSEvents exclusion paths only apply to files, not directories. - if (watcher->isIgnored(paths[i])) { - continue; - } - - // Handle unambiguous events first - if (isCreated && !(isRemoved || isModified || isRenamed)) { - state->tree->add(paths[i], 0, isDir); - list.create(paths[i]); - } else if (isRemoved && !(isCreated || isModified || isRenamed)) { - state->tree->remove(paths[i]); - list.remove(paths[i]); - if (paths[i] == watcher->mDir) { - deletedRoot = true; - } - } else if (isModified && !(isCreated || isRemoved || isRenamed)) { - struct stat file; - if (stat(paths[i], &file)) { - continue; - } - - // Ignore if mtime is the same as the last event. - // This prevents duplicate events from being emitted. - // If tv_nsec is zero, the file system probably only has second-level - // granularity so allow the even through in that case. - uint64_t mtime = CONVERT_TIME(file.st_mtimespec); - DirEntry *entry = state->tree->find(paths[i]); - if (entry && mtime == entry->mtime && file.st_mtimespec.tv_nsec != 0) { - continue; - } - - if (entry) { - // Update mtime. - entry->mtime = mtime; - } else { - // Add to tree if this path has not been discovered yet. - state->tree->add(paths[i], mtime, S_ISDIR(file.st_mode)); - } - - list.update(paths[i]); - } else { - // If multiple flags were set, then we need to call `stat` to determine if the file really exists. - // This helps disambiguate creates, updates, and deletes. - struct stat file; - if (stat(paths[i], &file) || !pathExists(paths[i])) { - // File does not exist, so we have to assume it was removed. This is not exact since the - // flags set by fsevents get coalesced together (e.g. created & deleted), so there is no way to - // know whether the create and delete both happened since our snapshot (in which case - // we'd rather ignore this event completely). This will result in some extra delete events - // being emitted for files we don't know about, but that is the best we can do. - state->tree->remove(paths[i]); - list.remove(paths[i]); - if (paths[i] == watcher->mDir) { - deletedRoot = true; - } - continue; - } - - // If the file was modified, and existed before, then this is an update, otherwise a create. - uint64_t ctime = CONVERT_TIME(file.st_birthtimespec); - uint64_t mtime = CONVERT_TIME(file.st_mtimespec); - DirEntry *entry = !since ? state->tree->find(paths[i]) : NULL; - if (entry && entry->mtime == mtime && file.st_mtimespec.tv_nsec != 0) { - continue; - } - - // Some mounted file systems report a creation time of 0/unix epoch which we special case. - if (isModified && (entry || (ctime <= since && ctime != 0))) { - state->tree->update(paths[i], mtime); - list.update(paths[i]); - } else { - state->tree->add(paths[i], mtime, S_ISDIR(file.st_mode)); - list.create(paths[i]); - } - } - } - - if (!since) { - watcher->notify(); - } - - // Stop watching if the root directory was deleted. - if (deletedRoot) { - stopStream((FSEventStreamRef)streamRef, CFRunLoopGetCurrent()); - watcher->state = nullptr; - } -} - -void checkWatcher(WatcherRef watcher) { - struct stat file; - if (stat(watcher->mDir.c_str(), &file)) { - throw WatcherError(strerror(errno), watcher); - } - - if (!S_ISDIR(file.st_mode)) { - throw WatcherError(strerror(ENOTDIR), watcher); - } -} - -void FSEventsBackend::startStream(WatcherRef watcher, FSEventStreamEventId id) { - checkWatcher(watcher); - - CFAbsoluteTime latency = 0.001; - CFStringRef fileWatchPath = CFStringCreateWithCString( - NULL, - watcher->mDir.c_str(), - kCFStringEncodingUTF8 - ); - - CFArrayRef pathsToWatch = CFArrayCreate( - NULL, - (const void **)&fileWatchPath, - 1, - NULL - ); - - // Make a watcher reference we can pass into the callback. This ensures bumped ref-count. - std::shared_ptr* callbackWatcher = new std::shared_ptr (watcher); - FSEventStreamContext callbackInfo {0, static_cast (callbackWatcher), nullptr, nullptr, nullptr}; - FSEventStreamRef stream = FSEventStreamCreate( - NULL, - &FSEventsCallback, - &callbackInfo, - pathsToWatch, - id, - latency, - kFSEventStreamCreateFlagFileEvents - ); - - CFMutableArrayRef exclusions = CFArrayCreateMutable(NULL, watcher->mIgnorePaths.size(), NULL); - for (auto it = watcher->mIgnorePaths.begin(); it != watcher->mIgnorePaths.end(); it++) { - CFStringRef path = CFStringCreateWithCString( - NULL, - it->c_str(), - kCFStringEncodingUTF8 - ); - - CFArrayAppendValue(exclusions, (const void *)path); - } - - FSEventStreamSetExclusionPaths(stream, exclusions); - - FSEventStreamScheduleWithRunLoop(stream, mRunLoop, kCFRunLoopDefaultMode); - bool started = FSEventStreamStart(stream); - - CFRelease(pathsToWatch); - CFRelease(fileWatchPath); - - if (!started) { - FSEventStreamRelease(stream); - throw WatcherError("Error starting FSEvents stream", watcher); - } - - auto stateGuard = watcher->state; - State* s = static_cast(stateGuard.get()); - s->tree = std::make_shared(watcher->mDir); - s->stream = stream; -} - -void FSEventsBackend::start() { - mRunLoop = CFRunLoopGetCurrent(); - CFRetain(mRunLoop); - - // Unlock once run loop has started. - CFRunLoopPerformBlock(mRunLoop, kCFRunLoopDefaultMode, ^ { - notifyStarted(); - }); - - CFRunLoopWakeUp(mRunLoop); - CFRunLoopRun(); -} - -FSEventsBackend::~FSEventsBackend() { - std::unique_lock lock(mMutex); - CFRunLoopStop(mRunLoop); - CFRelease(mRunLoop); -} - -void FSEventsBackend::writeSnapshot(WatcherRef watcher, std::string *snapshotPath) { - std::unique_lock lock(mMutex); - checkWatcher(watcher); - - FSEventStreamEventId id = FSEventsGetCurrentEventId(); - std::ofstream ofs(*snapshotPath); - ofs << id; - ofs << "\n"; - - struct timespec now; - clock_gettime(CLOCK_REALTIME, &now); - ofs << CONVERT_TIME(now); -} - -void FSEventsBackend::getEventsSince(WatcherRef watcher, std::string *snapshotPath) { - std::unique_lock lock(mMutex); - std::ifstream ifs(*snapshotPath); - if (ifs.fail()) { - return; - } - - FSEventStreamEventId id; - uint64_t since; - ifs >> id; - ifs >> since; - - auto s = std::make_shared(); - s->since = since; - watcher->state = s; - - startStream(watcher, id); - watcher->wait(); - stopStream(s->stream, mRunLoop); - - watcher->state = nullptr; -} - -// This function is called by Backend::watch which takes a lock on mMutex -void FSEventsBackend::subscribe(WatcherRef watcher) { - auto s = std::make_shared(); - s->since = 0; - watcher->state = s; - startStream(watcher, kFSEventStreamEventIdSinceNow); -} - -// This function is called by Backend::unwatch which takes a lock on mMutex -void FSEventsBackend::unsubscribe(WatcherRef watcher) { - auto stateGuard = watcher->state; - State* s = static_cast(stateGuard.get()); - if (s != nullptr) { - stopStream(s->stream, mRunLoop); - watcher->state = nullptr; - } -} diff --git a/node_modules/@parcel/watcher/src/macos/FSEventsBackend.hh b/node_modules/@parcel/watcher/src/macos/FSEventsBackend.hh deleted file mode 100644 index 57ded66..0000000 --- a/node_modules/@parcel/watcher/src/macos/FSEventsBackend.hh +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef FS_EVENTS_H -#define FS_EVENTS_H - -#include -#include "../Backend.hh" - -class FSEventsBackend : public Backend { -public: - void start() override; - ~FSEventsBackend(); - void writeSnapshot(WatcherRef watcher, std::string *snapshotPath) override; - void getEventsSince(WatcherRef watcher, std::string *snapshotPath) override; - void subscribe(WatcherRef watcher) override; - void unsubscribe(WatcherRef watcher) override; -private: - void startStream(WatcherRef watcher, FSEventStreamEventId id); - CFRunLoopRef mRunLoop; -}; - -#endif diff --git a/node_modules/@parcel/watcher/src/shared/BruteForceBackend.cc b/node_modules/@parcel/watcher/src/shared/BruteForceBackend.cc deleted file mode 100644 index 0e9b84f..0000000 --- a/node_modules/@parcel/watcher/src/shared/BruteForceBackend.cc +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include "../DirTree.hh" -#include "../Event.hh" -#include "./BruteForceBackend.hh" - -std::shared_ptr BruteForceBackend::getTree(WatcherRef watcher, bool shouldRead) { - auto tree = DirTree::getCached(watcher->mDir); - - // If the tree is not complete, read it if needed. - if (!tree->isComplete && shouldRead) { - readTree(watcher, tree); - tree->isComplete = true; - } - - return tree; -} - -void BruteForceBackend::writeSnapshot(WatcherRef watcher, std::string *snapshotPath) { - std::unique_lock lock(mMutex); - auto tree = getTree(watcher); - FILE *f = fopen(snapshotPath->c_str(), "w"); - if (!f) { - throw std::runtime_error(std::string("Unable to open snapshot file: ") + strerror(errno)); - } - - tree->write(f); - fclose(f); -} - -void BruteForceBackend::getEventsSince(WatcherRef watcher, std::string *snapshotPath) { - std::unique_lock lock(mMutex); - FILE *f = fopen(snapshotPath->c_str(), "r"); - if (!f) { - throw std::runtime_error(std::string("Unable to open snapshot file: ") + strerror(errno)); - } - - DirTree snapshot{watcher->mDir, f}; - auto now = getTree(watcher); - now->getChanges(&snapshot, watcher->mEvents); - fclose(f); -} diff --git a/node_modules/@parcel/watcher/src/shared/BruteForceBackend.hh b/node_modules/@parcel/watcher/src/shared/BruteForceBackend.hh deleted file mode 100644 index de7a73d..0000000 --- a/node_modules/@parcel/watcher/src/shared/BruteForceBackend.hh +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef BRUTE_FORCE_H -#define BRUTE_FORCE_H - -#include "../Backend.hh" -#include "../DirTree.hh" -#include "../Watcher.hh" - -class BruteForceBackend : public Backend { -public: - void writeSnapshot(WatcherRef watcher, std::string *snapshotPath) override; - void getEventsSince(WatcherRef watcher, std::string *snapshotPath) override; - void subscribe(WatcherRef watcher) override { - throw "Brute force backend doesn't support subscriptions."; - } - - void unsubscribe(WatcherRef watcher) override { - throw "Brute force backend doesn't support subscriptions."; - } - - std::shared_ptr getTree(WatcherRef watcher, bool shouldRead = true); -private: - void readTree(WatcherRef watcher, std::shared_ptr tree); -}; - -#endif diff --git a/node_modules/@parcel/watcher/src/unix/fts.cc b/node_modules/@parcel/watcher/src/unix/fts.cc deleted file mode 100644 index d50c3e4..0000000 --- a/node_modules/@parcel/watcher/src/unix/fts.cc +++ /dev/null @@ -1,50 +0,0 @@ -#include - -// weird error on linux -#ifdef __THROW -#undef __THROW -#endif -#define __THROW - -#include -#include -#include "../DirTree.hh" -#include "../shared/BruteForceBackend.hh" - -#define CONVERT_TIME(ts) ((uint64_t)ts.tv_sec * 1000000000 + ts.tv_nsec) -#if __APPLE__ -#define st_mtim st_mtimespec -#endif - -void BruteForceBackend::readTree(WatcherRef watcher, std::shared_ptr tree) { - char *paths[2] {(char *)watcher->mDir.c_str(), NULL}; - FTS *fts = fts_open(paths, FTS_NOCHDIR | FTS_PHYSICAL, NULL); - if (!fts) { - throw WatcherError(strerror(errno), watcher); - } - - FTSENT *node; - bool isRoot = true; - - while ((node = fts_read(fts)) != NULL) { - if (node->fts_errno) { - fts_close(fts); - throw WatcherError(strerror(node->fts_errno), watcher); - } - - if (isRoot && !(node->fts_info & FTS_D)) { - fts_close(fts); - throw WatcherError(strerror(ENOTDIR), watcher); - } - - if (watcher->isIgnored(std::string(node->fts_path))) { - fts_set(fts, node, FTS_SKIP); - continue; - } - - tree->add(node->fts_path, CONVERT_TIME(node->fts_statp->st_mtim), (node->fts_info & FTS_D) == FTS_D); - isRoot = false; - } - - fts_close(fts); -} diff --git a/node_modules/@parcel/watcher/src/unix/legacy.cc b/node_modules/@parcel/watcher/src/unix/legacy.cc deleted file mode 100644 index 60490c6..0000000 --- a/node_modules/@parcel/watcher/src/unix/legacy.cc +++ /dev/null @@ -1,77 +0,0 @@ -#include - -// weird error on linux -#ifdef __THROW -#undef __THROW -#endif -#define __THROW - -#ifdef _LIBC -# include -#else -# include -#endif -#include -#include -#include - -#include "../DirTree.hh" -#include "../shared/BruteForceBackend.hh" - -#define CONVERT_TIME(ts) ((uint64_t)ts.tv_sec * 1000000000 + ts.tv_nsec) -#if __APPLE__ -#define st_mtim st_mtimespec -#endif -#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2]))) - -void iterateDir(WatcherRef watcher, const std::shared_ptr tree, const char *relative, int parent_fd, const std::string &dirname) { - int open_flags = (O_RDONLY | O_CLOEXEC | O_DIRECTORY | O_NOCTTY | O_NONBLOCK | O_NOFOLLOW); - int new_fd = openat(parent_fd, relative, open_flags); - if (new_fd == -1) { - if (errno == EACCES) { - return; // ignore insufficient permissions - } - - throw WatcherError(strerror(errno), watcher); - } - - struct stat rootAttributes; - fstatat(new_fd, ".", &rootAttributes, AT_SYMLINK_NOFOLLOW); - tree->add(dirname, CONVERT_TIME(rootAttributes.st_mtim), true); - - if (DIR *dir = fdopendir(new_fd)) { - while (struct dirent *ent = (errno = 0, readdir(dir))) { - if (ISDOT(ent->d_name)) continue; - - std::string fullPath = dirname + "/" + ent->d_name; - - if (!watcher->isIgnored(fullPath)) { - struct stat attrib; - fstatat(new_fd, ent->d_name, &attrib, AT_SYMLINK_NOFOLLOW); - bool isDir = ent->d_type == DT_DIR; - - if (isDir) { - iterateDir(watcher, tree, ent->d_name, new_fd, fullPath); - } else { - tree->add(fullPath, CONVERT_TIME(attrib.st_mtim), isDir); - } - } - } - - closedir(dir); - } else { - close(new_fd); - } - - if (errno) { - throw WatcherError(strerror(errno), watcher); - } -} - -void BruteForceBackend::readTree(WatcherRef watcher, std::shared_ptr tree) { - int fd = open(watcher->mDir.c_str(), O_RDONLY); - if (fd) { - iterateDir(watcher, tree, ".", fd, watcher->mDir); - close(fd); - } -} diff --git a/node_modules/@parcel/watcher/src/wasm/WasmBackend.cc b/node_modules/@parcel/watcher/src/wasm/WasmBackend.cc deleted file mode 100644 index 9514109..0000000 --- a/node_modules/@parcel/watcher/src/wasm/WasmBackend.cc +++ /dev/null @@ -1,132 +0,0 @@ -#include -#include "WasmBackend.hh" - -#define CONVERT_TIME(ts) ((uint64_t)ts.tv_sec * 1000000000 + ts.tv_nsec) - -void WasmBackend::start() { - notifyStarted(); -} - -void WasmBackend::subscribe(WatcherRef watcher) { - // Build a full directory tree recursively, and watch each directory. - std::shared_ptr tree = getTree(watcher); - - for (auto it = tree->entries.begin(); it != tree->entries.end(); it++) { - if (it->second.isDir) { - watchDir(watcher, it->second.path, tree); - } - } -} - -void WasmBackend::watchDir(WatcherRef watcher, std::string path, std::shared_ptr tree) { - int wd = wasm_backend_add_watch(path.c_str(), (void *)this); - std::shared_ptr sub = std::make_shared(); - sub->tree = tree; - sub->path = path; - sub->watcher = watcher; - mSubscriptions.emplace(wd, sub); -} - -extern "C" void wasm_backend_event_handler(void *backend, int wd, int type, char *filename) { - WasmBackend *b = (WasmBackend *)(backend); - b->handleEvent(wd, type, filename); -} - -void WasmBackend::handleEvent(int wd, int type, char *filename) { - // Find the subscriptions for this watch descriptor - auto range = mSubscriptions.equal_range(wd); - std::unordered_set> set; - for (auto it = range.first; it != range.second; it++) { - set.insert(it->second); - } - - for (auto it = set.begin(); it != set.end(); it++) { - if (handleSubscription(type, filename, *it)) { - (*it)->watcher->notify(); - } - } -} - -bool WasmBackend::handleSubscription(int type, char *filename, std::shared_ptr sub) { - // Build full path and check if its in our ignore list. - WatcherRef watcher = sub->watcher; - std::string path = std::string(sub->path); - - if (filename[0] != '\0') { - path += "/" + std::string(filename); - } - - if (watcher->isIgnored(path)) { - return false; - } - - if (type == 1) { - struct stat st; - stat(path.c_str(), &st); - sub->tree->update(path, CONVERT_TIME(st.st_mtim)); - watcher->mEvents.update(path); - } else if (type == 2) { - // Determine if this is a create or delete depending on if the file exists or not. - struct stat st; - if (lstat(path.c_str(), &st)) { - // If the entry being deleted/moved is a directory, remove it from the list of subscriptions - DirEntry *entry = sub->tree->find(path); - if (!entry) { - return false; - } - - if (entry->isDir) { - std::string pathStart = path + DIR_SEP; - for (auto it = mSubscriptions.begin(); it != mSubscriptions.end();) { - if (it->second->path == path || it->second->path.rfind(pathStart, 0) == 0) { - wasm_backend_remove_watch(it->first); - it = mSubscriptions.erase(it); - } else { - ++it; - } - } - - // Remove all sub-entries - for (auto it = sub->tree->entries.begin(); it != sub->tree->entries.end();) { - if (it->first.rfind(pathStart, 0) == 0) { - watcher->mEvents.remove(it->first); - it = sub->tree->entries.erase(it); - } else { - it++; - } - } - } - - watcher->mEvents.remove(path); - sub->tree->remove(path); - } else if (sub->tree->find(path)) { - sub->tree->update(path, CONVERT_TIME(st.st_mtim)); - watcher->mEvents.update(path); - } else { - watcher->mEvents.create(path); - - // If this is a create, check if it's a directory and start watching if it is. - DirEntry *entry = sub->tree->add(path, CONVERT_TIME(st.st_mtim), S_ISDIR(st.st_mode)); - if (entry->isDir) { - watchDir(watcher, path, sub->tree); - } - } - } - - return true; -} - -void WasmBackend::unsubscribe(WatcherRef watcher) { - // Find any subscriptions pointing to this watcher, and remove them. - for (auto it = mSubscriptions.begin(); it != mSubscriptions.end();) { - if (it->second->watcher.get() == watcher.get()) { - if (mSubscriptions.count(it->first) == 1) { - wasm_backend_remove_watch(it->first); - } - - it = mSubscriptions.erase(it); - } else { - it++; - } - } -} diff --git a/node_modules/@parcel/watcher/src/wasm/WasmBackend.hh b/node_modules/@parcel/watcher/src/wasm/WasmBackend.hh deleted file mode 100644 index 9facac8..0000000 --- a/node_modules/@parcel/watcher/src/wasm/WasmBackend.hh +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef WASM_H -#define WASM_H - -#include -#include "../shared/BruteForceBackend.hh" -#include "../DirTree.hh" - -extern "C" { - int wasm_backend_add_watch(const char *filename, void *backend); - void wasm_backend_remove_watch(int wd); - void wasm_backend_event_handler(void *backend, int wd, int type, char *filename); -}; - -struct WasmSubscription { - std::shared_ptr tree; - std::string path; - WatcherRef watcher; -}; - -class WasmBackend : public BruteForceBackend { -public: - void start() override; - void subscribe(WatcherRef watcher) override; - void unsubscribe(WatcherRef watcher) override; - void handleEvent(int wd, int type, char *filename); -private: - int mWasm; - std::unordered_multimap> mSubscriptions; - - void watchDir(WatcherRef watcher, std::string path, std::shared_ptr tree); - bool handleSubscription(int type, char *filename, std::shared_ptr sub); -}; - -#endif diff --git a/node_modules/@parcel/watcher/src/wasm/include.h b/node_modules/@parcel/watcher/src/wasm/include.h deleted file mode 100644 index 60e4d65..0000000 --- a/node_modules/@parcel/watcher/src/wasm/include.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -Copyright Node.js contributors. 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. -*/ - -// Node does not include the headers for these functions when compiling for WASM, so add them here. -#ifdef __wasm32__ -extern "C" { -NAPI_EXTERN napi_status NAPI_CDECL -napi_create_threadsafe_function(napi_env env, - napi_value func, - napi_value async_resource, - napi_value async_resource_name, - size_t max_queue_size, - size_t initial_thread_count, - void* thread_finalize_data, - napi_finalize thread_finalize_cb, - void* context, - napi_threadsafe_function_call_js call_js_cb, - napi_threadsafe_function* result); - -NAPI_EXTERN napi_status NAPI_CDECL napi_get_threadsafe_function_context( - napi_threadsafe_function func, void** result); - -NAPI_EXTERN napi_status NAPI_CDECL -napi_call_threadsafe_function(napi_threadsafe_function func, - void* data, - napi_threadsafe_function_call_mode is_blocking); - -NAPI_EXTERN napi_status NAPI_CDECL -napi_acquire_threadsafe_function(napi_threadsafe_function func); - -NAPI_EXTERN napi_status NAPI_CDECL napi_release_threadsafe_function( - napi_threadsafe_function func, napi_threadsafe_function_release_mode mode); - -NAPI_EXTERN napi_status NAPI_CDECL -napi_unref_threadsafe_function(napi_env env, napi_threadsafe_function func); - -NAPI_EXTERN napi_status NAPI_CDECL -napi_ref_threadsafe_function(napi_env env, napi_threadsafe_function func); - -NAPI_EXTERN napi_status NAPI_CDECL -napi_create_async_work(napi_env env, - napi_value async_resource, - napi_value async_resource_name, - napi_async_execute_callback execute, - napi_async_complete_callback complete, - void* data, - napi_async_work* result); -NAPI_EXTERN napi_status NAPI_CDECL napi_delete_async_work(napi_env env, - napi_async_work work); -NAPI_EXTERN napi_status NAPI_CDECL napi_queue_async_work(napi_env env, - napi_async_work work); -NAPI_EXTERN napi_status NAPI_CDECL napi_cancel_async_work(napi_env env, - napi_async_work work); -} -#endif diff --git a/node_modules/@parcel/watcher/src/watchman/BSER.cc b/node_modules/@parcel/watcher/src/watchman/BSER.cc deleted file mode 100644 index 82390dd..0000000 --- a/node_modules/@parcel/watcher/src/watchman/BSER.cc +++ /dev/null @@ -1,302 +0,0 @@ -#include -#include "./BSER.hh" - -BSERType decodeType(std::istream &iss) { - int8_t type; - iss.read(reinterpret_cast(&type), sizeof(type)); - return (BSERType) type; -} - -void expectType(std::istream &iss, BSERType expected) { - BSERType got = decodeType(iss); - if (got != expected) { - throw std::runtime_error("Unexpected BSER type"); - } -} - -void encodeType(std::ostream &oss, BSERType type) { - int8_t t = (int8_t)type; - oss.write(reinterpret_cast(&t), sizeof(t)); -} - -template -class Value : public BSERValue { -public: - T value; - Value(T val) { - value = val; - } - - Value() {} -}; - -class BSERInteger : public Value { -public: - BSERInteger(int64_t value) : Value(value) {} - BSERInteger(std::istream &iss) { - int8_t int8; - int16_t int16; - int32_t int32; - int64_t int64; - - BSERType type = decodeType(iss); - - switch (type) { - case BSER_INT8: - iss.read(reinterpret_cast(&int8), sizeof(int8)); - value = int8; - break; - case BSER_INT16: - iss.read(reinterpret_cast(&int16), sizeof(int16)); - value = int16; - break; - case BSER_INT32: - iss.read(reinterpret_cast(&int32), sizeof(int32)); - value = int32; - break; - case BSER_INT64: - iss.read(reinterpret_cast(&int64), sizeof(int64)); - value = int64; - break; - default: - throw std::runtime_error("Invalid BSER int type"); - } - } - - int64_t intValue() override { - return value; - } - - void encode(std::ostream &oss) override { - if (value <= INT8_MAX) { - encodeType(oss, BSER_INT8); - int8_t v = (int8_t)value; - oss.write(reinterpret_cast(&v), sizeof(v)); - } else if (value <= INT16_MAX) { - encodeType(oss, BSER_INT16); - int16_t v = (int16_t)value; - oss.write(reinterpret_cast(&v), sizeof(v)); - } else if (value <= INT32_MAX) { - encodeType(oss, BSER_INT32); - int32_t v = (int32_t)value; - oss.write(reinterpret_cast(&v), sizeof(v)); - } else { - encodeType(oss, BSER_INT64); - oss.write(reinterpret_cast(&value), sizeof(value)); - } - } -}; - -class BSERArray : public Value { -public: - BSERArray() : Value() {} - BSERArray(BSER::Array value) : Value(value) {} - BSERArray(std::istream &iss) { - expectType(iss, BSER_ARRAY); - int64_t len = BSERInteger(iss).intValue(); - for (int64_t i = 0; i < len; i++) { - value.push_back(BSER(iss)); - } - } - - BSER::Array arrayValue() override { - return value; - } - - void encode(std::ostream &oss) override { - encodeType(oss, BSER_ARRAY); - BSERInteger(value.size()).encode(oss); - for (auto it = value.begin(); it != value.end(); it++) { - it->encode(oss); - } - } -}; - -class BSERString : public Value { -public: - BSERString(std::string value) : Value(value) {} - BSERString(std::istream &iss) { - expectType(iss, BSER_STRING); - int64_t len = BSERInteger(iss).intValue(); - value.resize(len); - iss.read(&value[0], len); - } - - std::string stringValue() override { - return value; - } - - void encode(std::ostream &oss) override { - encodeType(oss, BSER_STRING); - BSERInteger(value.size()).encode(oss); - oss << value; - } -}; - -class BSERObject : public Value { -public: - BSERObject() : Value() {} - BSERObject(BSER::Object value) : Value(value) {} - BSERObject(std::istream &iss) { - expectType(iss, BSER_OBJECT); - int64_t len = BSERInteger(iss).intValue(); - for (int64_t i = 0; i < len; i++) { - auto key = BSERString(iss).stringValue(); - auto val = BSER(iss); - value.emplace(key, val); - } - } - - BSER::Object objectValue() override { - return value; - } - - void encode(std::ostream &oss) override { - encodeType(oss, BSER_OBJECT); - BSERInteger(value.size()).encode(oss); - for (auto it = value.begin(); it != value.end(); it++) { - BSERString(it->first).encode(oss); - it->second.encode(oss); - } - } -}; - -class BSERDouble : public Value { -public: - BSERDouble(double value) : Value(value) {} - BSERDouble(std::istream &iss) { - expectType(iss, BSER_REAL); - iss.read(reinterpret_cast(&value), sizeof(value)); - } - - double doubleValue() override { - return value; - } - - void encode(std::ostream &oss) override { - encodeType(oss, BSER_REAL); - oss.write(reinterpret_cast(&value), sizeof(value)); - } -}; - -class BSERBoolean : public Value { -public: - BSERBoolean(bool value) : Value(value) {} - bool boolValue() override { return value; } - void encode(std::ostream &oss) override { - int8_t t = value == true ? static_cast(BSER_BOOL_TRUE) : static_cast(BSER_BOOL_FALSE); - oss.write(reinterpret_cast(&t), sizeof(t)); - } -}; - -class BSERNull : public Value { -public: - BSERNull() : Value(false) {} - void encode(std::ostream &oss) override { - encodeType(oss, BSER_NULL); - } -}; - -std::shared_ptr decodeTemplate(std::istream &iss) { - expectType(iss, BSER_TEMPLATE); - auto keys = BSERArray(iss).arrayValue(); - auto len = BSERInteger(iss).intValue(); - std::shared_ptr arr = std::make_shared(); - for (int64_t i = 0; i < len; i++) { - BSER::Object obj; - for (auto it = keys.begin(); it != keys.end(); it++) { - if (iss.peek() == 0x0c) { - iss.ignore(1); - continue; - } - - auto val = BSER(iss); - obj.emplace(it->stringValue(), val); - } - arr->value.push_back(obj); - } - return arr; -} - -BSER::BSER(std::istream &iss) { - BSERType type = decodeType(iss); - iss.unget(); - - switch (type) { - case BSER_ARRAY: - m_ptr = std::make_shared(iss); - break; - case BSER_OBJECT: - m_ptr = std::make_shared(iss); - break; - case BSER_STRING: - m_ptr = std::make_shared(iss); - break; - case BSER_INT8: - case BSER_INT16: - case BSER_INT32: - case BSER_INT64: - m_ptr = std::make_shared(iss); - break; - case BSER_REAL: - m_ptr = std::make_shared(iss); - break; - case BSER_BOOL_TRUE: - iss.ignore(1); - m_ptr = std::make_shared(true); - break; - case BSER_BOOL_FALSE: - iss.ignore(1); - m_ptr = std::make_shared(false); - break; - case BSER_NULL: - iss.ignore(1); - m_ptr = std::make_shared(); - break; - case BSER_TEMPLATE: - m_ptr = decodeTemplate(iss); - break; - default: - throw std::runtime_error("unknown BSER type"); - } -} - -BSER::BSER() : m_ptr(std::make_shared()) {} -BSER::BSER(BSER::Array value) : m_ptr(std::make_shared(value)) {} -BSER::BSER(BSER::Object value) : m_ptr(std::make_shared(value)) {} -BSER::BSER(const char *value) : m_ptr(std::make_shared(value)) {} -BSER::BSER(std::string value) : m_ptr(std::make_shared(value)) {} -BSER::BSER(int64_t value) : m_ptr(std::make_shared(value)) {} -BSER::BSER(double value) : m_ptr(std::make_shared(value)) {} -BSER::BSER(bool value) : m_ptr(std::make_shared(value)) {} - -BSER::Array BSER::arrayValue() { return m_ptr->arrayValue(); } -BSER::Object BSER::objectValue() { return m_ptr->objectValue(); } -std::string BSER::stringValue() { return m_ptr->stringValue(); } -int64_t BSER::intValue() { return m_ptr->intValue(); } -double BSER::doubleValue() { return m_ptr->doubleValue(); } -bool BSER::boolValue() { return m_ptr->boolValue(); } -void BSER::encode(std::ostream &oss) { - m_ptr->encode(oss); -} - -int64_t BSER::decodeLength(std::istream &iss) { - char pdu[2]; - if (!iss.read(pdu, 2) || pdu[0] != 0 || pdu[1] != 1) { - throw std::runtime_error("Invalid BSER"); - } - - return BSERInteger(iss).intValue(); -} - -std::string BSER::encode() { - std::ostringstream oss(std::ios_base::binary); - encode(oss); - - std::ostringstream res(std::ios_base::binary); - res.write("\x00\x01", 2); - - BSERInteger(oss.str().size()).encode(res); - res << oss.str(); - return res.str(); -} diff --git a/node_modules/@parcel/watcher/src/watchman/BSER.hh b/node_modules/@parcel/watcher/src/watchman/BSER.hh deleted file mode 100644 index 6bd2025..0000000 --- a/node_modules/@parcel/watcher/src/watchman/BSER.hh +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef BSER_H -#define BSER_H - -#include -#include -#include -#include -#include - -enum BSERType { - BSER_ARRAY = 0x00, - BSER_OBJECT = 0x01, - BSER_STRING = 0x02, - BSER_INT8 = 0x03, - BSER_INT16 = 0x04, - BSER_INT32 = 0x05, - BSER_INT64 = 0x06, - BSER_REAL = 0x07, - BSER_BOOL_TRUE = 0x08, - BSER_BOOL_FALSE = 0x09, - BSER_NULL = 0x0a, - BSER_TEMPLATE = 0x0b -}; - -class BSERValue; - -class BSER { -public: - typedef std::vector Array; - typedef std::unordered_map Object; - - BSER(); - BSER(BSER::Array value); - BSER(BSER::Object value); - BSER(std::string value); - BSER(const char *value); - BSER(int64_t value); - BSER(double value); - BSER(bool value); - BSER(std::istream &iss); - - BSER::Array arrayValue(); - BSER::Object objectValue(); - std::string stringValue(); - int64_t intValue(); - double doubleValue(); - bool boolValue(); - void encode(std::ostream &oss); - - static int64_t decodeLength(std::istream &iss); - std::string encode(); -private: - std::shared_ptr m_ptr; -}; - -class BSERValue { -protected: - friend class BSER; - virtual BSER::Array arrayValue() { return BSER::Array(); } - virtual BSER::Object objectValue() { return BSER::Object(); } - virtual std::string stringValue() { return std::string(); } - virtual int64_t intValue() { return 0; } - virtual double doubleValue() { return 0; } - virtual bool boolValue() { return false; } - virtual void encode(std::ostream &oss) {} - virtual ~BSERValue() {} -}; - -#endif diff --git a/node_modules/@parcel/watcher/src/watchman/IPC.hh b/node_modules/@parcel/watcher/src/watchman/IPC.hh deleted file mode 100644 index 94aa62f..0000000 --- a/node_modules/@parcel/watcher/src/watchman/IPC.hh +++ /dev/null @@ -1,175 +0,0 @@ -#ifndef IPC_H -#define IPC_H - -#include -#include - -#ifdef _WIN32 -#include -#include -#else -#include -#include -#include -#endif - -class IPC { -public: - IPC(std::string path) { - mStopped = false; - #ifdef _WIN32 - while (true) { - mPipe = CreateFile( - path.data(), // pipe name - GENERIC_READ | GENERIC_WRITE, // read and write access - 0, // no sharing - NULL, // default security attributes - OPEN_EXISTING, // opens existing pipe - FILE_FLAG_OVERLAPPED, // attributes - NULL // no template file - ); - - if (mPipe != INVALID_HANDLE_VALUE) { - break; - } - - if (GetLastError() != ERROR_PIPE_BUSY) { - throw std::runtime_error("Could not open pipe"); - } - - // Wait for pipe to become available if it is busy - if (!WaitNamedPipe(path.data(), 30000)) { - throw std::runtime_error("Error waiting for pipe"); - } - } - - mReader = CreateEvent(NULL, true, false, NULL); - mWriter = CreateEvent(NULL, true, false, NULL); - #else - struct sockaddr_un addr; - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path) - 1); - - mSock = socket(AF_UNIX, SOCK_STREAM, 0); - if (connect(mSock, (struct sockaddr *) &addr, sizeof(struct sockaddr_un))) { - throw std::runtime_error("Error connecting to socket"); - } - #endif - } - - ~IPC() { - mStopped = true; - #ifdef _WIN32 - CancelIo(mPipe); - CloseHandle(mPipe); - CloseHandle(mReader); - CloseHandle(mWriter); - #else - shutdown(mSock, SHUT_RDWR); - #endif - } - - void write(std::string buf) { - #ifdef _WIN32 - OVERLAPPED overlapped; - overlapped.hEvent = mWriter; - bool success = WriteFile( - mPipe, // pipe handle - buf.data(), // message - static_cast(buf.size()), // message length - NULL, // bytes written - &overlapped // overlapped - ); - - if (mStopped) { - return; - } - - if (!success) { - if (GetLastError() != ERROR_IO_PENDING) { - throw std::runtime_error("Write error"); - } - } - - DWORD written; - success = GetOverlappedResult(mPipe, &overlapped, &written, true); - if (!success) { - throw std::runtime_error("GetOverlappedResult failed"); - } - - if (written != buf.size()) { - throw std::runtime_error("Wrong number of bytes written"); - } - #else - int r = 0; - for (unsigned int i = 0; i != buf.size(); i += r) { - r = ::write(mSock, &buf[i], buf.size() - i); - if (r == -1) { - if (errno == EAGAIN) { - r = 0; - } else if (mStopped) { - return; - } else { - throw std::runtime_error("Write error"); - } - } - } - #endif - } - - int read(char *buf, size_t len) { - #ifdef _WIN32 - OVERLAPPED overlapped; - overlapped.hEvent = mReader; - bool success = ReadFile( - mPipe, // pipe handle - buf, // buffer to receive reply - static_cast(len), // size of buffer - NULL, // number of bytes read - &overlapped // overlapped - ); - - if (!success && !mStopped) { - if (GetLastError() != ERROR_IO_PENDING) { - throw std::runtime_error("Read error"); - } - } - - DWORD read = 0; - success = GetOverlappedResult(mPipe, &overlapped, &read, true); - if (!success && !mStopped) { - throw std::runtime_error("GetOverlappedResult failed"); - } - - return read; - #else - int r = ::read(mSock, buf, len); - if (r == 0 && !mStopped) { - throw std::runtime_error("Socket ended unexpectedly"); - } - - if (r < 0) { - if (mStopped) { - return 0; - } - - throw std::runtime_error(strerror(errno)); - } - - return r; - #endif - } - -private: - bool mStopped; - #ifdef _WIN32 - HANDLE mPipe; - HANDLE mReader; - HANDLE mWriter; - #else - int mSock; - #endif -}; - -#endif diff --git a/node_modules/@parcel/watcher/src/watchman/WatchmanBackend.cc b/node_modules/@parcel/watcher/src/watchman/WatchmanBackend.cc deleted file mode 100644 index a442f16..0000000 --- a/node_modules/@parcel/watcher/src/watchman/WatchmanBackend.cc +++ /dev/null @@ -1,342 +0,0 @@ -#include -#include -#include -#include -#include "../DirTree.hh" -#include "../Event.hh" -#include "./BSER.hh" -#include "./WatchmanBackend.hh" - -#ifdef _WIN32 -#include "../windows/win_utils.hh" -#define S_ISDIR(mode) ((mode & _S_IFDIR) == _S_IFDIR) -#define popen _popen -#define pclose _pclose -#else -#include -#define normalizePath(dir) dir -#endif - -template -BSER readBSER(T &&do_read) { - std::stringstream oss; - char buffer[256]; - size_t r; - int64_t len = -1; - do { - // Start by reading a minimal amount of data in order to decode the length. - // After that, attempt to read the remaining length, up to the buffer size. - r = do_read(buffer, len == -1 ? 20 : (len < 256 ? len : 256)); - oss << std::string(buffer, r); - - if (len == -1) { - uint64_t l = BSER::decodeLength(oss); - len = l + oss.tellg(); - } - - len -= r; - } while (len > 0); - - return BSER(oss); -} - -std::string getSockPath() { - auto var = getenv("WATCHMAN_SOCK"); - if (var && *var) { - return std::string(var); - } - -#ifdef _WIN32 - FILE *fp = popen("watchman --output-encoding=bser get-sockname", "r"); -#else - FILE *fp = popen("watchman --output-encoding=bser get-sockname 2>/dev/null", "r"); -#endif - if (fp == NULL || errno == ECHILD) { - throw std::runtime_error("Failed to execute watchman"); - } - - BSER b = readBSER([fp] (char *buf, size_t len) { - return fread(buf, sizeof(char), len, fp); - }); - - pclose(fp); - - auto objValue = b.objectValue(); - auto foundSockname = objValue.find("sockname"); - if (foundSockname == objValue.end()) { - throw std::runtime_error("sockname not found"); - } - return foundSockname->second.stringValue(); -} - -std::unique_ptr watchmanConnect() { - std::string path = getSockPath(); - return std::unique_ptr(new IPC(path)); -} - -BSER watchmanRead(IPC *ipc) { - return readBSER([ipc] (char *buf, size_t len) { - return ipc->read(buf, len); - }); -} - -BSER::Object WatchmanBackend::watchmanRequest(BSER b) { - std::string cmd = b.encode(); - mIPC->write(cmd); - mRequestSignal.notify(); - - mResponseSignal.wait(); - mResponseSignal.reset(); - - if (!mError.empty()) { - std::runtime_error err = std::runtime_error(mError); - mError = std::string(); - throw err; - } - - return mResponse; -} - -void WatchmanBackend::watchmanWatch(std::string dir) { - std::vector cmd; - cmd.push_back("watch"); - cmd.push_back(normalizePath(dir)); - watchmanRequest(cmd); -} - -bool WatchmanBackend::checkAvailable() { - try { - watchmanConnect(); - return true; - } catch (std::exception&) { - return false; - } -} - -void handleFiles(WatcherRef watcher, BSER::Object obj) { - auto found = obj.find("files"); - if (found == obj.end()) { - throw WatcherError("Error reading changes from watchman", watcher); - } - - auto files = found->second.arrayValue(); - for (auto it = files.begin(); it != files.end(); it++) { - auto file = it->objectValue(); - auto name = file.find("name")->second.stringValue(); - #ifdef _WIN32 - std::replace(name.begin(), name.end(), '/', '\\'); - #endif - auto mode = file.find("mode")->second.intValue(); - auto isNew = file.find("new")->second.boolValue(); - auto exists = file.find("exists")->second.boolValue(); - auto path = watcher->mDir + DIR_SEP + name; - if (watcher->isIgnored(path)) { - continue; - } - - if (isNew && exists) { - watcher->mEvents.create(path); - } else if (exists && !S_ISDIR(mode)) { - watcher->mEvents.update(path); - } else if (!isNew && !exists) { - watcher->mEvents.remove(path); - } - } -} - -void WatchmanBackend::handleSubscription(BSER::Object obj) { - std::unique_lock lock(mMutex); - auto subscription = obj.find("subscription")->second.stringValue(); - auto it = mSubscriptions.find(subscription); - if (it == mSubscriptions.end()) { - return; - } - - auto watcher = it->second; - try { - handleFiles(watcher, obj); - watcher->notify(); - } catch (WatcherError &err) { - handleWatcherError(err); - } -} - -void WatchmanBackend::start() { - mIPC = watchmanConnect(); - notifyStarted(); - - while (true) { - // If there are no subscriptions we are reading, wait for a request. - if (mSubscriptions.size() == 0) { - mRequestSignal.wait(); - mRequestSignal.reset(); - } - - // Break out of loop if we are stopped. - if (mStopped) { - break; - } - - // Attempt to read from the socket. - // If there is an error and we are stopped, break. - BSER b; - try { - b = watchmanRead(&*mIPC); - } catch (std::exception &err) { - if (mStopped) { - break; - } else if (mResponseSignal.isWaiting()) { - mError = err.what(); - mResponseSignal.notify(); - } else { - // Throwing causes the backend to be destroyed, but we never reach the code below to notify the signal - mEndedSignal.notify(); - throw; - } - } - - auto obj = b.objectValue(); - auto error = obj.find("error"); - if (error != obj.end()) { - mError = error->second.stringValue(); - mResponseSignal.notify(); - continue; - } - - // If this message is for a subscription, handle it, otherwise notify the request. - auto subscription = obj.find("subscription"); - if (subscription != obj.end()) { - handleSubscription(obj); - } else { - mResponse = obj; - mResponseSignal.notify(); - } - } - - mEndedSignal.notify(); -} - -WatchmanBackend::~WatchmanBackend() { - // Mark the watcher as stopped, close the socket, and trigger the lock. - // This will cause the read loop to be broken and the thread to exit. - mStopped = true; - mIPC.reset(); - mRequestSignal.notify(); - - // If not ended yet, wait. - mEndedSignal.wait(); -} - -std::string WatchmanBackend::clock(WatcherRef watcher) { - BSER::Array cmd; - cmd.push_back("clock"); - cmd.push_back(normalizePath(watcher->mDir)); - - BSER::Object obj = watchmanRequest(cmd); - auto found = obj.find("clock"); - if (found == obj.end()) { - throw WatcherError("Error reading clock from watchman", watcher); - } - - return found->second.stringValue(); -} - -void WatchmanBackend::writeSnapshot(WatcherRef watcher, std::string *snapshotPath) { - std::unique_lock lock(mMutex); - watchmanWatch(watcher->mDir); - - std::ofstream ofs(*snapshotPath); - ofs << clock(watcher); -} - -void WatchmanBackend::getEventsSince(WatcherRef watcher, std::string *snapshotPath) { - std::unique_lock lock(mMutex); - std::ifstream ifs(*snapshotPath); - if (ifs.fail()) { - return; - } - - watchmanWatch(watcher->mDir); - - std::string clock; - ifs >> clock; - - BSER::Array cmd; - cmd.push_back("since"); - cmd.push_back(normalizePath(watcher->mDir)); - cmd.push_back(clock); - - BSER::Object obj = watchmanRequest(cmd); - handleFiles(watcher, obj); -} - -std::string getId(WatcherRef watcher) { - std::ostringstream id; - id << "parcel-"; - id << static_cast(watcher.get()); - return id.str(); -} - -// This function is called by Backend::watch which takes a lock on mMutex -void WatchmanBackend::subscribe(WatcherRef watcher) { - watchmanWatch(watcher->mDir); - - std::string id = getId(watcher); - BSER::Array cmd; - cmd.push_back("subscribe"); - cmd.push_back(normalizePath(watcher->mDir)); - cmd.push_back(id); - - BSER::Array fields; - fields.push_back("name"); - fields.push_back("mode"); - fields.push_back("exists"); - fields.push_back("new"); - - BSER::Object opts; - opts.emplace("fields", fields); - opts.emplace("since", clock(watcher)); - - if (watcher->mIgnorePaths.size() > 0) { - BSER::Array ignore; - BSER::Array anyOf; - anyOf.push_back("anyof"); - - for (auto it = watcher->mIgnorePaths.begin(); it != watcher->mIgnorePaths.end(); it++) { - std::string pathStart = watcher->mDir + DIR_SEP; - if (it->rfind(pathStart, 0) == 0) { - auto relative = it->substr(pathStart.size()); - BSER::Array dirname; - dirname.push_back("dirname"); - dirname.push_back(relative); - anyOf.push_back(dirname); - } - } - - ignore.push_back("not"); - ignore.push_back(anyOf); - - opts.emplace("expression", ignore); - } - - cmd.push_back(opts); - watchmanRequest(cmd); - - mSubscriptions.emplace(id, watcher); - mRequestSignal.notify(); -} - -// This function is called by Backend::unwatch which takes a lock on mMutex -void WatchmanBackend::unsubscribe(WatcherRef watcher) { - std::string id = getId(watcher); - auto erased = mSubscriptions.erase(id); - - if (erased) { - BSER::Array cmd; - cmd.push_back("unsubscribe"); - cmd.push_back(normalizePath(watcher->mDir)); - cmd.push_back(id); - - watchmanRequest(cmd); - } -} diff --git a/node_modules/@parcel/watcher/src/watchman/WatchmanBackend.hh b/node_modules/@parcel/watcher/src/watchman/WatchmanBackend.hh deleted file mode 100644 index 699cded..0000000 --- a/node_modules/@parcel/watcher/src/watchman/WatchmanBackend.hh +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef WATCHMAN_H -#define WATCHMAN_H - -#include "../Backend.hh" -#include "./BSER.hh" -#include "../Signal.hh" -#include "./IPC.hh" - -class WatchmanBackend : public Backend { -public: - static bool checkAvailable(); - void start() override; - WatchmanBackend() : mStopped(false) {}; - ~WatchmanBackend(); - void writeSnapshot(WatcherRef watcher, std::string *snapshotPath) override; - void getEventsSince(WatcherRef watcher, std::string *snapshotPath) override; - void subscribe(WatcherRef watcher) override; - void unsubscribe(WatcherRef watcher) override; -private: - std::unique_ptr mIPC; - Signal mRequestSignal; - Signal mResponseSignal; - BSER::Object mResponse; - std::string mError; - std::unordered_map mSubscriptions; - bool mStopped; - Signal mEndedSignal; - - std::string clock(WatcherRef watcher); - void watchmanWatch(std::string dir); - BSER::Object watchmanRequest(BSER cmd); - void handleSubscription(BSER::Object obj); -}; - -#endif diff --git a/node_modules/@parcel/watcher/src/windows/WindowsBackend.cc b/node_modules/@parcel/watcher/src/windows/WindowsBackend.cc deleted file mode 100644 index eabce1e..0000000 --- a/node_modules/@parcel/watcher/src/windows/WindowsBackend.cc +++ /dev/null @@ -1,282 +0,0 @@ -#include -#include -#include "../DirTree.hh" -#include "../shared/BruteForceBackend.hh" -#include "./WindowsBackend.hh" -#include "./win_utils.hh" - -#define DEFAULT_BUF_SIZE 1024 * 1024 -#define NETWORK_BUF_SIZE 64 * 1024 -#define CONVERT_TIME(ft) ULARGE_INTEGER{ft.dwLowDateTime, ft.dwHighDateTime}.QuadPart - -void BruteForceBackend::readTree(WatcherRef watcher, std::shared_ptr tree) { - std::stack directories; - - directories.push(watcher->mDir); - - while (!directories.empty()) { - HANDLE hFind = INVALID_HANDLE_VALUE; - - std::string path = directories.top(); - std::string spec = path + "\\*"; - directories.pop(); - - WIN32_FIND_DATA ffd; - hFind = FindFirstFile(spec.c_str(), &ffd); - - if (hFind == INVALID_HANDLE_VALUE) { - if (path == watcher->mDir) { - FindClose(hFind); - throw WatcherError("Error opening directory", watcher); - } - - tree->remove(path); - continue; - } - - do { - if (strcmp(ffd.cFileName, ".") != 0 && strcmp(ffd.cFileName, "..") != 0) { - std::string fullPath = path + "\\" + ffd.cFileName; - if (watcher->isIgnored(fullPath)) { - continue; - } - - tree->add(fullPath, CONVERT_TIME(ffd.ftLastWriteTime), ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); - if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - directories.push(fullPath); - } - } - } while (FindNextFile(hFind, &ffd) != 0); - - FindClose(hFind); - } -} - -void WindowsBackend::start() { - mRunning = true; - notifyStarted(); - - while (mRunning) { - SleepEx(INFINITE, true); - } -} - -WindowsBackend::~WindowsBackend() { - // Mark as stopped, and queue a noop function in the thread to break the loop - mRunning = false; - QueueUserAPC([](__in ULONG_PTR) {}, mThread.native_handle(), (ULONG_PTR)this); -} - -class Subscription: public WatcherState { -public: - Subscription(WindowsBackend *backend, WatcherRef watcher, std::shared_ptr tree) { - mRunning = true; - mBackend = backend; - mWatcher = watcher; - mTree = tree; - ZeroMemory(&mOverlapped, sizeof(OVERLAPPED)); - mOverlapped.hEvent = this; - mReadBuffer.resize(DEFAULT_BUF_SIZE); - mWriteBuffer.resize(DEFAULT_BUF_SIZE); - - mDirectoryHandle = CreateFileW( - utf8ToUtf16(watcher->mDir).data(), - FILE_LIST_DIRECTORY, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, - NULL - ); - - if (mDirectoryHandle == INVALID_HANDLE_VALUE) { - throw WatcherError("Invalid handle", mWatcher); - } - - // Ensure that the path is a directory - BY_HANDLE_FILE_INFORMATION info; - bool success = GetFileInformationByHandle( - mDirectoryHandle, - &info - ); - - if (!success) { - throw WatcherError("Could not get file information", mWatcher); - } - - if (!(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - throw WatcherError("Not a directory", mWatcher); - } - } - - virtual ~Subscription() { - stop(); - } - - void run() { - try { - poll(); - } catch (WatcherError &err) { - mBackend->handleWatcherError(err); - } - } - - void stop() { - if (mRunning) { - mRunning = false; - CancelIo(mDirectoryHandle); - CloseHandle(mDirectoryHandle); - } - } - - void poll() { - if (!mRunning) { - return; - } - - // Asynchronously wait for changes. - int success = ReadDirectoryChangesW( - mDirectoryHandle, - mWriteBuffer.data(), - static_cast(mWriteBuffer.size()), - TRUE, // recursive - FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES - | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, - NULL, - &mOverlapped, - [](DWORD errorCode, DWORD numBytes, LPOVERLAPPED overlapped) { - auto subscription = reinterpret_cast(overlapped->hEvent); - try { - subscription->processEvents(errorCode); - } catch (WatcherError &err) { - subscription->mBackend->handleWatcherError(err); - } - } - ); - - if (!success) { - throw WatcherError("Failed to read changes", mWatcher); - } - } - - void processEvents(DWORD errorCode) { - if (!mRunning) { - return; - } - - switch (errorCode) { - case ERROR_OPERATION_ABORTED: - return; - case ERROR_INVALID_PARAMETER: - // resize buffers to network size (64kb), and try again - mReadBuffer.resize(NETWORK_BUF_SIZE); - mWriteBuffer.resize(NETWORK_BUF_SIZE); - poll(); - return; - case ERROR_NOTIFY_ENUM_DIR: - throw WatcherError("Buffer overflow. Some events may have been lost.", mWatcher); - case ERROR_ACCESS_DENIED: { - // This can happen if the watched directory is deleted. Check if that is the case, - // and if so emit a delete event. Otherwise, fall through to default error case. - DWORD attrs = GetFileAttributesW(utf8ToUtf16(mWatcher->mDir).data()); - bool isDir = attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY); - if (!isDir) { - mWatcher->mEvents.remove(mWatcher->mDir); - mTree->remove(mWatcher->mDir); - mWatcher->notify(); - stop(); - return; - } - } - default: - if (errorCode != ERROR_SUCCESS) { - throw WatcherError("Unknown error", mWatcher); - } - } - - // Swap read and write buffers, and poll again - std::swap(mWriteBuffer, mReadBuffer); - poll(); - - // Read change events - BYTE *base = mReadBuffer.data(); - while (true) { - PFILE_NOTIFY_INFORMATION info = (PFILE_NOTIFY_INFORMATION)base; - processEvent(info); - - if (info->NextEntryOffset == 0) { - break; - } - - base += info->NextEntryOffset; - } - - mWatcher->notify(); - } - - void processEvent(PFILE_NOTIFY_INFORMATION info) { - std::string path = mWatcher->mDir + "\\" + utf16ToUtf8(info->FileName, info->FileNameLength / sizeof(WCHAR)); - if (mWatcher->isIgnored(path)) { - return; - } - - switch (info->Action) { - case FILE_ACTION_ADDED: - case FILE_ACTION_RENAMED_NEW_NAME: { - WIN32_FILE_ATTRIBUTE_DATA data; - if (GetFileAttributesExW(utf8ToUtf16(path).data(), GetFileExInfoStandard, &data)) { - mWatcher->mEvents.create(path); - mTree->add(path, CONVERT_TIME(data.ftLastWriteTime), data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); - } - break; - } - case FILE_ACTION_MODIFIED: { - WIN32_FILE_ATTRIBUTE_DATA data; - if (GetFileAttributesExW(utf8ToUtf16(path).data(), GetFileExInfoStandard, &data)) { - mTree->update(path, CONVERT_TIME(data.ftLastWriteTime)); - if (!(data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - mWatcher->mEvents.update(path); - } - } - break; - } - case FILE_ACTION_REMOVED: - case FILE_ACTION_RENAMED_OLD_NAME: - mWatcher->mEvents.remove(path); - mTree->remove(path); - break; - } - } - -private: - WindowsBackend *mBackend; - std::shared_ptr mWatcher; - std::shared_ptr mTree; - bool mRunning; - HANDLE mDirectoryHandle; - std::vector mReadBuffer; - std::vector mWriteBuffer; - OVERLAPPED mOverlapped; -}; - -// This function is called by Backend::watch which takes a lock on mMutex -void WindowsBackend::subscribe(WatcherRef watcher) { - // Create a subscription for this watcher - auto sub = std::make_shared(this, watcher, getTree(watcher, false)); - watcher->state = sub; - - // Queue polling for this subscription in the correct thread. - bool success = QueueUserAPC([](__in ULONG_PTR ptr) { - Subscription *sub = (Subscription *)ptr; - sub->run(); - }, mThread.native_handle(), (ULONG_PTR)sub.get()); - - if (!success) { - throw std::runtime_error("Unable to queue APC"); - } -} - -// This function is called by Backend::unwatch which takes a lock on mMutex -void WindowsBackend::unsubscribe(WatcherRef watcher) { - watcher->state = nullptr; -} diff --git a/node_modules/@parcel/watcher/src/windows/WindowsBackend.hh b/node_modules/@parcel/watcher/src/windows/WindowsBackend.hh deleted file mode 100644 index d679782..0000000 --- a/node_modules/@parcel/watcher/src/windows/WindowsBackend.hh +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef WINDOWS_H -#define WINDOWS_H - -#include -#include -#include "../shared/BruteForceBackend.hh" - -class WindowsBackend : public BruteForceBackend { -public: - void start() override; - ~WindowsBackend(); - void subscribe(WatcherRef watcher) override; - void unsubscribe(WatcherRef watcher) override; -private: - bool mRunning; -}; - -#endif diff --git a/node_modules/@parcel/watcher/src/windows/win_utils.cc b/node_modules/@parcel/watcher/src/windows/win_utils.cc deleted file mode 100644 index 62a1e59..0000000 --- a/node_modules/@parcel/watcher/src/windows/win_utils.cc +++ /dev/null @@ -1,44 +0,0 @@ -#include "./win_utils.hh" - -std::wstring utf8ToUtf16(std::string input) { - unsigned int len = MultiByteToWideChar(CP_UTF8, 0, input.c_str(), -1, NULL, 0); - WCHAR *output = new WCHAR[len]; - MultiByteToWideChar(CP_UTF8, 0, input.c_str(), -1, output, len); - std::wstring res(output); - delete[] output; - return res; -} - -std::string utf16ToUtf8(const WCHAR *input, DWORD length) { - unsigned int len = WideCharToMultiByte(CP_UTF8, 0, input, length, NULL, 0, NULL, NULL); - char *output = new char[len + 1]; - WideCharToMultiByte(CP_UTF8, 0, input, length, output, len, NULL, NULL); - output[len] = '\0'; - std::string res(output); - delete[] output; - return res; -} - -std::string normalizePath(std::string path) { - // Prevent truncation to MAX_PATH characters by adding the \\?\ prefix - std::wstring p = utf8ToUtf16("\\\\?\\" + path); - - // Get the required length for the output - DWORD len = GetLongPathNameW(p.data(), NULL, 0); - if (!len) { - return path; - } - - // Allocate output array and get long path - WCHAR *output = new WCHAR[len]; - len = GetLongPathNameW(p.data(), output, len); - if (!len) { - delete[] output; - return path; - } - - // Convert back to utf8 - std::string res = utf16ToUtf8(output + 4, len - 4); - delete[] output; - return res; -} diff --git a/node_modules/@parcel/watcher/src/windows/win_utils.hh b/node_modules/@parcel/watcher/src/windows/win_utils.hh deleted file mode 100644 index 9178d1b..0000000 --- a/node_modules/@parcel/watcher/src/windows/win_utils.hh +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef WIN_UTILS_H -#define WIN_UTILS_H - -#include -#include - -std::wstring utf8ToUtf16(std::string input); -std::string utf16ToUtf8(const WCHAR *input, DWORD length); -std::string normalizePath(std::string path); - -#endif diff --git a/node_modules/@parcel/watcher/wrapper.js b/node_modules/@parcel/watcher/wrapper.js deleted file mode 100644 index 3b47518..0000000 --- a/node_modules/@parcel/watcher/wrapper.js +++ /dev/null @@ -1,74 +0,0 @@ -const path = require('path'); -const picomatch = require('picomatch'); -const isGlob = require('is-glob'); - -function normalizeOptions(dir, opts = {}) { - const { ignore, ...rest } = opts; - - if (Array.isArray(ignore)) { - opts = { ...rest }; - - for (const value of ignore) { - if (isGlob(value)) { - if (!opts.ignoreGlobs) { - opts.ignoreGlobs = []; - } - - const regex = picomatch.makeRe(value, { - // We set `dot: true` to workaround an issue with the - // regular expression on Linux where the resulting - // negative lookahead `(?!(\\/|^)` was never matching - // in some cases. See also https://bit.ly/3UZlQDm - dot: true, - windows: process.platform === 'win32', - }); - opts.ignoreGlobs.push(regex.source); - } else { - if (!opts.ignorePaths) { - opts.ignorePaths = []; - } - - opts.ignorePaths.push(path.resolve(dir, value)); - } - } - } - - return opts; -} - -exports.createWrapper = (binding) => { - return { - writeSnapshot(dir, snapshot, opts) { - return binding.writeSnapshot( - path.resolve(dir), - path.resolve(snapshot), - normalizeOptions(dir, opts), - ); - }, - getEventsSince(dir, snapshot, opts) { - return binding.getEventsSince( - path.resolve(dir), - path.resolve(snapshot), - normalizeOptions(dir, opts), - ); - }, - async subscribe(dir, fn, opts) { - dir = path.resolve(dir); - opts = normalizeOptions(dir, opts); - await binding.subscribe(dir, fn, opts); - - return { - unsubscribe() { - return binding.unsubscribe(dir, fn, opts); - }, - }; - }, - unsubscribe(dir, fn, opts) { - return binding.unsubscribe( - path.resolve(dir), - fn, - normalizeOptions(dir, opts), - ); - } - }; -}; diff --git a/node_modules/accepts/HISTORY.md b/node_modules/accepts/HISTORY.md deleted file mode 100644 index cb5990c..0000000 --- a/node_modules/accepts/HISTORY.md +++ /dev/null @@ -1,243 +0,0 @@ -1.3.8 / 2022-02-02 -================== - - * deps: mime-types@~2.1.34 - - deps: mime-db@~1.51.0 - * deps: negotiator@0.6.3 - -1.3.7 / 2019-04-29 -================== - - * deps: negotiator@0.6.2 - - Fix sorting charset, encoding, and language with extra parameters - -1.3.6 / 2019-04-28 -================== - - * deps: mime-types@~2.1.24 - - deps: mime-db@~1.40.0 - -1.3.5 / 2018-02-28 -================== - - * deps: mime-types@~2.1.18 - - deps: mime-db@~1.33.0 - -1.3.4 / 2017-08-22 -================== - - * deps: mime-types@~2.1.16 - - deps: mime-db@~1.29.0 - -1.3.3 / 2016-05-02 -================== - - * deps: mime-types@~2.1.11 - - deps: mime-db@~1.23.0 - * deps: negotiator@0.6.1 - - perf: improve `Accept` parsing speed - - perf: improve `Accept-Charset` parsing speed - - perf: improve `Accept-Encoding` parsing speed - - perf: improve `Accept-Language` parsing speed - -1.3.2 / 2016-03-08 -================== - - * deps: mime-types@~2.1.10 - - Fix extension of `application/dash+xml` - - Update primary extension for `audio/mp4` - - deps: mime-db@~1.22.0 - -1.3.1 / 2016-01-19 -================== - - * deps: mime-types@~2.1.9 - - deps: mime-db@~1.21.0 - -1.3.0 / 2015-09-29 -================== - - * deps: mime-types@~2.1.7 - - deps: mime-db@~1.19.0 - * deps: negotiator@0.6.0 - - Fix including type extensions in parameters in `Accept` parsing - - Fix parsing `Accept` parameters with quoted equals - - Fix parsing `Accept` parameters with quoted semicolons - - Lazy-load modules from main entry point - - perf: delay type concatenation until needed - - perf: enable strict mode - - perf: hoist regular expressions - - perf: remove closures getting spec properties - - perf: remove a closure from media type parsing - - perf: remove property delete from media type parsing - -1.2.13 / 2015-09-06 -=================== - - * deps: mime-types@~2.1.6 - - deps: mime-db@~1.18.0 - -1.2.12 / 2015-07-30 -=================== - - * deps: mime-types@~2.1.4 - - deps: mime-db@~1.16.0 - -1.2.11 / 2015-07-16 -=================== - - * deps: mime-types@~2.1.3 - - deps: mime-db@~1.15.0 - -1.2.10 / 2015-07-01 -=================== - - * deps: mime-types@~2.1.2 - - deps: mime-db@~1.14.0 - -1.2.9 / 2015-06-08 -================== - - * deps: mime-types@~2.1.1 - - perf: fix deopt during mapping - -1.2.8 / 2015-06-07 -================== - - * deps: mime-types@~2.1.0 - - deps: mime-db@~1.13.0 - * perf: avoid argument reassignment & argument slice - * perf: avoid negotiator recursive construction - * perf: enable strict mode - * perf: remove unnecessary bitwise operator - -1.2.7 / 2015-05-10 -================== - - * deps: negotiator@0.5.3 - - Fix media type parameter matching to be case-insensitive - -1.2.6 / 2015-05-07 -================== - - * deps: mime-types@~2.0.11 - - deps: mime-db@~1.9.1 - * deps: negotiator@0.5.2 - - Fix comparing media types with quoted values - - Fix splitting media types with quoted commas - -1.2.5 / 2015-03-13 -================== - - * deps: mime-types@~2.0.10 - - deps: mime-db@~1.8.0 - -1.2.4 / 2015-02-14 -================== - - * Support Node.js 0.6 - * deps: mime-types@~2.0.9 - - deps: mime-db@~1.7.0 - * deps: negotiator@0.5.1 - - Fix preference sorting to be stable for long acceptable lists - -1.2.3 / 2015-01-31 -================== - - * deps: mime-types@~2.0.8 - - deps: mime-db@~1.6.0 - -1.2.2 / 2014-12-30 -================== - - * deps: mime-types@~2.0.7 - - deps: mime-db@~1.5.0 - -1.2.1 / 2014-12-30 -================== - - * deps: mime-types@~2.0.5 - - deps: mime-db@~1.3.1 - -1.2.0 / 2014-12-19 -================== - - * deps: negotiator@0.5.0 - - Fix list return order when large accepted list - - Fix missing identity encoding when q=0 exists - - Remove dynamic building of Negotiator class - -1.1.4 / 2014-12-10 -================== - - * deps: mime-types@~2.0.4 - - deps: mime-db@~1.3.0 - -1.1.3 / 2014-11-09 -================== - - * deps: mime-types@~2.0.3 - - deps: mime-db@~1.2.0 - -1.1.2 / 2014-10-14 -================== - - * deps: negotiator@0.4.9 - - Fix error when media type has invalid parameter - -1.1.1 / 2014-09-28 -================== - - * deps: mime-types@~2.0.2 - - deps: mime-db@~1.1.0 - * deps: negotiator@0.4.8 - - Fix all negotiations to be case-insensitive - - Stable sort preferences of same quality according to client order - -1.1.0 / 2014-09-02 -================== - - * update `mime-types` - -1.0.7 / 2014-07-04 -================== - - * Fix wrong type returned from `type` when match after unknown extension - -1.0.6 / 2014-06-24 -================== - - * deps: negotiator@0.4.7 - -1.0.5 / 2014-06-20 -================== - - * fix crash when unknown extension given - -1.0.4 / 2014-06-19 -================== - - * use `mime-types` - -1.0.3 / 2014-06-11 -================== - - * deps: negotiator@0.4.6 - - Order by specificity when quality is the same - -1.0.2 / 2014-05-29 -================== - - * Fix interpretation when header not in request - * deps: pin negotiator@0.4.5 - -1.0.1 / 2014-01-18 -================== - - * Identity encoding isn't always acceptable - * deps: negotiator@~0.4.0 - -1.0.0 / 2013-12-27 -================== - - * Genesis diff --git a/node_modules/accepts/LICENSE b/node_modules/accepts/LICENSE deleted file mode 100644 index 0616607..0000000 --- a/node_modules/accepts/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -(The MIT License) - -Copyright (c) 2014 Jonathan Ong -Copyright (c) 2015 Douglas Christopher Wilson - -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. diff --git a/node_modules/accepts/README.md b/node_modules/accepts/README.md deleted file mode 100644 index 82680c5..0000000 --- a/node_modules/accepts/README.md +++ /dev/null @@ -1,140 +0,0 @@ -# accepts - -[![NPM Version][npm-version-image]][npm-url] -[![NPM Downloads][npm-downloads-image]][npm-url] -[![Node.js Version][node-version-image]][node-version-url] -[![Build Status][github-actions-ci-image]][github-actions-ci-url] -[![Test Coverage][coveralls-image]][coveralls-url] - -Higher level content negotiation based on [negotiator](https://www.npmjs.com/package/negotiator). -Extracted from [koa](https://www.npmjs.com/package/koa) for general use. - -In addition to negotiator, it allows: - -- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])` - as well as `('text/html', 'application/json')`. -- Allows type shorthands such as `json`. -- Returns `false` when no types match -- Treats non-existent headers as `*` - -## Installation - -This is a [Node.js](https://nodejs.org/en/) module available through the -[npm registry](https://www.npmjs.com/). Installation is done using the -[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): - -```sh -$ npm install accepts -``` - -## API - -```js -var accepts = require('accepts') -``` - -### accepts(req) - -Create a new `Accepts` object for the given `req`. - -#### .charset(charsets) - -Return the first accepted charset. If nothing in `charsets` is accepted, -then `false` is returned. - -#### .charsets() - -Return the charsets that the request accepts, in the order of the client's -preference (most preferred first). - -#### .encoding(encodings) - -Return the first accepted encoding. If nothing in `encodings` is accepted, -then `false` is returned. - -#### .encodings() - -Return the encodings that the request accepts, in the order of the client's -preference (most preferred first). - -#### .language(languages) - -Return the first accepted language. If nothing in `languages` is accepted, -then `false` is returned. - -#### .languages() - -Return the languages that the request accepts, in the order of the client's -preference (most preferred first). - -#### .type(types) - -Return the first accepted type (and it is returned as the same text as what -appears in the `types` array). If nothing in `types` is accepted, then `false` -is returned. - -The `types` array can contain full MIME types or file extensions. Any value -that is not a full MIME types is passed to `require('mime-types').lookup`. - -#### .types() - -Return the types that the request accepts, in the order of the client's -preference (most preferred first). - -## Examples - -### Simple type negotiation - -This simple example shows how to use `accepts` to return a different typed -respond body based on what the client wants to accept. The server lists it's -preferences in order and will get back the best match between the client and -server. - -```js -var accepts = require('accepts') -var http = require('http') - -function app (req, res) { - var accept = accepts(req) - - // the order of this list is significant; should be server preferred order - switch (accept.type(['json', 'html'])) { - case 'json': - res.setHeader('Content-Type', 'application/json') - res.write('{"hello":"world!"}') - break - case 'html': - res.setHeader('Content-Type', 'text/html') - res.write('hello, world!') - break - default: - // the fallback is text/plain, so no need to specify it above - res.setHeader('Content-Type', 'text/plain') - res.write('hello, world!') - break - } - - res.end() -} - -http.createServer(app).listen(3000) -``` - -You can test this out with the cURL program: -```sh -curl -I -H'Accept: text/html' http://localhost:3000/ -``` - -## License - -[MIT](LICENSE) - -[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/accepts/master -[coveralls-url]: https://coveralls.io/r/jshttp/accepts?branch=master -[github-actions-ci-image]: https://badgen.net/github/checks/jshttp/accepts/master?label=ci -[github-actions-ci-url]: https://github.com/jshttp/accepts/actions/workflows/ci.yml -[node-version-image]: https://badgen.net/npm/node/accepts -[node-version-url]: https://nodejs.org/en/download -[npm-downloads-image]: https://badgen.net/npm/dm/accepts -[npm-url]: https://npmjs.org/package/accepts -[npm-version-image]: https://badgen.net/npm/v/accepts diff --git a/node_modules/accepts/index.js b/node_modules/accepts/index.js deleted file mode 100644 index e9b2f63..0000000 --- a/node_modules/accepts/index.js +++ /dev/null @@ -1,238 +0,0 @@ -/*! - * accepts - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2015 Douglas Christopher Wilson - * MIT Licensed - */ - -'use strict' - -/** - * Module dependencies. - * @private - */ - -var Negotiator = require('negotiator') -var mime = require('mime-types') - -/** - * Module exports. - * @public - */ - -module.exports = Accepts - -/** - * Create a new Accepts object for the given req. - * - * @param {object} req - * @public - */ - -function Accepts (req) { - if (!(this instanceof Accepts)) { - return new Accepts(req) - } - - this.headers = req.headers - this.negotiator = new Negotiator(req) -} - -/** - * Check if the given `type(s)` is acceptable, returning - * the best match when true, otherwise `undefined`, in which - * case you should respond with 406 "Not Acceptable". - * - * The `type` value may be a single mime type string - * such as "application/json", the extension name - * such as "json" or an array `["json", "html", "text/plain"]`. When a list - * or array is given the _best_ match, if any is returned. - * - * Examples: - * - * // Accept: text/html - * this.types('html'); - * // => "html" - * - * // Accept: text/*, application/json - * this.types('html'); - * // => "html" - * this.types('text/html'); - * // => "text/html" - * this.types('json', 'text'); - * // => "json" - * this.types('application/json'); - * // => "application/json" - * - * // Accept: text/*, application/json - * this.types('image/png'); - * this.types('png'); - * // => undefined - * - * // Accept: text/*;q=.5, application/json - * this.types(['html', 'json']); - * this.types('html', 'json'); - * // => "json" - * - * @param {String|Array} types... - * @return {String|Array|Boolean} - * @public - */ - -Accepts.prototype.type = -Accepts.prototype.types = function (types_) { - var types = types_ - - // support flattened arguments - if (types && !Array.isArray(types)) { - types = new Array(arguments.length) - for (var i = 0; i < types.length; i++) { - types[i] = arguments[i] - } - } - - // no types, return all requested types - if (!types || types.length === 0) { - return this.negotiator.mediaTypes() - } - - // no accept header, return first given type - if (!this.headers.accept) { - return types[0] - } - - var mimes = types.map(extToMime) - var accepts = this.negotiator.mediaTypes(mimes.filter(validMime)) - var first = accepts[0] - - return first - ? types[mimes.indexOf(first)] - : false -} - -/** - * Return accepted encodings or best fit based on `encodings`. - * - * Given `Accept-Encoding: gzip, deflate` - * an array sorted by quality is returned: - * - * ['gzip', 'deflate'] - * - * @param {String|Array} encodings... - * @return {String|Array} - * @public - */ - -Accepts.prototype.encoding = -Accepts.prototype.encodings = function (encodings_) { - var encodings = encodings_ - - // support flattened arguments - if (encodings && !Array.isArray(encodings)) { - encodings = new Array(arguments.length) - for (var i = 0; i < encodings.length; i++) { - encodings[i] = arguments[i] - } - } - - // no encodings, return all requested encodings - if (!encodings || encodings.length === 0) { - return this.negotiator.encodings() - } - - return this.negotiator.encodings(encodings)[0] || false -} - -/** - * Return accepted charsets or best fit based on `charsets`. - * - * Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5` - * an array sorted by quality is returned: - * - * ['utf-8', 'utf-7', 'iso-8859-1'] - * - * @param {String|Array} charsets... - * @return {String|Array} - * @public - */ - -Accepts.prototype.charset = -Accepts.prototype.charsets = function (charsets_) { - var charsets = charsets_ - - // support flattened arguments - if (charsets && !Array.isArray(charsets)) { - charsets = new Array(arguments.length) - for (var i = 0; i < charsets.length; i++) { - charsets[i] = arguments[i] - } - } - - // no charsets, return all requested charsets - if (!charsets || charsets.length === 0) { - return this.negotiator.charsets() - } - - return this.negotiator.charsets(charsets)[0] || false -} - -/** - * Return accepted languages or best fit based on `langs`. - * - * Given `Accept-Language: en;q=0.8, es, pt` - * an array sorted by quality is returned: - * - * ['es', 'pt', 'en'] - * - * @param {String|Array} langs... - * @return {Array|String} - * @public - */ - -Accepts.prototype.lang = -Accepts.prototype.langs = -Accepts.prototype.language = -Accepts.prototype.languages = function (languages_) { - var languages = languages_ - - // support flattened arguments - if (languages && !Array.isArray(languages)) { - languages = new Array(arguments.length) - for (var i = 0; i < languages.length; i++) { - languages[i] = arguments[i] - } - } - - // no languages, return all requested languages - if (!languages || languages.length === 0) { - return this.negotiator.languages() - } - - return this.negotiator.languages(languages)[0] || false -} - -/** - * Convert extnames to mime. - * - * @param {String} type - * @return {String} - * @private - */ - -function extToMime (type) { - return type.indexOf('/') === -1 - ? mime.lookup(type) - : type -} - -/** - * Check if mime is valid. - * - * @param {String} type - * @return {String} - * @private - */ - -function validMime (type) { - return typeof type === 'string' -} diff --git a/node_modules/accepts/package.json b/node_modules/accepts/package.json deleted file mode 100644 index 0f2d15d..0000000 --- a/node_modules/accepts/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "accepts", - "description": "Higher-level content negotiation", - "version": "1.3.8", - "contributors": [ - "Douglas Christopher Wilson ", - "Jonathan Ong (http://jongleberry.com)" - ], - "license": "MIT", - "repository": "jshttp/accepts", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "devDependencies": { - "deep-equal": "1.0.1", - "eslint": "7.32.0", - "eslint-config-standard": "14.1.1", - "eslint-plugin-import": "2.25.4", - "eslint-plugin-markdown": "2.2.1", - "eslint-plugin-node": "11.1.0", - "eslint-plugin-promise": "4.3.1", - "eslint-plugin-standard": "4.1.0", - "mocha": "9.2.0", - "nyc": "15.1.0" - }, - "files": [ - "LICENSE", - "HISTORY.md", - "index.js" - ], - "engines": { - "node": ">= 0.6" - }, - "scripts": { - "lint": "eslint .", - "test": "mocha --reporter spec --check-leaks --bail test/", - "test-ci": "nyc --reporter=lcov --reporter=text npm test", - "test-cov": "nyc --reporter=html --reporter=text npm test" - }, - "keywords": [ - "content", - "negotiation", - "accept", - "accepts" - ] -} diff --git a/node_modules/array-flatten/LICENSE b/node_modules/array-flatten/LICENSE deleted file mode 100644 index 983fbe8..0000000 --- a/node_modules/array-flatten/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com) - -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. diff --git a/node_modules/array-flatten/README.md b/node_modules/array-flatten/README.md deleted file mode 100644 index 91fa5b6..0000000 --- a/node_modules/array-flatten/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Array Flatten - -[![NPM version][npm-image]][npm-url] -[![NPM downloads][downloads-image]][downloads-url] -[![Build status][travis-image]][travis-url] -[![Test coverage][coveralls-image]][coveralls-url] - -> Flatten an array of nested arrays into a single flat array. Accepts an optional depth. - -## Installation - -``` -npm install array-flatten --save -``` - -## Usage - -```javascript -var flatten = require('array-flatten') - -flatten([1, [2, [3, [4, [5], 6], 7], 8], 9]) -//=> [1, 2, 3, 4, 5, 6, 7, 8, 9] - -flatten([1, [2, [3, [4, [5], 6], 7], 8], 9], 2) -//=> [1, 2, 3, [4, [5], 6], 7, 8, 9] - -(function () { - flatten(arguments) //=> [1, 2, 3] -})(1, [2, 3]) -``` - -## License - -MIT - -[npm-image]: https://img.shields.io/npm/v/array-flatten.svg?style=flat -[npm-url]: https://npmjs.org/package/array-flatten -[downloads-image]: https://img.shields.io/npm/dm/array-flatten.svg?style=flat -[downloads-url]: https://npmjs.org/package/array-flatten -[travis-image]: https://img.shields.io/travis/blakeembrey/array-flatten.svg?style=flat -[travis-url]: https://travis-ci.org/blakeembrey/array-flatten -[coveralls-image]: https://img.shields.io/coveralls/blakeembrey/array-flatten.svg?style=flat -[coveralls-url]: https://coveralls.io/r/blakeembrey/array-flatten?branch=master diff --git a/node_modules/array-flatten/array-flatten.js b/node_modules/array-flatten/array-flatten.js deleted file mode 100644 index 089117b..0000000 --- a/node_modules/array-flatten/array-flatten.js +++ /dev/null @@ -1,64 +0,0 @@ -'use strict' - -/** - * Expose `arrayFlatten`. - */ -module.exports = arrayFlatten - -/** - * Recursive flatten function with depth. - * - * @param {Array} array - * @param {Array} result - * @param {Number} depth - * @return {Array} - */ -function flattenWithDepth (array, result, depth) { - for (var i = 0; i < array.length; i++) { - var value = array[i] - - if (depth > 0 && Array.isArray(value)) { - flattenWithDepth(value, result, depth - 1) - } else { - result.push(value) - } - } - - return result -} - -/** - * Recursive flatten function. Omitting depth is slightly faster. - * - * @param {Array} array - * @param {Array} result - * @return {Array} - */ -function flattenForever (array, result) { - for (var i = 0; i < array.length; i++) { - var value = array[i] - - if (Array.isArray(value)) { - flattenForever(value, result) - } else { - result.push(value) - } - } - - return result -} - -/** - * Flatten an array, with the ability to define a depth. - * - * @param {Array} array - * @param {Number} depth - * @return {Array} - */ -function arrayFlatten (array, depth) { - if (depth == null) { - return flattenForever(array, []) - } - - return flattenWithDepth(array, [], depth) -} diff --git a/node_modules/array-flatten/package.json b/node_modules/array-flatten/package.json deleted file mode 100644 index 1a24e2a..0000000 --- a/node_modules/array-flatten/package.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "array-flatten", - "version": "1.1.1", - "description": "Flatten an array of nested arrays into a single flat array", - "main": "array-flatten.js", - "files": [ - "array-flatten.js", - "LICENSE" - ], - "scripts": { - "test": "istanbul cover _mocha -- -R spec" - }, - "repository": { - "type": "git", - "url": "git://github.com/blakeembrey/array-flatten.git" - }, - "keywords": [ - "array", - "flatten", - "arguments", - "depth" - ], - "author": { - "name": "Blake Embrey", - "email": "hello@blakeembrey.com", - "url": "http://blakeembrey.me" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/blakeembrey/array-flatten/issues" - }, - "homepage": "https://github.com/blakeembrey/array-flatten", - "devDependencies": { - "istanbul": "^0.3.13", - "mocha": "^2.2.4", - "pre-commit": "^1.0.7", - "standard": "^3.7.3" - } -} diff --git a/node_modules/body-parser/HISTORY.md b/node_modules/body-parser/HISTORY.md deleted file mode 100644 index e5c4fde..0000000 --- a/node_modules/body-parser/HISTORY.md +++ /dev/null @@ -1,686 +0,0 @@ -1.20.5 / 2026-04-24 -=================== -* refactor(json): simplify strict mode error string construction -* fix: extended urlencoded parsing of arrays with >100 elements (#716) -* deps: qs@~6.15.1 - -1.20.4 / 2025-12-01 -=================== - - * deps: qs@~6.14.0 - * deps: use tilde notation for dependencies - * deps: http-errors@~2.0.1 - * deps: raw-body@~2.5.3 - -1.20.3 / 2024-09-10 -=================== - - * deps: qs@6.13.0 - * add `depth` option to customize the depth level in the parser - * IMPORTANT: The default `depth` level for parsing URL-encoded data is now `32` (previously was `Infinity`) - -1.20.2 / 2023-02-21 -=================== - - * Fix strict json error message on Node.js 19+ - * deps: content-type@~1.0.5 - - perf: skip value escaping when unnecessary - * deps: raw-body@2.5.2 - -1.20.1 / 2022-10-06 -=================== - - * deps: qs@6.11.0 - * perf: remove unnecessary object clone - -1.20.0 / 2022-04-02 -=================== - - * Fix error message for json parse whitespace in `strict` - * Fix internal error when inflated body exceeds limit - * Prevent loss of async hooks context - * Prevent hanging when request already read - * deps: depd@2.0.0 - - Replace internal `eval` usage with `Function` constructor - - Use instance methods on `process` to check for listeners - * deps: http-errors@2.0.0 - - deps: depd@2.0.0 - - deps: statuses@2.0.1 - * deps: on-finished@2.4.1 - * deps: qs@6.10.3 - * deps: raw-body@2.5.1 - - deps: http-errors@2.0.0 - -1.19.2 / 2022-02-15 -=================== - - * deps: bytes@3.1.2 - * deps: qs@6.9.7 - * Fix handling of `__proto__` keys - * deps: raw-body@2.4.3 - - deps: bytes@3.1.2 - -1.19.1 / 2021-12-10 -=================== - - * deps: bytes@3.1.1 - * deps: http-errors@1.8.1 - - deps: inherits@2.0.4 - - deps: toidentifier@1.0.1 - - deps: setprototypeof@1.2.0 - * deps: qs@6.9.6 - * deps: raw-body@2.4.2 - - deps: bytes@3.1.1 - - deps: http-errors@1.8.1 - * deps: safe-buffer@5.2.1 - * deps: type-is@~1.6.18 - -1.19.0 / 2019-04-25 -=================== - - * deps: bytes@3.1.0 - - Add petabyte (`pb`) support - * deps: http-errors@1.7.2 - - Set constructor name when possible - - deps: setprototypeof@1.1.1 - - deps: statuses@'>= 1.5.0 < 2' - * deps: iconv-lite@0.4.24 - - Added encoding MIK - * deps: qs@6.7.0 - - Fix parsing array brackets after index - * deps: raw-body@2.4.0 - - deps: bytes@3.1.0 - - deps: http-errors@1.7.2 - - deps: iconv-lite@0.4.24 - * deps: type-is@~1.6.17 - - deps: mime-types@~2.1.24 - - perf: prevent internal `throw` on invalid type - -1.18.3 / 2018-05-14 -=================== - - * Fix stack trace for strict json parse error - * deps: depd@~1.1.2 - - perf: remove argument reassignment - * deps: http-errors@~1.6.3 - - deps: depd@~1.1.2 - - deps: setprototypeof@1.1.0 - - deps: statuses@'>= 1.3.1 < 2' - * deps: iconv-lite@0.4.23 - - Fix loading encoding with year appended - - Fix deprecation warnings on Node.js 10+ - * deps: qs@6.5.2 - * deps: raw-body@2.3.3 - - deps: http-errors@1.6.3 - - deps: iconv-lite@0.4.23 - * deps: type-is@~1.6.16 - - deps: mime-types@~2.1.18 - -1.18.2 / 2017-09-22 -=================== - - * deps: debug@2.6.9 - * perf: remove argument reassignment - -1.18.1 / 2017-09-12 -=================== - - * deps: content-type@~1.0.4 - - perf: remove argument reassignment - - perf: skip parameter parsing when no parameters - * deps: iconv-lite@0.4.19 - - Fix ISO-8859-1 regression - - Update Windows-1255 - * deps: qs@6.5.1 - - Fix parsing & compacting very deep objects - * deps: raw-body@2.3.2 - - deps: iconv-lite@0.4.19 - -1.18.0 / 2017-09-08 -=================== - - * Fix JSON strict violation error to match native parse error - * Include the `body` property on verify errors - * Include the `type` property on all generated errors - * Use `http-errors` to set status code on errors - * deps: bytes@3.0.0 - * deps: debug@2.6.8 - * deps: depd@~1.1.1 - - Remove unnecessary `Buffer` loading - * deps: http-errors@~1.6.2 - - deps: depd@1.1.1 - * deps: iconv-lite@0.4.18 - - Add support for React Native - - Add a warning if not loaded as utf-8 - - Fix CESU-8 decoding in Node.js 8 - - Improve speed of ISO-8859-1 encoding - * deps: qs@6.5.0 - * deps: raw-body@2.3.1 - - Use `http-errors` for standard emitted errors - - deps: bytes@3.0.0 - - deps: iconv-lite@0.4.18 - - perf: skip buffer decoding on overage chunk - * perf: prevent internal `throw` when missing charset - -1.17.2 / 2017-05-17 -=================== - - * deps: debug@2.6.7 - - Fix `DEBUG_MAX_ARRAY_LENGTH` - - deps: ms@2.0.0 - * deps: type-is@~1.6.15 - - deps: mime-types@~2.1.15 - -1.17.1 / 2017-03-06 -=================== - - * deps: qs@6.4.0 - - Fix regression parsing keys starting with `[` - -1.17.0 / 2017-03-01 -=================== - - * deps: http-errors@~1.6.1 - - Make `message` property enumerable for `HttpError`s - - deps: setprototypeof@1.0.3 - * deps: qs@6.3.1 - - Fix compacting nested arrays - -1.16.1 / 2017-02-10 -=================== - - * deps: debug@2.6.1 - - Fix deprecation messages in WebStorm and other editors - - Undeprecate `DEBUG_FD` set to `1` or `2` - -1.16.0 / 2017-01-17 -=================== - - * deps: debug@2.6.0 - - Allow colors in workers - - Deprecated `DEBUG_FD` environment variable - - Fix error when running under React Native - - Use same color for same namespace - - deps: ms@0.7.2 - * deps: http-errors@~1.5.1 - - deps: inherits@2.0.3 - - deps: setprototypeof@1.0.2 - - deps: statuses@'>= 1.3.1 < 2' - * deps: iconv-lite@0.4.15 - - Added encoding MS-31J - - Added encoding MS-932 - - Added encoding MS-936 - - Added encoding MS-949 - - Added encoding MS-950 - - Fix GBK/GB18030 handling of Euro character - * deps: qs@6.2.1 - - Fix array parsing from skipping empty values - * deps: raw-body@~2.2.0 - - deps: iconv-lite@0.4.15 - * deps: type-is@~1.6.14 - - deps: mime-types@~2.1.13 - -1.15.2 / 2016-06-19 -=================== - - * deps: bytes@2.4.0 - * deps: content-type@~1.0.2 - - perf: enable strict mode - * deps: http-errors@~1.5.0 - - Use `setprototypeof` module to replace `__proto__` setting - - deps: statuses@'>= 1.3.0 < 2' - - perf: enable strict mode - * deps: qs@6.2.0 - * deps: raw-body@~2.1.7 - - deps: bytes@2.4.0 - - perf: remove double-cleanup on happy path - * deps: type-is@~1.6.13 - - deps: mime-types@~2.1.11 - -1.15.1 / 2016-05-05 -=================== - - * deps: bytes@2.3.0 - - Drop partial bytes on all parsed units - - Fix parsing byte string that looks like hex - * deps: raw-body@~2.1.6 - - deps: bytes@2.3.0 - * deps: type-is@~1.6.12 - - deps: mime-types@~2.1.10 - -1.15.0 / 2016-02-10 -=================== - - * deps: http-errors@~1.4.0 - - Add `HttpError` export, for `err instanceof createError.HttpError` - - deps: inherits@2.0.1 - - deps: statuses@'>= 1.2.1 < 2' - * deps: qs@6.1.0 - * deps: type-is@~1.6.11 - - deps: mime-types@~2.1.9 - -1.14.2 / 2015-12-16 -=================== - - * deps: bytes@2.2.0 - * deps: iconv-lite@0.4.13 - * deps: qs@5.2.0 - * deps: raw-body@~2.1.5 - - deps: bytes@2.2.0 - - deps: iconv-lite@0.4.13 - * deps: type-is@~1.6.10 - - deps: mime-types@~2.1.8 - -1.14.1 / 2015-09-27 -=================== - - * Fix issue where invalid charset results in 400 when `verify` used - * deps: iconv-lite@0.4.12 - - Fix CESU-8 decoding in Node.js 4.x - * deps: raw-body@~2.1.4 - - Fix masking critical errors from `iconv-lite` - - deps: iconv-lite@0.4.12 - * deps: type-is@~1.6.9 - - deps: mime-types@~2.1.7 - -1.14.0 / 2015-09-16 -=================== - - * Fix JSON strict parse error to match syntax errors - * Provide static `require` analysis in `urlencoded` parser - * deps: depd@~1.1.0 - - Support web browser loading - * deps: qs@5.1.0 - * deps: raw-body@~2.1.3 - - Fix sync callback when attaching data listener causes sync read - * deps: type-is@~1.6.8 - - Fix type error when given invalid type to match against - - deps: mime-types@~2.1.6 - -1.13.3 / 2015-07-31 -=================== - - * deps: type-is@~1.6.6 - - deps: mime-types@~2.1.4 - -1.13.2 / 2015-07-05 -=================== - - * deps: iconv-lite@0.4.11 - * deps: qs@4.0.0 - - Fix dropping parameters like `hasOwnProperty` - - Fix user-visible incompatibilities from 3.1.0 - - Fix various parsing edge cases - * deps: raw-body@~2.1.2 - - Fix error stack traces to skip `makeError` - - deps: iconv-lite@0.4.11 - * deps: type-is@~1.6.4 - - deps: mime-types@~2.1.2 - - perf: enable strict mode - - perf: remove argument reassignment - -1.13.1 / 2015-06-16 -=================== - - * deps: qs@2.4.2 - - Downgraded from 3.1.0 because of user-visible incompatibilities - -1.13.0 / 2015-06-14 -=================== - - * Add `statusCode` property on `Error`s, in addition to `status` - * Change `type` default to `application/json` for JSON parser - * Change `type` default to `application/x-www-form-urlencoded` for urlencoded parser - * Provide static `require` analysis - * Use the `http-errors` module to generate errors - * deps: bytes@2.1.0 - - Slight optimizations - * deps: iconv-lite@0.4.10 - - The encoding UTF-16 without BOM now defaults to UTF-16LE when detection fails - - Leading BOM is now removed when decoding - * deps: on-finished@~2.3.0 - - Add defined behavior for HTTP `CONNECT` requests - - Add defined behavior for HTTP `Upgrade` requests - - deps: ee-first@1.1.1 - * deps: qs@3.1.0 - - Fix dropping parameters like `hasOwnProperty` - - Fix various parsing edge cases - - Parsed object now has `null` prototype - * deps: raw-body@~2.1.1 - - Use `unpipe` module for unpiping requests - - deps: iconv-lite@0.4.10 - * deps: type-is@~1.6.3 - - deps: mime-types@~2.1.1 - - perf: reduce try block size - - perf: remove bitwise operations - * perf: enable strict mode - * perf: remove argument reassignment - * perf: remove delete call - -1.12.4 / 2015-05-10 -=================== - - * deps: debug@~2.2.0 - * deps: qs@2.4.2 - - Fix allowing parameters like `constructor` - * deps: on-finished@~2.2.1 - * deps: raw-body@~2.0.1 - - Fix a false-positive when unpiping in Node.js 0.8 - - deps: bytes@2.0.1 - * deps: type-is@~1.6.2 - - deps: mime-types@~2.0.11 - -1.12.3 / 2015-04-15 -=================== - - * Slight efficiency improvement when not debugging - * deps: depd@~1.0.1 - * deps: iconv-lite@0.4.8 - - Add encoding alias UNICODE-1-1-UTF-7 - * deps: raw-body@1.3.4 - - Fix hanging callback if request aborts during read - - deps: iconv-lite@0.4.8 - -1.12.2 / 2015-03-16 -=================== - - * deps: qs@2.4.1 - - Fix error when parameter `hasOwnProperty` is present - -1.12.1 / 2015-03-15 -=================== - - * deps: debug@~2.1.3 - - Fix high intensity foreground color for bold - - deps: ms@0.7.0 - * deps: type-is@~1.6.1 - - deps: mime-types@~2.0.10 - -1.12.0 / 2015-02-13 -=================== - - * add `debug` messages - * accept a function for the `type` option - * use `content-type` to parse `Content-Type` headers - * deps: iconv-lite@0.4.7 - - Gracefully support enumerables on `Object.prototype` - * deps: raw-body@1.3.3 - - deps: iconv-lite@0.4.7 - * deps: type-is@~1.6.0 - - fix argument reassignment - - fix false-positives in `hasBody` `Transfer-Encoding` check - - support wildcard for both type and subtype (`*/*`) - - deps: mime-types@~2.0.9 - -1.11.0 / 2015-01-30 -=================== - - * make internal `extended: true` depth limit infinity - * deps: type-is@~1.5.6 - - deps: mime-types@~2.0.8 - -1.10.2 / 2015-01-20 -=================== - - * deps: iconv-lite@0.4.6 - - Fix rare aliases of single-byte encodings - * deps: raw-body@1.3.2 - - deps: iconv-lite@0.4.6 - -1.10.1 / 2015-01-01 -=================== - - * deps: on-finished@~2.2.0 - * deps: type-is@~1.5.5 - - deps: mime-types@~2.0.7 - -1.10.0 / 2014-12-02 -=================== - - * make internal `extended: true` array limit dynamic - -1.9.3 / 2014-11-21 -================== - - * deps: iconv-lite@0.4.5 - - Fix Windows-31J and X-SJIS encoding support - * deps: qs@2.3.3 - - Fix `arrayLimit` behavior - * deps: raw-body@1.3.1 - - deps: iconv-lite@0.4.5 - * deps: type-is@~1.5.3 - - deps: mime-types@~2.0.3 - -1.9.2 / 2014-10-27 -================== - - * deps: qs@2.3.2 - - Fix parsing of mixed objects and values - -1.9.1 / 2014-10-22 -================== - - * deps: on-finished@~2.1.1 - - Fix handling of pipelined requests - * deps: qs@2.3.0 - - Fix parsing of mixed implicit and explicit arrays - * deps: type-is@~1.5.2 - - deps: mime-types@~2.0.2 - -1.9.0 / 2014-09-24 -================== - - * include the charset in "unsupported charset" error message - * include the encoding in "unsupported content encoding" error message - * deps: depd@~1.0.0 - -1.8.4 / 2014-09-23 -================== - - * fix content encoding to be case-insensitive - -1.8.3 / 2014-09-19 -================== - - * deps: qs@2.2.4 - - Fix issue with object keys starting with numbers truncated - -1.8.2 / 2014-09-15 -================== - - * deps: depd@0.4.5 - -1.8.1 / 2014-09-07 -================== - - * deps: media-typer@0.3.0 - * deps: type-is@~1.5.1 - -1.8.0 / 2014-09-05 -================== - - * make empty-body-handling consistent between chunked requests - - empty `json` produces `{}` - - empty `raw` produces `new Buffer(0)` - - empty `text` produces `''` - - empty `urlencoded` produces `{}` - * deps: qs@2.2.3 - - Fix issue where first empty value in array is discarded - * deps: type-is@~1.5.0 - - fix `hasbody` to be true for `content-length: 0` - -1.7.0 / 2014-09-01 -================== - - * add `parameterLimit` option to `urlencoded` parser - * change `urlencoded` extended array limit to 100 - * respond with 413 when over `parameterLimit` in `urlencoded` - -1.6.7 / 2014-08-29 -================== - - * deps: qs@2.2.2 - - Remove unnecessary cloning - -1.6.6 / 2014-08-27 -================== - - * deps: qs@2.2.0 - - Array parsing fix - - Performance improvements - -1.6.5 / 2014-08-16 -================== - - * deps: on-finished@2.1.0 - -1.6.4 / 2014-08-14 -================== - - * deps: qs@1.2.2 - -1.6.3 / 2014-08-10 -================== - - * deps: qs@1.2.1 - -1.6.2 / 2014-08-07 -================== - - * deps: qs@1.2.0 - - Fix parsing array of objects - -1.6.1 / 2014-08-06 -================== - - * deps: qs@1.1.0 - - Accept urlencoded square brackets - - Accept empty values in implicit array notation - -1.6.0 / 2014-08-05 -================== - - * deps: qs@1.0.2 - - Complete rewrite - - Limits array length to 20 - - Limits object depth to 5 - - Limits parameters to 1,000 - -1.5.2 / 2014-07-27 -================== - - * deps: depd@0.4.4 - - Work-around v8 generating empty stack traces - -1.5.1 / 2014-07-26 -================== - - * deps: depd@0.4.3 - - Fix exception when global `Error.stackTraceLimit` is too low - -1.5.0 / 2014-07-20 -================== - - * deps: depd@0.4.2 - - Add `TRACE_DEPRECATION` environment variable - - Remove non-standard grey color from color output - - Support `--no-deprecation` argument - - Support `--trace-deprecation` argument - * deps: iconv-lite@0.4.4 - - Added encoding UTF-7 - * deps: raw-body@1.3.0 - - deps: iconv-lite@0.4.4 - - Added encoding UTF-7 - - Fix `Cannot switch to old mode now` error on Node.js 0.10+ - * deps: type-is@~1.3.2 - -1.4.3 / 2014-06-19 -================== - - * deps: type-is@1.3.1 - - fix global variable leak - -1.4.2 / 2014-06-19 -================== - - * deps: type-is@1.3.0 - - improve type parsing - -1.4.1 / 2014-06-19 -================== - - * fix urlencoded extended deprecation message - -1.4.0 / 2014-06-19 -================== - - * add `text` parser - * add `raw` parser - * check accepted charset in content-type (accepts utf-8) - * check accepted encoding in content-encoding (accepts identity) - * deprecate `bodyParser()` middleware; use `.json()` and `.urlencoded()` as needed - * deprecate `urlencoded()` without provided `extended` option - * lazy-load urlencoded parsers - * parsers split into files for reduced mem usage - * support gzip and deflate bodies - - set `inflate: false` to turn off - * deps: raw-body@1.2.2 - - Support all encodings from `iconv-lite` - -1.3.1 / 2014-06-11 -================== - - * deps: type-is@1.2.1 - - Switch dependency from mime to mime-types@1.0.0 - -1.3.0 / 2014-05-31 -================== - - * add `extended` option to urlencoded parser - -1.2.2 / 2014-05-27 -================== - - * deps: raw-body@1.1.6 - - assert stream encoding on node.js 0.8 - - assert stream encoding on node.js < 0.10.6 - - deps: bytes@1 - -1.2.1 / 2014-05-26 -================== - - * invoke `next(err)` after request fully read - - prevents hung responses and socket hang ups - -1.2.0 / 2014-05-11 -================== - - * add `verify` option - * deps: type-is@1.2.0 - - support suffix matching - -1.1.2 / 2014-05-11 -================== - - * improve json parser speed - -1.1.1 / 2014-05-11 -================== - - * fix repeated limit parsing with every request - -1.1.0 / 2014-05-10 -================== - - * add `type` option - * deps: pin for safety and consistency - -1.0.2 / 2014-04-14 -================== - - * use `type-is` module - -1.0.1 / 2014-03-20 -================== - - * lower default limits to 100kb diff --git a/node_modules/body-parser/LICENSE b/node_modules/body-parser/LICENSE deleted file mode 100644 index 386b7b6..0000000 --- a/node_modules/body-parser/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -(The MIT License) - -Copyright (c) 2014 Jonathan Ong -Copyright (c) 2014-2015 Douglas Christopher Wilson - -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. diff --git a/node_modules/body-parser/README.md b/node_modules/body-parser/README.md deleted file mode 100644 index f6661b7..0000000 --- a/node_modules/body-parser/README.md +++ /dev/null @@ -1,476 +0,0 @@ -# body-parser - -[![NPM Version][npm-version-image]][npm-url] -[![NPM Downloads][npm-downloads-image]][npm-url] -[![Build Status][ci-image]][ci-url] -[![Test Coverage][coveralls-image]][coveralls-url] -[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer] - -Node.js body parsing middleware. - -Parse incoming request bodies in a middleware before your handlers, available -under the `req.body` property. - -**Note** As `req.body`'s shape is based on user-controlled input, all -properties and values in this object are untrusted and should be validated -before trusting. For example, `req.body.foo.toString()` may fail in multiple -ways, for example the `foo` property may not be there or may not be a string, -and `toString` may not be a function and instead a string or other user input. - -[Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/). - -_This does not handle multipart bodies_, due to their complex and typically -large nature. For multipart bodies, you may be interested in the following -modules: - - * [busboy](https://www.npmjs.org/package/busboy#readme) and - [connect-busboy](https://www.npmjs.org/package/connect-busboy#readme) - * [multiparty](https://www.npmjs.org/package/multiparty#readme) and - [connect-multiparty](https://www.npmjs.org/package/connect-multiparty#readme) - * [formidable](https://www.npmjs.org/package/formidable#readme) - * [multer](https://www.npmjs.org/package/multer#readme) - -This module provides the following parsers: - - * [JSON body parser](#bodyparserjsonoptions) - * [Raw body parser](#bodyparserrawoptions) - * [Text body parser](#bodyparsertextoptions) - * [URL-encoded form body parser](#bodyparserurlencodedoptions) - -Other body parsers you might be interested in: - -- [body](https://www.npmjs.org/package/body#readme) -- [co-body](https://www.npmjs.org/package/co-body#readme) - -## Installation - -```sh -$ npm install body-parser -``` - -## API - -```js -var bodyParser = require('body-parser') -``` - -The `bodyParser` object exposes various factories to create middlewares. All -middlewares will populate the `req.body` property with the parsed body when -the `Content-Type` request header matches the `type` option, or an empty -object (`{}`) if there was no body to parse, the `Content-Type` was not matched, -or an error occurred. - -The various errors returned by this module are described in the -[errors section](#errors). - -### bodyParser.json([options]) - -Returns middleware that only parses `json` and only looks at requests where -the `Content-Type` header matches the `type` option. This parser accepts any -Unicode encoding of the body and supports automatic inflation of `gzip` and -`deflate` encodings. - -A new `body` object containing the parsed data is populated on the `request` -object after the middleware (i.e. `req.body`). - -#### Options - -The `json` function takes an optional `options` object that may contain any of -the following keys: - -##### inflate - -When set to `true`, then deflated (compressed) bodies will be inflated; when -`false`, deflated bodies are rejected. Defaults to `true`. - -##### limit - -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](https://www.npmjs.com/package/bytes) library for parsing. Defaults -to `'100kb'`. - -##### reviver - -The `reviver` option is passed directly to `JSON.parse` as the second -argument. You can find more information on this argument -[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter). - -##### strict - -When set to `true`, will only accept arrays and objects; when `false` will -accept anything `JSON.parse` accepts. Defaults to `true`. - -##### type - -The `type` option is used to determine what media type the middleware will -parse. This option can be a string, array of strings, or a function. If not a -function, `type` option is passed directly to the -[type-is](https://www.npmjs.org/package/type-is#readme) library and this can -be an extension name (like `json`), a mime type (like `application/json`), or -a mime type with a wildcard (like `*/*` or `*/json`). If a function, the `type` -option is called as `fn(req)` and the request is parsed if it returns a truthy -value. Defaults to `application/json`. - -##### verify - -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. The parsing can be aborted by throwing an error. - -### bodyParser.raw([options]) - -Returns middleware that parses all bodies as a `Buffer` and only looks at -requests where the `Content-Type` header matches the `type` option. This -parser supports automatic inflation of `gzip` and `deflate` encodings. - -A new `body` object containing the parsed data is populated on the `request` -object after the middleware (i.e. `req.body`). This will be a `Buffer` object -of the body. - -#### Options - -The `raw` function takes an optional `options` object that may contain any of -the following keys: - -##### inflate - -When set to `true`, then deflated (compressed) bodies will be inflated; when -`false`, deflated bodies are rejected. Defaults to `true`. - -##### limit - -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](https://www.npmjs.com/package/bytes) library for parsing. Defaults -to `'100kb'`. - -##### type - -The `type` option is used to determine what media type the middleware will -parse. This option can be a string, array of strings, or a function. -If not a function, `type` option is passed directly to the -[type-is](https://www.npmjs.org/package/type-is#readme) library and this -can be an extension name (like `bin`), a mime type (like -`application/octet-stream`), or a mime type with a wildcard (like `*/*` or -`application/*`). If a function, the `type` option is called as `fn(req)` -and the request is parsed if it returns a truthy value. Defaults to -`application/octet-stream`. - -##### verify - -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. The parsing can be aborted by throwing an error. - -### bodyParser.text([options]) - -Returns middleware that parses all bodies as a string and only looks at -requests where the `Content-Type` header matches the `type` option. This -parser supports automatic inflation of `gzip` and `deflate` encodings. - -A new `body` string containing the parsed data is populated on the `request` -object after the middleware (i.e. `req.body`). This will be a string of the -body. - -#### Options - -The `text` function takes an optional `options` object that may contain any of -the following keys: - -##### defaultCharset - -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`. - -##### inflate - -When set to `true`, then deflated (compressed) bodies will be inflated; when -`false`, deflated bodies are rejected. Defaults to `true`. - -##### limit - -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](https://www.npmjs.com/package/bytes) library for parsing. Defaults -to `'100kb'`. - -##### type - -The `type` option is used to determine what media type the middleware will -parse. This option can be a string, array of strings, or a function. If not -a function, `type` option is passed directly to the -[type-is](https://www.npmjs.org/package/type-is#readme) library and this can -be an extension name (like `txt`), a mime type (like `text/plain`), or a mime -type with a wildcard (like `*/*` or `text/*`). If a function, the `type` -option is called as `fn(req)` and the request is parsed if it returns a -truthy value. Defaults to `text/plain`. - -##### verify - -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. The parsing can be aborted by throwing an error. - -### bodyParser.urlencoded([options]) - -Returns middleware that only parses `urlencoded` bodies and only looks at -requests where the `Content-Type` header matches the `type` option. This -parser accepts only UTF-8 encoding of the body and supports automatic -inflation of `gzip` and `deflate` encodings. - -A new `body` object containing the parsed data is populated on the `request` -object after the middleware (i.e. `req.body`). This object will contain -key-value pairs, where the value can be a string or array (when `extended` is -`false`), or any type (when `extended` is `true`). - -#### Options - -The `urlencoded` function takes an optional `options` object that may contain -any of the following keys: - -##### extended - -The `extended` option allows to choose between parsing the URL-encoded data -with the `querystring` library (when `false`) or the `qs` library (when -`true`). The "extended" syntax allows for rich objects and arrays to be -encoded into the URL-encoded format, allowing for a JSON-like experience -with URL-encoded. For more information, please -[see the qs library](https://www.npmjs.org/package/qs#readme). - -Defaults to `true`, but using the default has been deprecated. Please -research into the difference between `qs` and `querystring` and choose the -appropriate setting. - -##### inflate - -When set to `true`, then deflated (compressed) bodies will be inflated; when -`false`, deflated bodies are rejected. Defaults to `true`. - -##### limit - -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](https://www.npmjs.com/package/bytes) library for parsing. Defaults -to `'100kb'`. - -##### parameterLimit - -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`. - -##### type - -The `type` option is used to determine what media type the middleware will -parse. This option can be a string, array of strings, or a function. If not -a function, `type` option is passed directly to the -[type-is](https://www.npmjs.org/package/type-is#readme) library and this can -be an extension name (like `urlencoded`), a mime type (like -`application/x-www-form-urlencoded`), or a mime type with a wildcard (like -`*/x-www-form-urlencoded`). If a function, the `type` option is called as -`fn(req)` and the request is parsed if it returns a truthy value. Defaults -to `application/x-www-form-urlencoded`. - -##### verify - -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. The parsing can be aborted by throwing an error. - -#### depth - -The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible. - -## Errors - -The middlewares provided by this module create errors using the -[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors -will typically have a `status`/`statusCode` property that contains the suggested -HTTP response code, an `expose` property to determine if the `message` property -should be displayed to the client, a `type` property to determine the type of -error without matching against the `message`, and a `body` property containing -the read body, if available. - -The following are the common errors created, though any error can come through -for various reasons. - -### content encoding unsupported - -This error will occur when the request had a `Content-Encoding` header that -contained an encoding but the "inflation" option was set to `false`. The -`status` property is set to `415`, the `type` property is set to -`'encoding.unsupported'`, and the `charset` property will be set to the -encoding that is unsupported. - -### entity parse failed - -This error will occur when the request contained an entity that could not be -parsed by the middleware. The `status` property is set to `400`, the `type` -property is set to `'entity.parse.failed'`, and the `body` property is set to -the entity value that failed parsing. - -### entity verify failed - -This error will occur when the request contained an entity that could not be -failed verification by the defined `verify` option. The `status` property is -set to `403`, the `type` property is set to `'entity.verify.failed'`, and the -`body` property is set to the entity value that failed verification. - -### request aborted - -This error will occur when the request is aborted by the client before reading -the body has finished. The `received` property will be set to the number of -bytes received before the request was aborted and the `expected` property is -set to the number of expected bytes. The `status` property is set to `400` -and `type` property is set to `'request.aborted'`. - -### request entity too large - -This error will occur when the request body's size is larger than the "limit" -option. The `limit` property will be set to the byte limit and the `length` -property will be set to the request body's length. The `status` property is -set to `413` and the `type` property is set to `'entity.too.large'`. - -### request size did not match content length - -This error will occur when the request's length did not match the length from -the `Content-Length` header. This typically occurs when the request is malformed, -typically when the `Content-Length` header was calculated based on characters -instead of bytes. The `status` property is set to `400` and the `type` property -is set to `'request.size.invalid'`. - -### stream encoding should not be set - -This error will occur when something called the `req.setEncoding` method prior -to this middleware. This module operates directly on bytes only and you cannot -call `req.setEncoding` when using this module. The `status` property is set to -`500` and the `type` property is set to `'stream.encoding.set'`. - -### stream is not readable - -This error will occur when the request is no longer readable when this middleware -attempts to read it. This typically means something other than a middleware from -this module read the request body already and the middleware was also configured to -read the same request. The `status` property is set to `500` and the `type` -property is set to `'stream.not.readable'`. - -### too many parameters - -This error will occur when the content of the request exceeds the configured -`parameterLimit` for the `urlencoded` parser. The `status` property is set to -`413` and the `type` property is set to `'parameters.too.many'`. - -### unsupported charset "BOGUS" - -This error will occur when the request had a charset parameter in the -`Content-Type` header, but the `iconv-lite` module does not support it OR the -parser does not support it. The charset is contained in the message as well -as in the `charset` property. The `status` property is set to `415`, the -`type` property is set to `'charset.unsupported'`, and the `charset` property -is set to the charset that is unsupported. - -### unsupported content encoding "bogus" - -This error will occur when the request had a `Content-Encoding` header that -contained an unsupported encoding. The encoding is contained in the message -as well as in the `encoding` property. The `status` property is set to `415`, -the `type` property is set to `'encoding.unsupported'`, and the `encoding` -property is set to the encoding that is unsupported. - -### The input exceeded the depth - -This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown. - -## Examples - -### Express/Connect top-level generic - -This example demonstrates adding a generic JSON and URL-encoded parser as a -top-level middleware, which will parse the bodies of all incoming requests. -This is the simplest setup. - -```js -var express = require('express') -var bodyParser = require('body-parser') - -var app = express() - -// parse application/x-www-form-urlencoded -app.use(bodyParser.urlencoded({ extended: false })) - -// parse application/json -app.use(bodyParser.json()) - -app.use(function (req, res) { - res.setHeader('Content-Type', 'text/plain') - res.write('you posted:\n') - res.end(JSON.stringify(req.body, null, 2)) -}) -``` - -### Express route-specific - -This example demonstrates adding body parsers specifically to the routes that -need them. In general, this is the most recommended way to use body-parser with -Express. - -```js -var express = require('express') -var bodyParser = require('body-parser') - -var app = express() - -// create application/json parser -var jsonParser = bodyParser.json() - -// create application/x-www-form-urlencoded parser -var urlencodedParser = bodyParser.urlencoded({ extended: false }) - -// POST /login gets urlencoded bodies -app.post('/login', urlencodedParser, function (req, res) { - res.send('welcome, ' + req.body.username) -}) - -// POST /api/users gets JSON bodies -app.post('/api/users', jsonParser, function (req, res) { - // create user in req.body -}) -``` - -### Change accepted type for parsers - -All the parsers accept a `type` option which allows you to change the -`Content-Type` that the middleware will parse. - -```js -var express = require('express') -var bodyParser = require('body-parser') - -var app = express() - -// parse various different custom JSON types as JSON -app.use(bodyParser.json({ type: 'application/*+json' })) - -// parse some custom thing into a Buffer -app.use(bodyParser.raw({ type: 'application/vnd.custom-type' })) - -// parse an HTML body into a string -app.use(bodyParser.text({ type: 'text/html' })) -``` - -## License - -[MIT](LICENSE) - -[ci-image]: https://badgen.net/github/checks/expressjs/body-parser/master?label=ci -[ci-url]: https://github.com/expressjs/body-parser/actions/workflows/ci.yml -[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/body-parser/master -[coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master -[node-version-image]: https://badgen.net/npm/node/body-parser -[node-version-url]: https://nodejs.org/en/download -[npm-downloads-image]: https://badgen.net/npm/dm/body-parser -[npm-url]: https://npmjs.org/package/body-parser -[npm-version-image]: https://badgen.net/npm/v/body-parser -[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge -[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/body-parser \ No newline at end of file diff --git a/node_modules/body-parser/index.js b/node_modules/body-parser/index.js deleted file mode 100644 index bb24d73..0000000 --- a/node_modules/body-parser/index.js +++ /dev/null @@ -1,156 +0,0 @@ -/*! - * body-parser - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ - -'use strict' - -/** - * Module dependencies. - * @private - */ - -var deprecate = require('depd')('body-parser') - -/** - * Cache of loaded parsers. - * @private - */ - -var parsers = Object.create(null) - -/** - * @typedef Parsers - * @type {function} - * @property {function} json - * @property {function} raw - * @property {function} text - * @property {function} urlencoded - */ - -/** - * Module exports. - * @type {Parsers} - */ - -exports = module.exports = deprecate.function(bodyParser, - 'bodyParser: use individual json/urlencoded middlewares') - -/** - * JSON parser. - * @public - */ - -Object.defineProperty(exports, 'json', { - configurable: true, - enumerable: true, - get: createParserGetter('json') -}) - -/** - * Raw parser. - * @public - */ - -Object.defineProperty(exports, 'raw', { - configurable: true, - enumerable: true, - get: createParserGetter('raw') -}) - -/** - * Text parser. - * @public - */ - -Object.defineProperty(exports, 'text', { - configurable: true, - enumerable: true, - get: createParserGetter('text') -}) - -/** - * URL-encoded parser. - * @public - */ - -Object.defineProperty(exports, 'urlencoded', { - configurable: true, - enumerable: true, - get: createParserGetter('urlencoded') -}) - -/** - * Create a middleware to parse json and urlencoded bodies. - * - * @param {object} [options] - * @return {function} - * @deprecated - * @public - */ - -function bodyParser (options) { - // use default type for parsers - var opts = Object.create(options || null, { - type: { - configurable: true, - enumerable: true, - value: undefined, - writable: true - } - }) - - var _urlencoded = exports.urlencoded(opts) - var _json = exports.json(opts) - - return function bodyParser (req, res, next) { - _json(req, res, function (err) { - if (err) return next(err) - _urlencoded(req, res, next) - }) - } -} - -/** - * Create a getter for loading a parser. - * @private - */ - -function createParserGetter (name) { - return function get () { - return loadParser(name) - } -} - -/** - * Load a parser module. - * @private - */ - -function loadParser (parserName) { - var parser = parsers[parserName] - - if (parser !== undefined) { - return parser - } - - // this uses a switch for static require analysis - switch (parserName) { - case 'json': - parser = require('./lib/types/json') - break - case 'raw': - parser = require('./lib/types/raw') - break - case 'text': - parser = require('./lib/types/text') - break - case 'urlencoded': - parser = require('./lib/types/urlencoded') - break - } - - // store to prevent invoking require() - return (parsers[parserName] = parser) -} diff --git a/node_modules/body-parser/lib/read.js b/node_modules/body-parser/lib/read.js deleted file mode 100644 index fce6283..0000000 --- a/node_modules/body-parser/lib/read.js +++ /dev/null @@ -1,205 +0,0 @@ -/*! - * body-parser - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ - -'use strict' - -/** - * Module dependencies. - * @private - */ - -var createError = require('http-errors') -var destroy = require('destroy') -var getBody = require('raw-body') -var iconv = require('iconv-lite') -var onFinished = require('on-finished') -var unpipe = require('unpipe') -var zlib = require('zlib') - -/** - * Module exports. - */ - -module.exports = read - -/** - * Read a request into a buffer and parse. - * - * @param {object} req - * @param {object} res - * @param {function} next - * @param {function} parse - * @param {function} debug - * @param {object} options - * @private - */ - -function read (req, res, next, parse, debug, options) { - var length - var opts = options - var stream - - // flag as parsed - req._body = true - - // read options - var encoding = opts.encoding !== null - ? opts.encoding - : null - var verify = opts.verify - - try { - // get the content stream - stream = contentstream(req, debug, opts.inflate) - length = stream.length - stream.length = undefined - } catch (err) { - return next(err) - } - - // set raw-body options - opts.length = length - opts.encoding = verify - ? null - : encoding - - // assert charset is supported - if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) { - return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { - charset: encoding.toLowerCase(), - type: 'charset.unsupported' - })) - } - - // read body - debug('read body') - getBody(stream, opts, function (error, body) { - if (error) { - var _error - - if (error.type === 'encoding.unsupported') { - // echo back charset - _error = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { - charset: encoding.toLowerCase(), - type: 'charset.unsupported' - }) - } else { - // set status code on error - _error = createError(400, error) - } - - // unpipe from stream and destroy - if (stream !== req) { - unpipe(req) - destroy(stream, true) - } - - // read off entire request - dump(req, function onfinished () { - next(createError(400, _error)) - }) - return - } - - // verify - if (verify) { - try { - debug('verify body') - verify(req, res, body, encoding) - } catch (err) { - next(createError(403, err, { - body: body, - type: err.type || 'entity.verify.failed' - })) - return - } - } - - // parse - var str = body - try { - debug('parse body') - str = typeof body !== 'string' && encoding !== null - ? iconv.decode(body, encoding) - : body - req.body = parse(str) - } catch (err) { - next(createError(400, err, { - body: str, - type: err.type || 'entity.parse.failed' - })) - return - } - - next() - }) -} - -/** - * Get the content stream of the request. - * - * @param {object} req - * @param {function} debug - * @param {boolean} [inflate=true] - * @return {object} - * @api private - */ - -function contentstream (req, debug, inflate) { - var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase() - var length = req.headers['content-length'] - var stream - - debug('content-encoding "%s"', encoding) - - if (inflate === false && encoding !== 'identity') { - throw createError(415, 'content encoding unsupported', { - encoding: encoding, - type: 'encoding.unsupported' - }) - } - - switch (encoding) { - case 'deflate': - stream = zlib.createInflate() - debug('inflate body') - req.pipe(stream) - break - case 'gzip': - stream = zlib.createGunzip() - debug('gunzip body') - req.pipe(stream) - break - case 'identity': - stream = req - stream.length = length - break - default: - throw createError(415, 'unsupported content encoding "' + encoding + '"', { - encoding: encoding, - type: 'encoding.unsupported' - }) - } - - return stream -} - -/** - * Dump the contents of a request. - * - * @param {object} req - * @param {function} callback - * @api private - */ - -function dump (req, callback) { - if (onFinished.isFinished(req)) { - callback(null) - } else { - onFinished(req, callback) - req.resume() - } -} diff --git a/node_modules/body-parser/lib/types/json.js b/node_modules/body-parser/lib/types/json.js deleted file mode 100644 index d1f510d..0000000 --- a/node_modules/body-parser/lib/types/json.js +++ /dev/null @@ -1,243 +0,0 @@ -/*! - * body-parser - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ - -'use strict' - -/** - * Module dependencies. - * @private - */ - -var bytes = require('bytes') -var contentType = require('content-type') -var createError = require('http-errors') -var debug = require('debug')('body-parser:json') -var read = require('../read') -var typeis = require('type-is') - -/** - * Module exports. - */ - -module.exports = json - -/** - * RegExp to match the first non-space in a string. - * - * Allowed whitespace is defined in RFC 7159: - * - * ws = *( - * %x20 / ; Space - * %x09 / ; Horizontal tab - * %x0A / ; Line feed or New line - * %x0D ) ; Carriage return - */ - -var FIRST_CHAR_REGEXP = /^[\x20\x09\x0a\x0d]*([^\x20\x09\x0a\x0d])/ // eslint-disable-line no-control-regex - -var JSON_SYNTAX_CHAR = '#' -var JSON_SYNTAX_REGEXP = /#+/g - -/** - * Create a middleware to parse JSON bodies. - * - * @param {object} [options] - * @return {function} - * @public - */ - -function json (options) { - var opts = options || {} - - var limit = typeof opts.limit !== 'number' - ? bytes.parse(opts.limit || '100kb') - : opts.limit - var inflate = opts.inflate !== false - var reviver = opts.reviver - var strict = opts.strict !== false - var type = opts.type || 'application/json' - var verify = opts.verify || false - - if (verify !== false && typeof verify !== 'function') { - throw new TypeError('option verify must be function') - } - - // create the appropriate type checking function - var shouldParse = typeof type !== 'function' - ? typeChecker(type) - : type - - function parse (body) { - if (body.length === 0) { - // special-case empty json body, as it's a common client-side mistake - // TODO: maybe make this configurable or part of "strict" option - return {} - } - - if (strict) { - var first = firstchar(body) - - if (first !== '{' && first !== '[') { - debug('strict violation') - throw createStrictSyntaxError(body, first) - } - } - - try { - debug('parse json') - return JSON.parse(body, reviver) - } catch (e) { - throw normalizeJsonSyntaxError(e, { - message: e.message, - stack: e.stack - }) - } - } - - return function jsonParser (req, res, next) { - if (req._body) { - debug('body already parsed') - next() - return - } - - req.body = req.body || {} - - // skip requests without bodies - if (!typeis.hasBody(req)) { - debug('skip empty body') - next() - return - } - - debug('content-type %j', req.headers['content-type']) - - // determine if request should be parsed - if (!shouldParse(req)) { - debug('skip parsing') - next() - return - } - - // assert charset per RFC 7159 sec 8.1 - var charset = getCharset(req) || 'utf-8' - if (charset.slice(0, 4) !== 'utf-') { - debug('invalid charset') - next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { - charset: charset, - type: 'charset.unsupported' - })) - return - } - - // read - read(req, res, next, parse, debug, { - encoding: charset, - inflate: inflate, - limit: limit, - verify: verify - }) - } -} - -/** - * Create strict violation syntax error matching native error. - * - * @param {string} str - * @param {string} char - * @return {Error} - * @private - */ - -function createStrictSyntaxError (str, char) { - var index = str.indexOf(char) - var partial = '' - - if (index !== -1) { - partial = str.substring(0, index) + new Array(str.length - index + 1).join(JSON_SYNTAX_CHAR) - } - - try { - JSON.parse(partial); /* istanbul ignore next */ throw new SyntaxError('strict violation') - } catch (e) { - return normalizeJsonSyntaxError(e, { - message: e.message.replace(JSON_SYNTAX_REGEXP, function (placeholder) { - return str.substring(index, index + placeholder.length) - }), - stack: e.stack - }) - } -} - -/** - * Get the first non-whitespace character in a string. - * - * @param {string} str - * @return {function} - * @private - */ - -function firstchar (str) { - var match = FIRST_CHAR_REGEXP.exec(str) - - return match - ? match[1] - : undefined -} - -/** - * Get the charset of a request. - * - * @param {object} req - * @api private - */ - -function getCharset (req) { - try { - return (contentType.parse(req).parameters.charset || '').toLowerCase() - } catch (e) { - return undefined - } -} - -/** - * Normalize a SyntaxError for JSON.parse. - * - * @param {SyntaxError} error - * @param {object} obj - * @return {SyntaxError} - */ - -function normalizeJsonSyntaxError (error, obj) { - var keys = Object.getOwnPropertyNames(error) - - for (var i = 0; i < keys.length; i++) { - var key = keys[i] - if (key !== 'stack' && key !== 'message') { - delete error[key] - } - } - - // replace stack before message for Node.js 0.10 and below - error.stack = obj.stack.replace(error.message, obj.message) - error.message = obj.message - - return error -} - -/** - * Get the simple type checker. - * - * @param {string} type - * @return {function} - */ - -function typeChecker (type) { - return function checkType (req) { - return Boolean(typeis(req, type)) - } -} diff --git a/node_modules/body-parser/lib/types/raw.js b/node_modules/body-parser/lib/types/raw.js deleted file mode 100644 index f5d1b67..0000000 --- a/node_modules/body-parser/lib/types/raw.js +++ /dev/null @@ -1,101 +0,0 @@ -/*! - * body-parser - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ - -'use strict' - -/** - * Module dependencies. - */ - -var bytes = require('bytes') -var debug = require('debug')('body-parser:raw') -var read = require('../read') -var typeis = require('type-is') - -/** - * Module exports. - */ - -module.exports = raw - -/** - * Create a middleware to parse raw bodies. - * - * @param {object} [options] - * @return {function} - * @api public - */ - -function raw (options) { - var opts = options || {} - - var inflate = opts.inflate !== false - var limit = typeof opts.limit !== 'number' - ? bytes.parse(opts.limit || '100kb') - : opts.limit - var type = opts.type || 'application/octet-stream' - var verify = opts.verify || false - - if (verify !== false && typeof verify !== 'function') { - throw new TypeError('option verify must be function') - } - - // create the appropriate type checking function - var shouldParse = typeof type !== 'function' - ? typeChecker(type) - : type - - function parse (buf) { - return buf - } - - return function rawParser (req, res, next) { - if (req._body) { - debug('body already parsed') - next() - return - } - - req.body = req.body || {} - - // skip requests without bodies - if (!typeis.hasBody(req)) { - debug('skip empty body') - next() - return - } - - debug('content-type %j', req.headers['content-type']) - - // determine if request should be parsed - if (!shouldParse(req)) { - debug('skip parsing') - next() - return - } - - // read - read(req, res, next, parse, debug, { - encoding: null, - inflate: inflate, - limit: limit, - verify: verify - }) - } -} - -/** - * Get the simple type checker. - * - * @param {string} type - * @return {function} - */ - -function typeChecker (type) { - return function checkType (req) { - return Boolean(typeis(req, type)) - } -} diff --git a/node_modules/body-parser/lib/types/text.js b/node_modules/body-parser/lib/types/text.js deleted file mode 100644 index 083a009..0000000 --- a/node_modules/body-parser/lib/types/text.js +++ /dev/null @@ -1,121 +0,0 @@ -/*! - * body-parser - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ - -'use strict' - -/** - * Module dependencies. - */ - -var bytes = require('bytes') -var contentType = require('content-type') -var debug = require('debug')('body-parser:text') -var read = require('../read') -var typeis = require('type-is') - -/** - * Module exports. - */ - -module.exports = text - -/** - * Create a middleware to parse text bodies. - * - * @param {object} [options] - * @return {function} - * @api public - */ - -function text (options) { - var opts = options || {} - - var defaultCharset = opts.defaultCharset || 'utf-8' - var inflate = opts.inflate !== false - var limit = typeof opts.limit !== 'number' - ? bytes.parse(opts.limit || '100kb') - : opts.limit - var type = opts.type || 'text/plain' - var verify = opts.verify || false - - if (verify !== false && typeof verify !== 'function') { - throw new TypeError('option verify must be function') - } - - // create the appropriate type checking function - var shouldParse = typeof type !== 'function' - ? typeChecker(type) - : type - - function parse (buf) { - return buf - } - - return function textParser (req, res, next) { - if (req._body) { - debug('body already parsed') - next() - return - } - - req.body = req.body || {} - - // skip requests without bodies - if (!typeis.hasBody(req)) { - debug('skip empty body') - next() - return - } - - debug('content-type %j', req.headers['content-type']) - - // determine if request should be parsed - if (!shouldParse(req)) { - debug('skip parsing') - next() - return - } - - // get charset - var charset = getCharset(req) || defaultCharset - - // read - read(req, res, next, parse, debug, { - encoding: charset, - inflate: inflate, - limit: limit, - verify: verify - }) - } -} - -/** - * Get the charset of a request. - * - * @param {object} req - * @api private - */ - -function getCharset (req) { - try { - return (contentType.parse(req).parameters.charset || '').toLowerCase() - } catch (e) { - return undefined - } -} - -/** - * Get the simple type checker. - * - * @param {string} type - * @return {function} - */ - -function typeChecker (type) { - return function checkType (req) { - return Boolean(typeis(req, type)) - } -} diff --git a/node_modules/body-parser/lib/types/urlencoded.js b/node_modules/body-parser/lib/types/urlencoded.js deleted file mode 100644 index 892e346..0000000 --- a/node_modules/body-parser/lib/types/urlencoded.js +++ /dev/null @@ -1,299 +0,0 @@ -/*! - * body-parser - * Copyright(c) 2014 Jonathan Ong - * Copyright(c) 2014-2015 Douglas Christopher Wilson - * MIT Licensed - */ - -'use strict' - -/** - * Module dependencies. - * @private - */ - -var bytes = require('bytes') -var contentType = require('content-type') -var createError = require('http-errors') -var debug = require('debug')('body-parser:urlencoded') -var deprecate = require('depd')('body-parser') -var read = require('../read') -var typeis = require('type-is') - -/** - * Module exports. - */ - -module.exports = urlencoded - -/** - * Cache of parser modules. - */ - -var parsers = Object.create(null) - -/** - * Create a middleware to parse urlencoded bodies. - * - * @param {object} [options] - * @return {function} - * @public - */ - -function urlencoded (options) { - var opts = options || {} - - // notice because option default will flip in next major - if (opts.extended === undefined) { - deprecate('undefined extended: provide extended option') - } - - var extended = opts.extended !== false - var inflate = opts.inflate !== false - var limit = typeof opts.limit !== 'number' - ? bytes.parse(opts.limit || '100kb') - : opts.limit - var type = opts.type || 'application/x-www-form-urlencoded' - var verify = opts.verify || false - - if (verify !== false && typeof verify !== 'function') { - throw new TypeError('option verify must be function') - } - - // create the appropriate query parser - var queryparse = extended - ? extendedparser(opts) - : simpleparser(opts) - - // create the appropriate type checking function - var shouldParse = typeof type !== 'function' - ? typeChecker(type) - : type - - function parse (body) { - return body.length - ? queryparse(body) - : {} - } - - return function urlencodedParser (req, res, next) { - if (req._body) { - debug('body already parsed') - next() - return - } - - req.body = req.body || {} - - // skip requests without bodies - if (!typeis.hasBody(req)) { - debug('skip empty body') - next() - return - } - - debug('content-type %j', req.headers['content-type']) - - // determine if request should be parsed - if (!shouldParse(req)) { - debug('skip parsing') - next() - return - } - - // assert charset - var charset = getCharset(req) || 'utf-8' - if (charset !== 'utf-8') { - debug('invalid charset') - next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { - charset: charset, - type: 'charset.unsupported' - })) - return - } - - // read - read(req, res, next, parse, debug, { - debug: debug, - encoding: charset, - inflate: inflate, - limit: limit, - verify: verify - }) - } -} - -/** - * Get the extended query parser. - * - * @param {object} options - */ - -function extendedparser (options) { - var parameterLimit = options.parameterLimit !== undefined - ? options.parameterLimit - : 1000 - var depth = options.depth !== undefined ? options.depth : 32 - var parse = parser('qs') - - if (isNaN(parameterLimit) || parameterLimit < 1) { - throw new TypeError('option parameterLimit must be a positive number') - } - - if (isNaN(depth) || depth < 0) { - throw new TypeError('option depth must be a zero or a positive number') - } - - if (isFinite(parameterLimit)) { - parameterLimit = parameterLimit | 0 - } - - return function queryparse (body) { - var paramCount = parameterCount(body, parameterLimit) - - if (paramCount === undefined) { - debug('too many parameters') - throw createError(413, 'too many parameters', { - type: 'parameters.too.many' - }) - } - - var arrayLimit = Math.max(100, paramCount) - - debug('parse extended urlencoding') - try { - return parse(body, { - allowPrototypes: true, - arrayLimit: arrayLimit, - depth: depth, - strictDepth: true, - parameterLimit: parameterLimit - }) - } catch (err) { - if (err instanceof RangeError) { - throw createError(400, 'The input exceeded the depth', { - type: 'querystring.parse.rangeError' - }) - } else { - throw err - } - } - } -} - -/** - * Get the charset of a request. - * - * @param {object} req - * @api private - */ - -function getCharset (req) { - try { - return (contentType.parse(req).parameters.charset || '').toLowerCase() - } catch (e) { - return undefined - } -} - -/** - * Count the number of parameters, stopping once limit reached - * - * @param {string} body - * @param {number} limit - * @api private - */ - -function parameterCount (body, limit) { - var count = 0 - var index = -1 - - do { - count++ - if (count > limit) { - return undefined - } - index = body.indexOf('&', index + 1) - } while (index !== -1) - - return count -} - -/** - * Get parser for module name dynamically. - * - * @param {string} name - * @return {function} - * @api private - */ - -function parser (name) { - var mod = parsers[name] - - if (mod !== undefined) { - return mod.parse - } - - // this uses a switch for static require analysis - switch (name) { - case 'qs': - mod = require('qs') - break - case 'querystring': - mod = require('querystring') - break - } - - // store to prevent invoking require() - parsers[name] = mod - - return mod.parse -} - -/** - * Get the simple query parser. - * - * @param {object} options - */ - -function simpleparser (options) { - var parameterLimit = options.parameterLimit !== undefined - ? options.parameterLimit - : 1000 - var parse = parser('querystring') - - if (isNaN(parameterLimit) || parameterLimit < 1) { - throw new TypeError('option parameterLimit must be a positive number') - } - - if (isFinite(parameterLimit)) { - parameterLimit = parameterLimit | 0 - } - - return function queryparse (body) { - var paramCount = parameterCount(body, parameterLimit) - - if (paramCount === undefined) { - debug('too many parameters') - throw createError(413, 'too many parameters', { - type: 'parameters.too.many' - }) - } - - debug('parse urlencoding') - return parse(body, undefined, undefined, { maxKeys: parameterLimit }) - } -} - -/** - * Get the simple type checker. - * - * @param {string} type - * @return {function} - */ - -function typeChecker (type) { - return function checkType (req) { - return Boolean(typeis(req, type)) - } -} diff --git a/node_modules/body-parser/node_modules/qs/.editorconfig b/node_modules/body-parser/node_modules/qs/.editorconfig deleted file mode 100644 index dd5a8d8..0000000 --- a/node_modules/body-parser/node_modules/qs/.editorconfig +++ /dev/null @@ -1,46 +0,0 @@ -root = true - -[*] -indent_style = space -indent_size = 4 -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true -max_line_length = 180 -quote_type = single - -[test/*] -max_line_length = off - -[LICENSE.md] -indent_size = off - -[*.md] -max_line_length = off - -[*.json] -max_line_length = off - -[Makefile] -max_line_length = off - -[CHANGELOG.md] -indent_style = space -indent_size = 2 - -[LICENSE] -indent_size = 2 -max_line_length = off - -[coverage/**/*] -indent_size = off -indent_style = off -indent = off -max_line_length = off - -[.nycrc] -indent_style = tab - -[tea.yaml] -indent_size = 2 diff --git a/node_modules/body-parser/node_modules/qs/.github/FUNDING.yml b/node_modules/body-parser/node_modules/qs/.github/FUNDING.yml deleted file mode 100644 index 0355f4f..0000000 --- a/node_modules/body-parser/node_modules/qs/.github/FUNDING.yml +++ /dev/null @@ -1,12 +0,0 @@ -# These are supported funding model platforms - -github: [ljharb] -patreon: # Replace with a single Patreon username -open_collective: # Replace with a single Open Collective username -ko_fi: # Replace with a single Ko-fi username -tidelift: npm/qs -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: # Replace with a single Liberapay username -issuehunt: # Replace with a single IssueHunt username -otechie: # Replace with a single Otechie username -custom: # Replace with a single custom sponsorship URL diff --git a/node_modules/body-parser/node_modules/qs/.github/SECURITY.md b/node_modules/body-parser/node_modules/qs/.github/SECURITY.md deleted file mode 100644 index b499cb6..0000000 --- a/node_modules/body-parser/node_modules/qs/.github/SECURITY.md +++ /dev/null @@ -1,11 +0,0 @@ -# Security - -Please file a private vulnerability report via GitHub, email [@ljharb](https://github.com/ljharb), or see https://tidelift.com/security if you have a potential security vulnerability to report. - -## Incident Response Plan - -Please see our [Incident Response Plan](https://github.com/ljharb/.github/blob/main/INCIDENT_RESPONSE_PLAN.md). - -## Threat Model - -Please see [THREAT_MODEL.md](./THREAT_MODEL.md). diff --git a/node_modules/body-parser/node_modules/qs/.github/THREAT_MODEL.md b/node_modules/body-parser/node_modules/qs/.github/THREAT_MODEL.md deleted file mode 100644 index 7e6fef1..0000000 --- a/node_modules/body-parser/node_modules/qs/.github/THREAT_MODEL.md +++ /dev/null @@ -1,78 +0,0 @@ -## Threat Model for qs (querystring parsing library) - -### 1. Library Overview - -- **Library Name:** qs -- **Brief Description:** A JavaScript library for parsing and stringifying URL query strings, supporting nested objects and arrays. It is widely used in Node.js and web applications for processing query parameters[2][6][8]. -- **Key Public APIs/Functions:** `qs.parse()`, `qs.stringify()` - -### 2. Define Scope - -This threat model focuses on the core parsing and stringifying functionality, specifically the handling of nested objects and arrays, option validation, and cycle management in stringification. - -### 3. Conceptual System Diagram - -``` -Caller Application → qs.parse(input, options) → Parsing Engine → Output Object - │ - └→ Options Handling - -Caller Application → qs.stringify(obj, options) → Stringifying Engine → Output String - │ - └→ Options Handling - └→ Cycle Tracking -``` - -**Trust Boundaries:** -- **Input string (parse):** May come from untrusted sources (e.g., user input, network requests) -- **Input object (stringify):** May contain cycles, which can lead to infinite loops during stringification -- **Options:** Provided by the caller -- **Cycle Tracking:** Used only during stringification to detect and handle circular references - -### 4. Identify Assets - -- **Integrity of parsed output:** Prevent malicious manipulation of the output object structure, especially ensuring builtins/globals are not modified as a result of parse[3][4][8]. -- **Confidentiality of processed data:** Avoid leaking sensitive information through errors or output. -- **Availability/performance for host application:** Prevent crashes or resource exhaustion in the consuming application. -- **Security of host application:** Prevent the library from being a vector for attacks (e.g., prototype pollution, DoS). -- **Reputation of library:** Maintain trust by avoiding supply chain attacks and vulnerabilities[1]. - -### 5. Identify Threats - -| Component / API / Interaction | S | T | R | I | D | E | -|---------------------------------------|----|----|----|----|----|----| -| Public API Call (`parse`) | – | ✓ | – | ✓ | ✓ | ✓ | -| Public API Call (`stringify`) | – | ✓ | – | ✓ | ✓ | – | -| Options Handling | ✓ | ✓ | – | ✓ | – | ✓ | -| Dependency Interaction | – | – | – | – | ✓ | – | - -**Key Threats:** -- **Tampering:** Malicious input can, if not prevented, alter parsed output (e.g., prototype pollution via `__proto__`, modification of builtins/globals)[3][4][8]. -- **Information Disclosure:** Error messages may expose internal details or sensitive data. -- **Denial of Service:** Large or malformed input can exhaust memory or CPU. -- **Elevation of Privilege:** Prototype pollution can lead to unintended privilege escalation in the host application[3][4][8]. - -### 6. Mitigation/Countermeasures - -| Threat Identified | Proposed Mitigation | -|---------------------------------------------------|---------------------| -| Tampering (malicious input, prototype pollution) | Strict input validation; keep `allowPrototypes: false` by default; use `plainObjects` for output; ensure builtins/globals are never modified by parse[4][8]. | -| Information Disclosure (error messages) | Generic error messages without stack traces or internal paths. | -| Denial of Service (memory/CPU exhaustion) | Enforce `arrayLimit` and `parameterLimit` with safe defaults; enable `throwOnLimitExceeded`; limit nesting depth[7]. | -| Elevation of Privilege (prototype pollution) | Keep `allowPrototypes: false`; validate options against allowlist; use `plainObjects` to avoid prototype pollution[4][8]. | - -### 7. Risk Ranking - -- **High:** Denial of Service via array parsing or malformed input (historical vulnerability) -- **Medium:** Prototype pollution via options or input (if `allowPrototypes` enabled) -- **Low:** Information disclosure in errors - -### 8. Next Steps & Review - -1. **Audit option validation logic.** -2. **Add depth limiting to nested parsing and stringification.** -3. **Implement fuzz testing for parser and stringifier edge cases.** -4. **Regularly review dependencies for vulnerabilities.** -5. **Keep documentation and threat model up to date.** -6. **Ensure builtins/globals are never modified as a result of parse.** -7. **Support round-trip consistency between parse and stringify as a non-security goal, with the right options[5][9].** diff --git a/node_modules/body-parser/node_modules/qs/.nycrc b/node_modules/body-parser/node_modules/qs/.nycrc deleted file mode 100644 index 1d57cab..0000000 --- a/node_modules/body-parser/node_modules/qs/.nycrc +++ /dev/null @@ -1,13 +0,0 @@ -{ - "all": true, - "check-coverage": false, - "reporter": ["text-summary", "text", "html", "json"], - "lines": 86, - "statements": 85.93, - "functions": 82.43, - "branches": 76.06, - "exclude": [ - "coverage", - "dist" - ] -} diff --git a/node_modules/body-parser/node_modules/qs/CHANGELOG.md b/node_modules/body-parser/node_modules/qs/CHANGELOG.md deleted file mode 100644 index c1c8041..0000000 --- a/node_modules/body-parser/node_modules/qs/CHANGELOG.md +++ /dev/null @@ -1,812 +0,0 @@ -## **6.15.1** -- [Fix] `parse`: `parameterLimit: Infinity` with `throwOnLimitExceeded: true` silently drops all parameters -- [Deps] update `@ljharb/eslint-config` -- [Dev Deps] update `@ljharb/eslint-config`, `iconv-lite` -- [Tests] increase coverage - -## **6.15.0** -- [New] `parse`: add `strictMerge` option to wrap object/primitive conflicts in an array (#425, #122) -- [Fix] `duplicates` option should not apply to bracket notation keys (#514) - -## **6.14.2** -- [Fix] `parse`: mark overflow objects for indexed notation exceeding `arrayLimit` (#546) -- [Fix] `arrayLimit` means max count, not max index, in `combine`/`merge`/`parseArrayValue` -- [Fix] `parse`: throw on `arrayLimit` exceeded with indexed notation when `throwOnLimitExceeded` is true (#529) -- [Fix] `parse`: enforce `arrayLimit` on `comma`-parsed values -- [Fix] `parse`: fix error message to reflect arrayLimit as max index; remove extraneous comments (#545) -- [Robustness] avoid `.push`, use `void` -- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418) -- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543) -- [readme] replace runkit CI badge with shields.io check-runs badge -- [meta] fix changelog typo (`arrayLength` → `arrayLimit`) -- [actions] fix rebase workflow permissions - -## **6.14.1** -- [Fix] ensure `arrayLimit` applies to `[]` notation as well -- [Fix] `parse`: when a custom decoder returns `null` for a key, ignore that key -- [Refactor] `parse`: extract key segment splitting helper -- [meta] add threat model -- [actions] add workflow permissions -- [Tests] `stringify`: increase coverage -- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `npmignore`, `es-value-fixtures`, `for-each`, `object-inspect` - -## **6.14.0** -- [New] `parse`: add `throwOnParameterLimitExceeded` option (#517) -- [Refactor] `parse`: use `utils.combine` more -- [patch] `parse`: add explicit `throwOnLimitExceeded` default -- [actions] use shared action; re-add finishers -- [meta] Fix changelog formatting bug -- [Deps] update `side-channel` -- [Dev Deps] update `es-value-fixtures`, `has-bigints`, `has-proto`, `has-symbols` -- [Tests] increase coverage - -## **6.13.3** -[Fix] fix regressions from robustness refactor -[actions] update reusable workflows - -## **6.13.2** -- [Robustness] avoid `.push`, use `void` -- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543) -- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418) -- [readme] replace runkit CI badge with shields.io check-runs badge -- [actions] fix rebase workflow permissions - -## **6.13.1** -- [Fix] `stringify`: avoid a crash when a `filter` key is `null` -- [Fix] `utils.merge`: functions should not be stringified into keys -- [Fix] `parse`: avoid a crash with interpretNumericEntities: true, comma: true, and iso charset -- [Fix] `stringify`: ensure a non-string `filter` does not crash -- [Refactor] use `__proto__` syntax instead of `Object.create` for null objects -- [Refactor] misc cleanup -- [Tests] `utils.merge`: add some coverage -- [Tests] fix a test case -- [actions] split out node 10-20, and 20+ -- [Dev Deps] update `es-value-fixtures`, `mock-property`, `object-inspect`, `tape` - -## **6.13.0** -- [New] `parse`: add `strictDepth` option (#511) -- [Tests] use `npm audit` instead of `aud` - -## **6.12.5** -- [Fix] fix regressions from robustness refactor -- [actions] update reusable workflows - -## **6.12.4** -- [Robustness] avoid `.push`, use `void` -- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543) -- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418) -- [readme] replace runkit CI badge with shields.io check-runs badge -- [actions] fix rebase workflow permissions - -## **6.12.3** -- [Fix] `parse`: properly account for `strictNullHandling` when `allowEmptyArrays` -- [meta] fix changelog indentation - -## **6.12.2** -- [Fix] `parse`: parse encoded square brackets (#506) -- [readme] add CII best practices badge - -## **6.12.1** -- [Fix] `parse`: Disable `decodeDotInKeys` by default to restore previous behavior (#501) -- [Performance] `utils`: Optimize performance under large data volumes, reduce memory usage, and speed up processing (#502) -- [Refactor] `utils`: use `+=` -- [Tests] increase coverage - -## **6.12.0** - -- [New] `parse`/`stringify`: add `decodeDotInKeys`/`encodeDotKeys` options (#488) -- [New] `parse`: add `duplicates` option -- [New] `parse`/`stringify`: add `allowEmptyArrays` option to allow [] in object values (#487) -- [Refactor] `parse`/`stringify`: move allowDots config logic to its own variable -- [Refactor] `stringify`: move option-handling code into `normalizeStringifyOptions` -- [readme] update readme, add logos (#484) -- [readme] `stringify`: clarify default `arrayFormat` behavior -- [readme] fix line wrapping -- [readme] remove dead badges -- [Deps] update `side-channel` -- [meta] make the dist build 50% smaller -- [meta] add `sideEffects` flag -- [meta] run build in prepack, not prepublish -- [Tests] `parse`: remove useless tests; add coverage -- [Tests] `stringify`: increase coverage -- [Tests] use `mock-property` -- [Tests] `stringify`: improve coverage -- [Dev Deps] update `@ljharb/eslint-config `, `aud`, `has-override-mistake`, `has-property-descriptors`, `mock-property`, `npmignore`, `object-inspect`, `tape` -- [Dev Deps] pin `glob`, since v10.3.8+ requires a broken `jackspeak` -- [Dev Deps] pin `jackspeak` since 2.1.2+ depends on npm aliases, which kill the install process in npm < 6 - -## **6.11.4** -- [Fix] fix regressions from robustness refactor -- [actions] update reusable workflows - -## **6.11.3** -- [Robustness] avoid `.push`, use `void` -- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543) -- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418) -- [readme] replace runkit CI badge with shields.io check-runs badge -- [actions] fix rebase workflow permissions - -## **6.11.2** -- [Fix] `parse`: Fix parsing when the global Object prototype is frozen (#473) -- [Tests] add passing test cases with empty keys (#473) - -## **6.11.1** -- [Fix] `stringify`: encode comma values more consistently (#463) -- [readme] add usage of `filter` option for injecting custom serialization, i.e. of custom types (#447) -- [meta] remove extraneous code backticks (#457) -- [meta] fix changelog markdown -- [actions] update checkout action -- [actions] restrict action permissions -- [Dev Deps] update `@ljharb/eslint-config`, `aud`, `object-inspect`, `tape` - -## **6.11.0** -- [New] [Fix] `stringify`: revert 0e903c0; add `commaRoundTrip` option (#442) -- [readme] fix version badge - -## **6.10.7** -- [Fix] fix regressions from robustness refactor -- [actions] update reusable workflows - -## **6.10.6** -- [Robustness] avoid `.push`, use `void` -- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543) -- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418) -- [readme] replace runkit CI badge with shields.io check-runs badge -- [actions] fix rebase workflow permissions - -## **6.10.5** -- [Fix] `stringify`: with `arrayFormat: comma`, properly include an explicit `[]` on a single-item array (#434) - -## **6.10.4** -- [Fix] `stringify`: with `arrayFormat: comma`, include an explicit `[]` on a single-item array (#441) -- [meta] use `npmignore` to autogenerate an npmignore file -- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `has-symbol`, `object-inspect`, `tape` - -## **6.10.3** -- [Fix] `parse`: ignore `__proto__` keys (#428) -- [Robustness] `stringify`: avoid relying on a global `undefined` (#427) -- [actions] reuse common workflows -- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `object-inspect`, `tape` - -## **6.10.2** -- [Fix] `stringify`: actually fix cyclic references (#426) -- [Fix] `stringify`: avoid encoding arrayformat comma when `encodeValuesOnly = true` (#424) -- [readme] remove travis badge; add github actions/codecov badges; update URLs -- [Docs] add note and links for coercing primitive values (#408) -- [actions] update codecov uploader -- [actions] update workflows -- [Tests] clean up stringify tests slightly -- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `object-inspect`, `safe-publish-latest`, `tape` - -## **6.10.1** -- [Fix] `stringify`: avoid exception on repeated object values (#402) - -## **6.10.0** -- [New] `stringify`: throw on cycles, instead of an infinite loop (#395, #394, #393) -- [New] `parse`: add `allowSparse` option for collapsing arrays with missing indices (#312) -- [meta] fix README.md (#399) -- [meta] only run `npm run dist` in publish, not install -- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `has-symbols`, `tape` -- [Tests] fix tests on node v0.6 -- [Tests] use `ljharb/actions/node/install` instead of `ljharb/actions/node/run` -- [Tests] Revert "[meta] ignore eclint transitive audit warning" - -## **6.9.9** -- [Fix] fix regressions from robustness refactor -- [meta] add `npmignore` to autogenerate an npmignore file -- [actions] update reusable workflows - -## **6.9.8** -- [Robustness] avoid `.push`, use `void` -- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543) -- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418) -- [readme] replace runkit CI badge with shields.io check-runs badge -- [actions] fix rebase workflow permissions - -## **6.9.7** -- [Fix] `parse`: ignore `__proto__` keys (#428) -- [Fix] `stringify`: avoid encoding arrayformat comma when `encodeValuesOnly = true` (#424) -- [Robustness] `stringify`: avoid relying on a global `undefined` (#427) -- [readme] remove travis badge; add github actions/codecov badges; update URLs -- [Docs] add note and links for coercing primitive values (#408) -- [Tests] clean up stringify tests slightly -- [meta] fix README.md (#399) -- Revert "[meta] ignore eclint transitive audit warning" -- [actions] backport actions from main -- [Dev Deps] backport updates from main - -## **6.9.6** -- [Fix] restore `dist` dir; mistakenly removed in d4f6c32 - -## **6.9.5** -- [Fix] `stringify`: do not encode parens for RFC1738 -- [Fix] `stringify`: fix arrayFormat comma with empty array/objects (#350) -- [Refactor] `format`: remove `util.assign` call -- [meta] add "Allow Edits" workflow; update rebase workflow -- [actions] switch Automatic Rebase workflow to `pull_request_target` event -- [Tests] `stringify`: add tests for #378 -- [Tests] migrate tests to Github Actions -- [Tests] run `nyc` on all tests; use `tape` runner -- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `browserify`, `mkdirp`, `object-inspect`, `tape`; add `aud` - -## **6.9.4** -- [Fix] `stringify`: when `arrayFormat` is `comma`, respect `serializeDate` (#364) -- [Refactor] `stringify`: reduce branching (part of #350) -- [Refactor] move `maybeMap` to `utils` -- [Dev Deps] update `browserify`, `tape` - -## **6.9.3** -- [Fix] proper comma parsing of URL-encoded commas (#361) -- [Fix] parses comma delimited array while having percent-encoded comma treated as normal text (#336) - -## **6.9.2** -- [Fix] `parse`: Fix parsing array from object with `comma` true (#359) -- [Fix] `parse`: throw a TypeError instead of an Error for bad charset (#349) -- [meta] ignore eclint transitive audit warning -- [meta] fix indentation in package.json -- [meta] add tidelift marketing copy -- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `object-inspect`, `has-symbols`, `tape`, `mkdirp`, `iconv-lite` -- [actions] add automatic rebasing / merge commit blocking - -## **6.9.1** -- [Fix] `parse`: with comma true, handle field that holds an array of arrays (#335) -- [Fix] `parse`: with comma true, do not split non-string values (#334) -- [meta] add `funding` field -- [Dev Deps] update `eslint`, `@ljharb/eslint-config` -- [Tests] use shared travis-ci config - -## **6.9.0** -- [New] `parse`/`stringify`: Pass extra key/value argument to `decoder` (#333) -- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `evalmd` -- [Tests] `parse`: add passing `arrayFormat` tests -- [Tests] add `posttest` using `npx aud` to run `npm audit` without a lockfile -- [Tests] up to `node` `v12.10`, `v11.15`, `v10.16`, `v8.16` -- [Tests] `Buffer.from` in node v5.0-v5.9 and v4.0-v4.4 requires a TypedArray - -## **6.8.5** -- [Fix] fix regressions from robustness refactor -- [meta] add `npmignore` to autogenerate an npmignore file -- [actions] update reusable workflows - -## **6.8.4** -- [Robustness] avoid `.push`, use `void` -- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543) -- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418) -- [readme] replace runkit CI badge with shields.io check-runs badge -- [actions] fix rebase workflow permissions - -## **6.8.3** -- [Fix] `parse`: ignore `__proto__` keys (#428) -- [Robustness] `stringify`: avoid relying on a global `undefined` (#427) -- [Fix] `stringify`: avoid encoding arrayformat comma when `encodeValuesOnly = true` (#424) -- [readme] remove travis badge; add github actions/codecov badges; update URLs -- [Tests] clean up stringify tests slightly -- [Docs] add note and links for coercing primitive values (#408) -- [meta] fix README.md (#399) -- [actions] backport actions from main -- [Dev Deps] backport updates from main -- [Refactor] `stringify`: reduce branching -- [meta] do not publish workflow files - -## **6.8.2** -- [Fix] proper comma parsing of URL-encoded commas (#361) -- [Fix] parses comma delimited array while having percent-encoded comma treated as normal text (#336) - -## **6.8.1** -- [Fix] `parse`: Fix parsing array from object with `comma` true (#359) -- [Fix] `parse`: throw a TypeError instead of an Error for bad charset (#349) -- [Fix] `parse`: with comma true, handle field that holds an array of arrays (#335) -- [fix] `parse`: with comma true, do not split non-string values (#334) -- [meta] add tidelift marketing copy -- [meta] add `funding` field -- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `tape`, `safe-publish-latest`, `evalmd`, `has-symbols`, `iconv-lite`, `mkdirp`, `object-inspect` -- [Tests] `parse`: add passing `arrayFormat` tests -- [Tests] use shared travis-ci configs -- [Tests] `Buffer.from` in node v5.0-v5.9 and v4.0-v4.4 requires a TypedArray -- [actions] add automatic rebasing / merge commit blocking - -## **6.8.0** -- [New] add `depth=false` to preserve the original key; [Fix] `depth=0` should preserve the original key (#326) -- [New] [Fix] stringify symbols and bigints -- [Fix] ensure node 0.12 can stringify Symbols -- [Fix] fix for an impossible situation: when the formatter is called with a non-string value -- [Refactor] `formats`: tiny bit of cleanup. -- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `browserify`, `safe-publish-latest`, `iconv-lite`, `tape` -- [Tests] add tests for `depth=0` and `depth=false` behavior, both current and intuitive/intended (#326) -- [Tests] use `eclint` instead of `editorconfig-tools` -- [docs] readme: add security note -- [meta] add github sponsorship -- [meta] add FUNDING.yml -- [meta] Clean up license text so it’s properly detected as BSD-3-Clause - -## **6.7.5** -- [Fix] fix regressions from robustness refactor -- [meta] add `npmignore` to autogenerate an npmignore file -- [actions] update reusable workflows - -## **6.7.4** -- [Robustness] avoid `.push`, use `void` -- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543) -- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418) -- [readme] replace runkit CI badge with shields.io check-runs badge -- [actions] fix rebase workflow permissions - -## **6.7.3** -- [Fix] `parse`: ignore `__proto__` keys (#428) -- [Fix] `stringify`: avoid encoding arrayformat comma when `encodeValuesOnly = true` (#424) -- [Robustness] `stringify`: avoid relying on a global `undefined` (#427) -- [readme] remove travis badge; add github actions/codecov badges; update URLs -- [Docs] add note and links for coercing primitive values (#408) -- [meta] fix README.md (#399) -- [meta] do not publish workflow files -- [actions] backport actions from main -- [Dev Deps] backport updates from main -- [Tests] use `nyc` for coverage -- [Tests] clean up stringify tests slightly - -## **6.7.2** -- [Fix] proper comma parsing of URL-encoded commas (#361) -- [Fix] parses comma delimited array while having percent-encoded comma treated as normal text (#336) - -## **6.7.1** -- [Fix] `parse`: Fix parsing array from object with `comma` true (#359) -- [Fix] `parse`: with comma true, handle field that holds an array of arrays (#335) -- [fix] `parse`: with comma true, do not split non-string values (#334) -- [Fix] `parse`: throw a TypeError instead of an Error for bad charset (#349) -- [Fix] fix for an impossible situation: when the formatter is called with a non-string value -- [Refactor] `formats`: tiny bit of cleanup. -- readme: add security note -- [meta] add tidelift marketing copy -- [meta] add `funding` field -- [meta] add FUNDING.yml -- [meta] Clean up license text so it’s properly detected as BSD-3-Clause -- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `tape`, `safe-publish-latest`, `evalmd`, `iconv-lite`, `mkdirp`, `object-inspect`, `browserify` -- [Tests] `parse`: add passing `arrayFormat` tests -- [Tests] use shared travis-ci configs -- [Tests] `Buffer.from` in node v5.0-v5.9 and v4.0-v4.4 requires a TypedArray -- [Tests] add tests for `depth=0` and `depth=false` behavior, both current and intuitive/intended -- [Tests] use `eclint` instead of `editorconfig-tools` -- [actions] add automatic rebasing / merge commit blocking - -## **6.7.0** -- [New] `stringify`/`parse`: add `comma` as an `arrayFormat` option (#276, #219) -- [Fix] correctly parse nested arrays (#212) -- [Fix] `utils.merge`: avoid a crash with a null target and a truthy non-array source, also with an array source -- [Robustness] `stringify`: cache `Object.prototype.hasOwnProperty` -- [Refactor] `utils`: `isBuffer`: small tweak; add tests -- [Refactor] use cached `Array.isArray` -- [Refactor] `parse`/`stringify`: make a function to normalize the options -- [Refactor] `utils`: reduce observable [[Get]]s -- [Refactor] `stringify`/`utils`: cache `Array.isArray` -- [Tests] always use `String(x)` over `x.toString()` -- [Tests] fix Buffer tests to work in node < 4.5 and node < 5.10 -- [Tests] temporarily allow coverage to fail - -## **6.6.3** -- [Fix] fix regressions from robustness refactor -- [meta] add `npmignore` to autogenerate an npmignore file -- [actions] update reusable workflows - -## **6.6.2** -- [Robustness] avoid `.push`, use `void` -- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543) -- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418) -- [readme] replace runkit CI badge with shields.io check-runs badge -- [actions] fix rebase workflow permissions - -## **6.6.1** -- [Fix] `parse`: ignore `__proto__` keys (#428) -- [Fix] fix for an impossible situation: when the formatter is called with a non-string value -- [Fix] `utils.merge`: avoid a crash with a null target and an array source -- [Fix] `utils.merge`: avoid a crash with a null target and a truthy non-array source -- [Fix] correctly parse nested arrays -- [Robustness] `stringify`: avoid relying on a global `undefined` (#427) -- [Robustness] `stringify`: cache `Object.prototype.hasOwnProperty` -- [Refactor] `formats`: tiny bit of cleanup. -- [Refactor] `utils`: `isBuffer`: small tweak; add tests -- [Refactor]: `stringify`/`utils`: cache `Array.isArray` -- [Refactor] `utils`: reduce observable [[Get]]s -- [Refactor] use cached `Array.isArray` -- [Refactor] `parse`/`stringify`: make a function to normalize the options -- [readme] remove travis badge; add github actions/codecov badges; update URLs -- [Docs] Clarify the need for "arrayLimit" option -- [meta] fix README.md (#399) -- [meta] do not publish workflow files -- [meta] Clean up license text so it’s properly detected as BSD-3-Clause -- [meta] add FUNDING.yml -- [meta] Fixes typo in CHANGELOG.md -- [actions] backport actions from main -- [Tests] fix Buffer tests to work in node < 4.5 and node < 5.10 -- [Tests] always use `String(x)` over `x.toString()` -- [Dev Deps] backport from main - -## **6.6.0** -- [New] Add support for iso-8859-1, utf8 "sentinel" and numeric entities (#268) -- [New] move two-value combine to a `utils` function (#189) -- [Fix] `stringify`: fix a crash with `strictNullHandling` and a custom `filter`/`serializeDate` (#279) -- [Fix] when `parseArrays` is false, properly handle keys ending in `[]` (#260) -- [Fix] `stringify`: do not crash in an obscure combo of `interpretNumericEntities`, a bad custom `decoder`, & `iso-8859-1` -- [Fix] `utils`: `merge`: fix crash when `source` is a truthy primitive & no options are provided -- [refactor] `stringify`: Avoid arr = arr.concat(...), push to the existing instance (#269) -- [Refactor] `parse`: only need to reassign the var once -- [Refactor] `parse`/`stringify`: clean up `charset` options checking; fix defaults -- [Refactor] add missing defaults -- [Refactor] `parse`: one less `concat` call -- [Refactor] `utils`: `compactQueue`: make it explicitly side-effecting -- [Dev Deps] update `browserify`, `eslint`, `@ljharb/eslint-config`, `iconv-lite`, `safe-publish-latest`, `tape` -- [Tests] up to `node` `v10.10`, `v9.11`, `v8.12`, `v6.14`, `v4.9`; pin included builds to LTS - -## **6.5.5** -- [Fix] fix regressions from robustness refactor -- [meta] add `npmignore` to autogenerate an npmignore file -- [actions] update reusable workflows - -## **6.5.4** -- [Robustness] avoid `.push`, use `void` -- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543) -- [readme] document that `addQueryPrefix` does not add `?` to empty output (#418) -- [readme] replace runkit CI badge with shields.io check-runs badge -- [actions] fix rebase workflow permissions - -## **6.5.3** -- [Fix] `parse`: ignore `__proto__` keys (#428) -- [Fix] `utils.merge`: avoid a crash with a null target and a truthy non-array source -- [Fix] correctly parse nested arrays -- [Fix] `stringify`: fix a crash with `strictNullHandling` and a custom `filter`/`serializeDate` (#279) -- [Fix] `utils`: `merge`: fix crash when `source` is a truthy primitive & no options are provided -- [Fix] when `parseArrays` is false, properly handle keys ending in `[]` -- [Fix] fix for an impossible situation: when the formatter is called with a non-string value -- [Fix] `utils.merge`: avoid a crash with a null target and an array source -- [Refactor] `utils`: reduce observable [[Get]]s -- [Refactor] use cached `Array.isArray` -- [Refactor] `stringify`: Avoid arr = arr.concat(...), push to the existing instance (#269) -- [Refactor] `parse`: only need to reassign the var once -- [Robustness] `stringify`: avoid relying on a global `undefined` (#427) -- [readme] remove travis badge; add github actions/codecov badges; update URLs -- [Docs] Clean up license text so it’s properly detected as BSD-3-Clause -- [Docs] Clarify the need for "arrayLimit" option -- [meta] fix README.md (#399) -- [meta] add FUNDING.yml -- [actions] backport actions from main -- [Tests] always use `String(x)` over `x.toString()` -- [Tests] remove nonexistent tape option -- [Dev Deps] backport from main - -## **6.5.2** -- [Fix] use `safer-buffer` instead of `Buffer` constructor -- [Refactor] utils: `module.exports` one thing, instead of mutating `exports` (#230) -- [Dev Deps] update `browserify`, `eslint`, `iconv-lite`, `safer-buffer`, `tape`, `browserify` - -## **6.5.1** -- [Fix] Fix parsing & compacting very deep objects (#224) -- [Refactor] name utils functions -- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `tape` -- [Tests] up to `node` `v8.4`; use `nvm install-latest-npm` so newer npm doesn’t break older node -- [Tests] Use precise dist for Node.js 0.6 runtime (#225) -- [Tests] make 0.6 required, now that it’s passing -- [Tests] on `node` `v8.2`; fix npm on node 0.6 - -## **6.5.0** -- [New] add `utils.assign` -- [New] pass default encoder/decoder to custom encoder/decoder functions (#206) -- [New] `parse`/`stringify`: add `ignoreQueryPrefix`/`addQueryPrefix` options, respectively (#213) -- [Fix] Handle stringifying empty objects with addQueryPrefix (#217) -- [Fix] do not mutate `options` argument (#207) -- [Refactor] `parse`: cache index to reuse in else statement (#182) -- [Docs] add various badges to readme (#208) -- [Dev Deps] update `eslint`, `browserify`, `iconv-lite`, `tape` -- [Tests] up to `node` `v8.1`, `v7.10`, `v6.11`; npm v4.6 breaks on node < v1; npm v5+ breaks on node < v4 -- [Tests] add `editorconfig-tools` - -## **6.4.3** -- [Fix] fix regressions from robustness refactor -- [meta] add `npmignore` to autogenerate an npmignore file -- [actions] update reusable workflows - -## **6.4.2** -- [Robustness] avoid `.push`, use `void` -- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543) -- [readme] replace runkit CI badge with shields.io check-runs badge -- [readme] replace travis CI badge with shields.io check-runs badge -- [actions] fix rebase workflow permissions - -## **6.4.1** -- [Fix] `parse`: ignore `__proto__` keys (#428) -- [Fix] fix for an impossible situation: when the formatter is called with a non-string value -- [Fix] use `safer-buffer` instead of `Buffer` constructor -- [Fix] `utils.merge`: avoid a crash with a null target and an array source -- [Fix] `utils.merge`: avoid a crash with a null target and a truthy non-array source -- [Fix] `stringify`: fix a crash with `strictNullHandling` and a custom `filter`/`serializeDate` (#279) -- [Fix] `utils`: `merge`: fix crash when `source` is a truthy primitive & no options are provided -- [Fix] when `parseArrays` is false, properly handle keys ending in `[]` -- [Robustness] `stringify`: avoid relying on a global `undefined` (#427) -- [Refactor] use cached `Array.isArray` -- [Refactor] `stringify`: Avoid arr = arr.concat(...), push to the existing instance (#269) -- [readme] remove travis badge; add github actions/codecov badges; update URLs -- [Docs] Clarify the need for "arrayLimit" option -- [meta] fix README.md (#399) -- [meta] Clean up license text so it’s properly detected as BSD-3-Clause -- [meta] add FUNDING.yml -- [actions] backport actions from main -- [Tests] remove nonexistent tape option -- [Dev Deps] backport from main - -## **6.4.0** -- [New] `qs.stringify`: add `encodeValuesOnly` option -- [Fix] follow `allowPrototypes` option during merge (#201, #201) -- [Fix] support keys starting with brackets (#202, #200) -- [Fix] chmod a-x -- [Dev Deps] update `eslint` -- [Tests] up to `node` `v7.7`, `v6.10`,` v4.8`; disable osx builds since they block linux builds -- [eslint] reduce warnings - -## **6.3.5** -- [Fix] fix regressions from robustness refactor -- [meta] add `npmignore` to autogenerate an npmignore file -- [actions] update reusable workflows - -## **6.3.4** -- [Robustness] avoid `.push`, use `void` -- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543) -- [readme] replace travis CI badge with shields.io check-runs badge -- [actions] fix rebase workflow permissions - -## **6.3.3** -- [Fix] `parse`: ignore `__proto__` keys (#428) -- [Fix] fix for an impossible situation: when the formatter is called with a non-string value -- [Fix] `utils.merge`: avoid a crash with a null target and an array source -- [Fix] `utils.merge`: avoid a crash with a null target and a truthy non-array source -- [Fix] `stringify`: fix a crash with `strictNullHandling` and a custom `filter`/`serializeDate` (#279) -- [Fix] `utils`: `merge`: fix crash when `source` is a truthy primitive & no options are provided -- [Fix] when `parseArrays` is false, properly handle keys ending in `[]` -- [Robustness] `stringify`: avoid relying on a global `undefined` (#427) -- [Refactor] use cached `Array.isArray` -- [Refactor] `stringify`: Avoid arr = arr.concat(...), push to the existing instance (#269) -- [Docs] Clarify the need for "arrayLimit" option -- [meta] fix README.md (#399) -- [meta] Clean up license text so it’s properly detected as BSD-3-Clause -- [meta] add FUNDING.yml -- [actions] backport actions from main -- [Tests] use `safer-buffer` instead of `Buffer` constructor -- [Tests] remove nonexistent tape option -- [Dev Deps] backport from main - -## **6.3.2** -- [Fix] follow `allowPrototypes` option during merge (#201, #200) -- [Dev Deps] update `eslint` -- [Fix] chmod a-x -- [Fix] support keys starting with brackets (#202, #200) -- [Tests] up to `node` `v7.7`, `v6.10`,` v4.8`; disable osx builds since they block linux builds - -## **6.3.1** -- [Fix] ensure that `allowPrototypes: false` does not ever shadow Object.prototype properties (thanks, @snyk!) -- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `browserify`, `iconv-lite`, `qs-iconv`, `tape` -- [Tests] on all node minors; improve test matrix -- [Docs] document stringify option `allowDots` (#195) -- [Docs] add empty object and array values example (#195) -- [Docs] Fix minor inconsistency/typo (#192) -- [Docs] document stringify option `sort` (#191) -- [Refactor] `stringify`: throw faster with an invalid encoder -- [Refactor] remove unnecessary escapes (#184) -- Remove contributing.md, since `qs` is no longer part of `hapi` (#183) - -## **6.3.0** -- [New] Add support for RFC 1738 (#174, #173) -- [New] `stringify`: Add `serializeDate` option to customize Date serialization (#159) -- [Fix] ensure `utils.merge` handles merging two arrays -- [Refactor] only constructors should be capitalized -- [Refactor] capitalized var names are for constructors only -- [Refactor] avoid using a sparse array -- [Robustness] `formats`: cache `String#replace` -- [Dev Deps] update `browserify`, `eslint`, `@ljharb/eslint-config`; add `safe-publish-latest` -- [Tests] up to `node` `v6.8`, `v4.6`; improve test matrix -- [Tests] flesh out arrayLimit/arrayFormat tests (#107) -- [Tests] skip Object.create tests when null objects are not available -- [Tests] Turn on eslint for test files (#175) - -## **6.2.6** -- [Fix] fix regression from robustness refactor -- [meta] add `npmignore` to autogenerate an npmignore file -- [actions] update reusable workflows - -## **6.2.5** -- [Robustness] avoid `.push`, use `void` -- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543) -- [readme] replace travis CI badge with shields.io check-runs badge -- [actions] fix rebase workflow permissions - -## **6.2.4** -- [Fix] `parse`: ignore `__proto__` keys (#428) -- [Fix] `utils.merge`: avoid a crash with a null target and an array source -- [Fix] `utils.merge`: avoid a crash with a null target and a truthy non-array source -- [Fix] `utils`: `merge`: fix crash when `source` is a truthy primitive & no options are provided -- [Fix] when `parseArrays` is false, properly handle keys ending in `[]` -- [Robustness] `stringify`: avoid relying on a global `undefined` (#427) -- [Refactor] use cached `Array.isArray` -- [Docs] Clarify the need for "arrayLimit" option -- [meta] fix README.md (#399) -- [meta] Clean up license text so it’s properly detected as BSD-3-Clause -- [meta] add FUNDING.yml -- [actions] backport actions from main -- [Tests] use `safer-buffer` instead of `Buffer` constructor -- [Tests] remove nonexistent tape option -- [Dev Deps] backport from main - -## **6.2.3** -- [Fix] follow `allowPrototypes` option during merge (#201, #200) -- [Fix] chmod a-x -- [Fix] support keys starting with brackets (#202, #200) -- [Tests] up to `node` `v7.7`, `v6.10`,` v4.8`; disable osx builds since they block linux builds - -## **6.2.2** -- [Fix] ensure that `allowPrototypes: false` does not ever shadow Object.prototype properties - -## **6.2.1** -- [Fix] ensure `key[]=x&key[]&key[]=y` results in 3, not 2, values -- [Refactor] Be explicit and use `Object.prototype.hasOwnProperty.call` -- [Tests] remove `parallelshell` since it does not reliably report failures -- [Tests] up to `node` `v6.3`, `v5.12` -- [Dev Deps] update `tape`, `eslint`, `@ljharb/eslint-config`, `qs-iconv` - -## [**6.2.0**](https://github.com/ljharb/qs/issues?milestone=36&state=closed) -- [New] pass Buffers to the encoder/decoder directly (#161) -- [New] add "encoder" and "decoder" options, for custom param encoding/decoding (#160) -- [Fix] fix compacting of nested sparse arrays (#150) - -## **6.1.4** -- [Fix] fix regression from robustness refactor -- [meta] add `npmignore` to autogenerate an npmignore file -- [actions] update reusable workflows - -## **6.1.3** -- [Robustness] avoid `.push`, use `void` -- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543) -- [readme] replace travis CI badge with shields.io check-runs badge - -## **6.1.2** -- [Fix] follow `allowPrototypes` option during merge (#201, #200) -- [Fix] chmod a-x -- [Fix] support keys starting with brackets (#202, #200) -- [Tests] up to `node` `v7.7`, `v6.10`,` v4.8`; disable osx builds since they block linux builds - -## **6.1.1** -- [Fix] ensure that `allowPrototypes: false` does not ever shadow Object.prototype properties - -## [**6.1.0**](https://github.com/ljharb/qs/issues?milestone=35&state=closed) -- [New] allowDots option for `stringify` (#151) -- [Fix] "sort" option should work at a depth of 3 or more (#151) -- [Fix] Restore `dist` directory; will be removed in v7 (#148) - -## **6.0.6** -- [Fix] fix regression from robustness refactor -- [meta] add `npmignore` to autogenerate an npmignore file -- [actions] update reusable workflows - -## **6.0.5** -- [Robustness] avoid `.push`, use `void` -- [readme] clarify `parseArrays` and `arrayLimit` documentation (#543) -- [readme] replace travis CI badge with shields.io check-runs badge - -## **6.0.4** -- [Fix] follow `allowPrototypes` option during merge (#201, #200) -- [Fix] chmod a-x -- [Fix] support keys starting with brackets (#202, #200) -- [Tests] up to `node` `v7.7`, `v6.10`,` v4.8`; disable osx builds since they block linux builds - -## **6.0.3** -- [Fix] ensure that `allowPrototypes: false` does not ever shadow Object.prototype properties -- [Fix] Restore `dist` directory; will be removed in v7 (#148) - -## [**6.0.2**](https://github.com/ljharb/qs/issues?milestone=33&state=closed) -- Revert ES6 requirement and restore support for node down to v0.8. - -## [**6.0.1**](https://github.com/ljharb/qs/issues?milestone=32&state=closed) -- [**#127**](https://github.com/ljharb/qs/pull/127) Fix engines definition in package.json - -## [**6.0.0**](https://github.com/ljharb/qs/issues?milestone=31&state=closed) -- [**#124**](https://github.com/ljharb/qs/issues/124) Use ES6 and drop support for node < v4 - -## **5.2.1** -- [Fix] ensure `key[]=x&key[]&key[]=y` results in 3, not 2, values - -## [**5.2.0**](https://github.com/ljharb/qs/issues?milestone=30&state=closed) -- [**#64**](https://github.com/ljharb/qs/issues/64) Add option to sort object keys in the query string - -## [**5.1.0**](https://github.com/ljharb/qs/issues?milestone=29&state=closed) -- [**#117**](https://github.com/ljharb/qs/issues/117) make URI encoding stringified results optional -- [**#106**](https://github.com/ljharb/qs/issues/106) Add flag `skipNulls` to optionally skip null values in stringify - -## [**5.0.0**](https://github.com/ljharb/qs/issues?milestone=28&state=closed) -- [**#114**](https://github.com/ljharb/qs/issues/114) default allowDots to false -- [**#100**](https://github.com/ljharb/qs/issues/100) include dist to npm - -## [**4.0.0**](https://github.com/ljharb/qs/issues?milestone=26&state=closed) -- [**#98**](https://github.com/ljharb/qs/issues/98) make returning plain objects and allowing prototype overwriting properties optional - -## [**3.1.0**](https://github.com/ljharb/qs/issues?milestone=24&state=closed) -- [**#89**](https://github.com/ljharb/qs/issues/89) Add option to disable "Transform dot notation to bracket notation" - -## [**3.0.0**](https://github.com/ljharb/qs/issues?milestone=23&state=closed) -- [**#80**](https://github.com/ljharb/qs/issues/80) qs.parse silently drops properties -- [**#77**](https://github.com/ljharb/qs/issues/77) Perf boost -- [**#60**](https://github.com/ljharb/qs/issues/60) Add explicit option to disable array parsing -- [**#74**](https://github.com/ljharb/qs/issues/74) Bad parse when turning array into object -- [**#81**](https://github.com/ljharb/qs/issues/81) Add a `filter` option -- [**#68**](https://github.com/ljharb/qs/issues/68) Fixed issue with recursion and passing strings into objects. -- [**#66**](https://github.com/ljharb/qs/issues/66) Add mixed array and object dot notation support Closes: #47 -- [**#76**](https://github.com/ljharb/qs/issues/76) RFC 3986 -- [**#85**](https://github.com/ljharb/qs/issues/85) No equal sign -- [**#84**](https://github.com/ljharb/qs/issues/84) update license attribute - -## [**2.4.1**](https://github.com/ljharb/qs/issues?milestone=20&state=closed) -- [**#73**](https://github.com/ljharb/qs/issues/73) Property 'hasOwnProperty' of object # is not a function - -## [**2.4.0**](https://github.com/ljharb/qs/issues?milestone=19&state=closed) -- [**#70**](https://github.com/ljharb/qs/issues/70) Add arrayFormat option - -## [**2.3.3**](https://github.com/ljharb/qs/issues?milestone=18&state=closed) -- [**#59**](https://github.com/ljharb/qs/issues/59) make sure array indexes are >= 0, closes #57 -- [**#58**](https://github.com/ljharb/qs/issues/58) make qs usable for browser loader - -## [**2.3.2**](https://github.com/ljharb/qs/issues?milestone=17&state=closed) -- [**#55**](https://github.com/ljharb/qs/issues/55) allow merging a string into an object - -## [**2.3.1**](https://github.com/ljharb/qs/issues?milestone=16&state=closed) -- [**#52**](https://github.com/ljharb/qs/issues/52) Return "undefined" and "false" instead of throwing "TypeError". - -## [**2.3.0**](https://github.com/ljharb/qs/issues?milestone=15&state=closed) -- [**#50**](https://github.com/ljharb/qs/issues/50) add option to omit array indices, closes #46 - -## [**2.2.5**](https://github.com/ljharb/qs/issues?milestone=14&state=closed) -- [**#39**](https://github.com/ljharb/qs/issues/39) Is there an alternative to Buffer.isBuffer? -- [**#49**](https://github.com/ljharb/qs/issues/49) refactor utils.merge, fixes #45 -- [**#41**](https://github.com/ljharb/qs/issues/41) avoid browserifying Buffer, for #39 - -## [**2.2.4**](https://github.com/ljharb/qs/issues?milestone=13&state=closed) -- [**#38**](https://github.com/ljharb/qs/issues/38) how to handle object keys beginning with a number - -## [**2.2.3**](https://github.com/ljharb/qs/issues?milestone=12&state=closed) -- [**#37**](https://github.com/ljharb/qs/issues/37) parser discards first empty value in array -- [**#36**](https://github.com/ljharb/qs/issues/36) Update to lab 4.x - -## [**2.2.2**](https://github.com/ljharb/qs/issues?milestone=11&state=closed) -- [**#33**](https://github.com/ljharb/qs/issues/33) Error when plain object in a value -- [**#34**](https://github.com/ljharb/qs/issues/34) use Object.prototype.hasOwnProperty.call instead of obj.hasOwnProperty -- [**#24**](https://github.com/ljharb/qs/issues/24) Changelog? Semver? - -## [**2.2.1**](https://github.com/ljharb/qs/issues?milestone=10&state=closed) -- [**#32**](https://github.com/ljharb/qs/issues/32) account for circular references properly, closes #31 -- [**#31**](https://github.com/ljharb/qs/issues/31) qs.parse stackoverflow on circular objects - -## [**2.2.0**](https://github.com/ljharb/qs/issues?milestone=9&state=closed) -- [**#26**](https://github.com/ljharb/qs/issues/26) Don't use Buffer global if it's not present -- [**#30**](https://github.com/ljharb/qs/issues/30) Bug when merging non-object values into arrays -- [**#29**](https://github.com/ljharb/qs/issues/29) Don't call Utils.clone at the top of Utils.merge -- [**#23**](https://github.com/ljharb/qs/issues/23) Ability to not limit parameters? - -## [**2.1.0**](https://github.com/ljharb/qs/issues?milestone=8&state=closed) -- [**#22**](https://github.com/ljharb/qs/issues/22) Enable using a RegExp as delimiter - -## [**2.0.0**](https://github.com/ljharb/qs/issues?milestone=7&state=closed) -- [**#18**](https://github.com/ljharb/qs/issues/18) Why is there arrayLimit? -- [**#20**](https://github.com/ljharb/qs/issues/20) Configurable parametersLimit -- [**#21**](https://github.com/ljharb/qs/issues/21) make all limits optional, for #18, for #20 - -## [**1.2.2**](https://github.com/ljharb/qs/issues?milestone=6&state=closed) -- [**#19**](https://github.com/ljharb/qs/issues/19) Don't overwrite null values - -## [**1.2.1**](https://github.com/ljharb/qs/issues?milestone=5&state=closed) -- [**#16**](https://github.com/ljharb/qs/issues/16) ignore non-string delimiters -- [**#15**](https://github.com/ljharb/qs/issues/15) Close code block - -## [**1.2.0**](https://github.com/ljharb/qs/issues?milestone=4&state=closed) -- [**#12**](https://github.com/ljharb/qs/issues/12) Add optional delim argument -- [**#13**](https://github.com/ljharb/qs/issues/13) fix #11: flattened keys in array are now correctly parsed - -## [**1.1.0**](https://github.com/ljharb/qs/issues?milestone=3&state=closed) -- [**#7**](https://github.com/ljharb/qs/issues/7) Empty values of a POST array disappear after being submitted -- [**#9**](https://github.com/ljharb/qs/issues/9) Should not omit equals signs (=) when value is null -- [**#6**](https://github.com/ljharb/qs/issues/6) Minor grammar fix in README - -## [**1.0.2**](https://github.com/ljharb/qs/issues?milestone=2&state=closed) -- [**#5**](https://github.com/ljharb/qs/issues/5) array holes incorrectly copied into object on large index diff --git a/node_modules/body-parser/node_modules/qs/LICENSE.md b/node_modules/body-parser/node_modules/qs/LICENSE.md deleted file mode 100644 index fecf6b6..0000000 --- a/node_modules/body-parser/node_modules/qs/LICENSE.md +++ /dev/null @@ -1,29 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2014, Nathan LaFreniere and other [contributors](https://github.com/ljharb/qs/graphs/contributors) -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/node_modules/body-parser/node_modules/qs/README.md b/node_modules/body-parser/node_modules/qs/README.md deleted file mode 100644 index 0980c9a..0000000 --- a/node_modules/body-parser/node_modules/qs/README.md +++ /dev/null @@ -1,758 +0,0 @@ -

- qs -

- -# qs [![Version Badge][npm-version-svg]][package-url] - -[![github actions][actions-image]][actions-url] -[![coverage][codecov-image]][codecov-url] -[![License][license-image]][license-url] -[![Downloads][downloads-image]][downloads-url] -[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/9058/badge)](https://bestpractices.coreinfrastructure.org/projects/9058) - -[![npm badge][npm-badge-png]][package-url] - -A querystring parsing and stringifying library with some added security. - -Lead Maintainer: [Jordan Harband](https://github.com/ljharb) - -The **qs** module was originally created and maintained by [TJ Holowaychuk](https://github.com/visionmedia/node-querystring). - -## Usage - -```javascript -var qs = require('qs'); -var assert = require('assert'); - -var obj = qs.parse('a=c'); -assert.deepEqual(obj, { a: 'c' }); - -var str = qs.stringify(obj); -assert.equal(str, 'a=c'); -``` - -### Parsing Objects - -[](#preventEval) -```javascript -qs.parse(string, [options]); -``` - -**qs** allows you to create nested objects within your query strings, by surrounding the name of sub-keys with square brackets `[]`. -For example, the string `'foo[bar]=baz'` converts to: - -```javascript -assert.deepEqual(qs.parse('foo[bar]=baz'), { - foo: { - bar: 'baz' - } -}); -``` - -When using the `plainObjects` option the parsed value is returned as a null object, created via `{ __proto__: null }` and as such you should be aware that prototype methods will not exist on it and a user may set those names to whatever value they like: - -```javascript -var nullObject = qs.parse('a[hasOwnProperty]=b', { plainObjects: true }); -assert.deepEqual(nullObject, { a: { hasOwnProperty: 'b' } }); -``` - -By default parameters that would overwrite properties on the object prototype are ignored, if you wish to keep the data from those fields either use `plainObjects` as mentioned above, or set `allowPrototypes` to `true` which will allow user input to overwrite those properties. -*WARNING* It is generally a bad idea to enable this option as it can cause problems when attempting to use the properties that have been overwritten. -Always be careful with this option. - -```javascript -var protoObject = qs.parse('a[hasOwnProperty]=b', { allowPrototypes: true }); -assert.deepEqual(protoObject, { a: { hasOwnProperty: 'b' } }); -``` - -URI encoded strings work too: - -```javascript -assert.deepEqual(qs.parse('a%5Bb%5D=c'), { - a: { b: 'c' } -}); -``` - -You can also nest your objects, like `'foo[bar][baz]=foobarbaz'`: - -```javascript -assert.deepEqual(qs.parse('foo[bar][baz]=foobarbaz'), { - foo: { - bar: { - baz: 'foobarbaz' - } - } -}); -``` - -By default, when nesting objects **qs** will only parse up to 5 children deep. -This means if you attempt to parse a string like `'a[b][c][d][e][f][g][h][i]=j'` your resulting object will be: - -```javascript -var expected = { - a: { - b: { - c: { - d: { - e: { - f: { - '[g][h][i]': 'j' - } - } - } - } - } - } -}; -var string = 'a[b][c][d][e][f][g][h][i]=j'; -assert.deepEqual(qs.parse(string), expected); -``` - -This depth can be overridden by passing a `depth` option to `qs.parse(string, [options])`: - -```javascript -var deep = qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1 }); -assert.deepEqual(deep, { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } }); -``` - -You can configure **qs** to throw an error when parsing nested input beyond this depth using the `strictDepth` option (defaulted to false): - -```javascript -try { - qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1, strictDepth: true }); -} catch (err) { - assert(err instanceof RangeError); - assert.strictEqual(err.message, 'Input depth exceeded depth option of 1 and strictDepth is true'); -} -``` - -The depth limit helps mitigate abuse when **qs** is used to parse user input, and it is recommended to keep it a reasonably small number. The strictDepth option adds a layer of protection by throwing an error when the limit is exceeded, allowing you to catch and handle such cases. - -For similar reasons, by default **qs** will only parse up to 1000 parameters. This can be overridden by passing a `parameterLimit` option: - -```javascript -var limited = qs.parse('a=b&c=d', { parameterLimit: 1 }); -assert.deepEqual(limited, { a: 'b' }); -``` - -If you want an error to be thrown whenever the a limit is exceeded (eg, `parameterLimit`, `arrayLimit`), set the `throwOnLimitExceeded` option to `true`. This option will generate a descriptive error if the query string exceeds a configured limit. -```javascript -try { - qs.parse('a=1&b=2&c=3&d=4', { parameterLimit: 3, throwOnLimitExceeded: true }); -} catch (err) { - assert(err instanceof Error); - assert.strictEqual(err.message, 'Parameter limit exceeded. Only 3 parameters allowed.'); -} -``` - -When `throwOnLimitExceeded` is set to `false` (default), **qs** will parse up to the specified `parameterLimit` and ignore the rest without throwing an error. - -To bypass the leading question mark, use `ignoreQueryPrefix`: - -```javascript -var prefixed = qs.parse('?a=b&c=d', { ignoreQueryPrefix: true }); -assert.deepEqual(prefixed, { a: 'b', c: 'd' }); -``` - -An optional delimiter can also be passed: - -```javascript -var delimited = qs.parse('a=b;c=d', { delimiter: ';' }); -assert.deepEqual(delimited, { a: 'b', c: 'd' }); -``` - -Delimiters can be a regular expression too: - -```javascript -var regexed = qs.parse('a=b;c=d,e=f', { delimiter: /[;,]/ }); -assert.deepEqual(regexed, { a: 'b', c: 'd', e: 'f' }); -``` - -Option `allowDots` can be used to enable dot notation: - -```javascript -var withDots = qs.parse('a.b=c', { allowDots: true }); -assert.deepEqual(withDots, { a: { b: 'c' } }); -``` - -Option `decodeDotInKeys` can be used to decode dots in keys -Note: it implies `allowDots`, so `parse` will error if you set `decodeDotInKeys` to `true`, and `allowDots` to `false`. - -```javascript -var withDots = qs.parse('name%252Eobj.first=John&name%252Eobj.last=Doe', { decodeDotInKeys: true }); -assert.deepEqual(withDots, { 'name.obj': { first: 'John', last: 'Doe' }}); -``` - -Option `allowEmptyArrays` can be used to allowing empty array values in object -```javascript -var withEmptyArrays = qs.parse('foo[]&bar=baz', { allowEmptyArrays: true }); -assert.deepEqual(withEmptyArrays, { foo: [], bar: 'baz' }); -``` - -Option `duplicates` can be used to change the behavior when duplicate keys are encountered -```javascript -assert.deepEqual(qs.parse('foo=bar&foo=baz'), { foo: ['bar', 'baz'] }); -assert.deepEqual(qs.parse('foo=bar&foo=baz', { duplicates: 'combine' }), { foo: ['bar', 'baz'] }); -assert.deepEqual(qs.parse('foo=bar&foo=baz', { duplicates: 'first' }), { foo: 'bar' }); -assert.deepEqual(qs.parse('foo=bar&foo=baz', { duplicates: 'last' }), { foo: 'baz' }); -``` - -Note that keys with bracket notation (`[]`) always combine into arrays, regardless of the `duplicates` setting: -```javascript -assert.deepEqual(qs.parse('a=1&a=2&b[]=1&b[]=2', { duplicates: 'last' }), { a: '2', b: ['1', '2'] }); -``` - -If you have to deal with legacy browsers or services, there's also support for decoding percent-encoded octets as iso-8859-1: - -```javascript -var oldCharset = qs.parse('a=%A7', { charset: 'iso-8859-1' }); -assert.deepEqual(oldCharset, { a: '§' }); -``` - -Some services add an initial `utf8=✓` value to forms so that old Internet Explorer versions are more likely to submit the form as utf-8. -Additionally, the server can check the value against wrong encodings of the checkmark character and detect that a query string or `application/x-www-form-urlencoded` body was *not* sent as utf-8, eg. if the form had an `accept-charset` parameter or the containing page had a different character set. - -**qs** supports this mechanism via the `charsetSentinel` option. -If specified, the `utf8` parameter will be omitted from the returned object. -It will be used to switch to `iso-8859-1`/`utf-8` mode depending on how the checkmark is encoded. - -**Important**: When you specify both the `charset` option and the `charsetSentinel` option, the `charset` will be overridden when the request contains a `utf8` parameter from which the actual charset can be deduced. -In that sense the `charset` will behave as the default charset rather than the authoritative charset. - -```javascript -var detectedAsUtf8 = qs.parse('utf8=%E2%9C%93&a=%C3%B8', { - charset: 'iso-8859-1', - charsetSentinel: true -}); -assert.deepEqual(detectedAsUtf8, { a: 'ø' }); - -// Browsers encode the checkmark as ✓ when submitting as iso-8859-1: -var detectedAsIso8859_1 = qs.parse('utf8=%26%2310003%3B&a=%F8', { - charset: 'utf-8', - charsetSentinel: true -}); -assert.deepEqual(detectedAsIso8859_1, { a: 'ø' }); -``` - -If you want to decode the `&#...;` syntax to the actual character, you can specify the `interpretNumericEntities` option as well: - -```javascript -var detectedAsIso8859_1 = qs.parse('a=%26%239786%3B', { - charset: 'iso-8859-1', - interpretNumericEntities: true -}); -assert.deepEqual(detectedAsIso8859_1, { a: '☺' }); -``` - -It also works when the charset has been detected in `charsetSentinel` mode. - -### Parsing Arrays - -**qs** can also parse arrays using a similar `[]` notation: - -```javascript -var withArray = qs.parse('a[]=b&a[]=c'); -assert.deepEqual(withArray, { a: ['b', 'c'] }); -``` - -You may specify an index as well: - -```javascript -var withIndexes = qs.parse('a[1]=c&a[0]=b'); -assert.deepEqual(withIndexes, { a: ['b', 'c'] }); -``` - -Note that the only difference between an index in an array and a key in an object is that the value between the brackets must be a number to create an array. -When creating arrays with specific indices, **qs** will compact a sparse array to only the existing values preserving their order: - -```javascript -var noSparse = qs.parse('a[1]=b&a[15]=c'); -assert.deepEqual(noSparse, { a: ['b', 'c'] }); -``` - -You may also use `allowSparse` option to parse sparse arrays: - -```javascript -var sparseArray = qs.parse('a[1]=2&a[3]=5', { allowSparse: true }); -assert.deepEqual(sparseArray, { a: [, '2', , '5'] }); -``` - -Note that an empty string is also a value, and will be preserved: - -```javascript -var withEmptyString = qs.parse('a[]=&a[]=b'); -assert.deepEqual(withEmptyString, { a: ['', 'b'] }); - -var withIndexedEmptyString = qs.parse('a[0]=b&a[1]=&a[2]=c'); -assert.deepEqual(withIndexedEmptyString, { a: ['b', '', 'c'] }); -``` - -**qs** will also limit arrays to a maximum of `20` elements. -Any array members with an index of `20` or greater will instead be converted to an object with the index as the key. -This is needed to handle cases when someone sent, for example, `a[999999999]` and it will take significant time to iterate over this huge array. - -```javascript -var withMaxIndex = qs.parse('a[100]=b'); -assert.deepEqual(withMaxIndex, { a: { '100': 'b' } }); -``` - -This limit can be overridden by passing an `arrayLimit` option: - -```javascript -var withArrayLimit = qs.parse('a[1]=b', { arrayLimit: 0 }); -assert.deepEqual(withArrayLimit, { a: { '1': 'b' } }); -``` - -If you want to throw an error whenever the array limit is exceeded, set the `throwOnLimitExceeded` option to `true`. This option will generate a descriptive error if the query string exceeds a configured limit. -```javascript -try { - qs.parse('a[1]=b', { arrayLimit: 0, throwOnLimitExceeded: true }); -} catch (err) { - assert(err instanceof Error); - assert.strictEqual(err.message, 'Array limit exceeded. Only 0 elements allowed in an array.'); -} -``` - -When `throwOnLimitExceeded` is set to `false` (default), **qs** will parse up to the specified `arrayLimit` and if the limit is exceeded, the array will instead be converted to an object with the index as the key - -To prevent array syntax (`a[]`, `a[0]`) from being parsed as arrays, set `parseArrays` to `false`. -Note that duplicate keys (e.g. `a=b&a=c`) may still produce arrays when `duplicates` is `'combine'` (the default). - -```javascript -var noParsingArrays = qs.parse('a[]=b', { parseArrays: false }); -assert.deepEqual(noParsingArrays, { a: { '0': 'b' } }); -``` - -If you mix notations, **qs** will merge the two items into an object: - -```javascript -var mixedNotation = qs.parse('a[0]=b&a[b]=c'); -assert.deepEqual(mixedNotation, { a: { '0': 'b', b: 'c' } }); -``` - -When a key appears as both a plain value and an object, **qs** will by default wrap the conflicting values in an array (`strictMerge` defaults to `true`): - -```javascript -assert.deepEqual(qs.parse('a[b]=c&a=d'), { a: [{ b: 'c' }, 'd'] }); -assert.deepEqual(qs.parse('a=d&a[b]=c'), { a: ['d', { b: 'c' }] }); -``` - -To restore the legacy behavior (where the primitive is used as a key with value `true`), set `strictMerge` to `false`: - -```javascript -assert.deepEqual(qs.parse('a[b]=c&a=d', { strictMerge: false }), { a: { b: 'c', d: true } }); -``` - -You can also create arrays of objects: - -```javascript -var arraysOfObjects = qs.parse('a[][b]=c'); -assert.deepEqual(arraysOfObjects, { a: [{ b: 'c' }] }); -``` - -Some people use comma to join array, **qs** can parse it: -```javascript -var arraysOfObjects = qs.parse('a=b,c', { comma: true }) -assert.deepEqual(arraysOfObjects, { a: ['b', 'c'] }) -``` -(_this cannot convert nested objects, such as `a={b:1},{c:d}`_) - -### Parsing primitive/scalar values (numbers, booleans, null, etc) - -By default, all values are parsed as strings. -This behavior will not change and is explained in [issue #91](https://github.com/ljharb/qs/issues/91). - -```javascript -var primitiveValues = qs.parse('a=15&b=true&c=null'); -assert.deepEqual(primitiveValues, { a: '15', b: 'true', c: 'null' }); -``` - -If you wish to auto-convert values which look like numbers, booleans, and other values into their primitive counterparts, you can use the [query-types Express JS middleware](https://github.com/xpepermint/query-types) which will auto-convert all request query parameters. - -### Stringifying - -[](#preventEval) -```javascript -qs.stringify(object, [options]); -``` - -When stringifying, **qs** by default URI encodes output. Objects are stringified as you would expect: - -```javascript -assert.equal(qs.stringify({ a: 'b' }), 'a=b'); -assert.equal(qs.stringify({ a: { b: 'c' } }), 'a%5Bb%5D=c'); -``` - -This encoding can be disabled by setting the `encode` option to `false`: - -```javascript -var unencoded = qs.stringify({ a: { b: 'c' } }, { encode: false }); -assert.equal(unencoded, 'a[b]=c'); -``` - -Encoding can be disabled for keys by setting the `encodeValuesOnly` option to `true`: -```javascript -var encodedValues = qs.stringify( - { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] }, - { encodeValuesOnly: true } -); -assert.equal(encodedValues,'a=b&c[0]=d&c[1]=e%3Df&f[0][0]=g&f[1][0]=h'); -``` - -This encoding can also be replaced by a custom encoding method set as `encoder` option: - -```javascript -var encoded = qs.stringify({ a: { b: 'c' } }, { encoder: function (str) { - // Passed in values `a`, `b`, `c` - return // Return encoded string -}}) -``` - -_(Note: the `encoder` option does not apply if `encode` is `false`)_ - -Analogue to the `encoder` there is a `decoder` option for `parse` to override decoding of properties and values: - -```javascript -var decoded = qs.parse('x=z', { decoder: function (str) { - // Passed in values `x`, `z` - return // Return decoded string -}}) -``` - -You can encode keys and values using different logic by using the type argument provided to the encoder: - -```javascript -var encoded = qs.stringify({ a: { b: 'c' } }, { encoder: function (str, defaultEncoder, charset, type) { - if (type === 'key') { - return // Encoded key - } else if (type === 'value') { - return // Encoded value - } -}}) -``` - -The type argument is also provided to the decoder: - -```javascript -var decoded = qs.parse('x=z', { decoder: function (str, defaultDecoder, charset, type) { - if (type === 'key') { - return // Decoded key - } else if (type === 'value') { - return // Decoded value - } -}}) -``` - -Examples beyond this point will be shown as though the output is not URI encoded for clarity. -Please note that the return values in these cases *will* be URI encoded during real usage. - -When arrays are stringified, they follow the `arrayFormat` option, which defaults to `indices`: - -```javascript -qs.stringify({ a: ['b', 'c', 'd'] }); -// 'a[0]=b&a[1]=c&a[2]=d' -``` - -You may override this by setting the `indices` option to `false`, or to be more explicit, the `arrayFormat` option to `repeat`: - -```javascript -qs.stringify({ a: ['b', 'c', 'd'] }, { indices: false }); -// 'a=b&a=c&a=d' -``` - -You may use the `arrayFormat` option to specify the format of the output array: - -```javascript -qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' }) -// 'a[0]=b&a[1]=c' -qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' }) -// 'a[]=b&a[]=c' -qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' }) -// 'a=b&a=c' -qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'comma' }) -// 'a=b,c' -``` - -Note: when using `arrayFormat` set to `'comma'`, you can also pass the `commaRoundTrip` option set to `true` or `false`, to append `[]` on single-item arrays, so that they can round trip through a parse. - -When objects are stringified, by default they use bracket notation: - -```javascript -qs.stringify({ a: { b: { c: 'd', e: 'f' } } }); -// 'a[b][c]=d&a[b][e]=f' -``` - -You may override this to use dot notation by setting the `allowDots` option to `true`: - -```javascript -qs.stringify({ a: { b: { c: 'd', e: 'f' } } }, { allowDots: true }); -// 'a.b.c=d&a.b.e=f' -``` - -You may encode the dot notation in the keys of object with option `encodeDotInKeys` by setting it to `true`: -Note: it implies `allowDots`, so `stringify` will error if you set `decodeDotInKeys` to `true`, and `allowDots` to `false`. -Caveat: when `encodeValuesOnly` is `true` as well as `encodeDotInKeys`, only dots in keys and nothing else will be encoded. -```javascript -qs.stringify({ "name.obj": { "first": "John", "last": "Doe" } }, { allowDots: true, encodeDotInKeys: true }) -// 'name%252Eobj.first=John&name%252Eobj.last=Doe' -``` - -You may allow empty array values by setting the `allowEmptyArrays` option to `true`: -```javascript -qs.stringify({ foo: [], bar: 'baz' }, { allowEmptyArrays: true }); -// 'foo[]&bar=baz' -``` - -Empty strings and null values will omit the value, but the equals sign (=) remains in place: - -```javascript -assert.equal(qs.stringify({ a: '' }), 'a='); -``` - -Key with no values (such as an empty object or array) will return nothing: - -```javascript -assert.equal(qs.stringify({ a: [] }), ''); -assert.equal(qs.stringify({ a: {} }), ''); -assert.equal(qs.stringify({ a: [{}] }), ''); -assert.equal(qs.stringify({ a: { b: []} }), ''); -assert.equal(qs.stringify({ a: { b: {}} }), ''); -``` - -Properties that are set to `undefined` will be omitted entirely: - -```javascript -assert.equal(qs.stringify({ a: null, b: undefined }), 'a='); -``` - -The query string may optionally be prepended with a question mark: - -```javascript -assert.equal(qs.stringify({ a: 'b', c: 'd' }, { addQueryPrefix: true }), '?a=b&c=d'); -``` - -Note that when the output is an empty string, the prefix will not be added: - -```javascript -assert.equal(qs.stringify({}, { addQueryPrefix: true }), ''); -``` - -The delimiter may be overridden with stringify as well: - -```javascript -assert.equal(qs.stringify({ a: 'b', c: 'd' }, { delimiter: ';' }), 'a=b;c=d'); -``` - -If you only want to override the serialization of `Date` objects, you can provide a `serializeDate` option: - -```javascript -var date = new Date(7); -assert.equal(qs.stringify({ a: date }), 'a=1970-01-01T00:00:00.007Z'.replace(/:/g, '%3A')); -assert.equal( - qs.stringify({ a: date }, { serializeDate: function (d) { return d.getTime(); } }), - 'a=7' -); -``` - -You may use the `sort` option to affect the order of parameter keys: - -```javascript -function alphabeticalSort(a, b) { - return a.localeCompare(b); -} -assert.equal(qs.stringify({ a: 'c', z: 'y', b : 'f' }, { sort: alphabeticalSort }), 'a=c&b=f&z=y'); -``` - -Finally, you can use the `filter` option to restrict which keys will be included in the stringified output. -If you pass a function, it will be called for each key to obtain the replacement value. -Otherwise, if you pass an array, it will be used to select properties and array indices for stringification: - -```javascript -function filterFunc(prefix, value) { - if (prefix == 'b') { - // Return an `undefined` value to omit a property. - return; - } - if (prefix == 'e[f]') { - return value.getTime(); - } - if (prefix == 'e[g][0]') { - return value * 2; - } - return value; -} -qs.stringify({ a: 'b', c: 'd', e: { f: new Date(123), g: [2] } }, { filter: filterFunc }); -// 'a=b&c=d&e[f]=123&e[g][0]=4' -qs.stringify({ a: 'b', c: 'd', e: 'f' }, { filter: ['a', 'e'] }); -// 'a=b&e=f' -qs.stringify({ a: ['b', 'c', 'd'], e: 'f' }, { filter: ['a', 0, 2] }); -// 'a[0]=b&a[2]=d' -``` - -You could also use `filter` to inject custom serialization for user defined types. -Consider you're working with some api that expects query strings of the format for ranges: - -``` -https://domain.com/endpoint?range=30...70 -``` - -For which you model as: - -```javascript -class Range { - constructor(from, to) { - this.from = from; - this.to = to; - } -} -``` - -You could _inject_ a custom serializer to handle values of this type: - -```javascript -qs.stringify( - { - range: new Range(30, 70), - }, - { - filter: (prefix, value) => { - if (value instanceof Range) { - return `${value.from}...${value.to}`; - } - // serialize the usual way - return value; - }, - } -); -// range=30...70 -``` - -### Handling of `null` values - -By default, `null` values are treated like empty strings: - -```javascript -var withNull = qs.stringify({ a: null, b: '' }); -assert.equal(withNull, 'a=&b='); -``` - -Parsing does not distinguish between parameters with and without equal signs. -Both are converted to empty strings. - -```javascript -var equalsInsensitive = qs.parse('a&b='); -assert.deepEqual(equalsInsensitive, { a: '', b: '' }); -``` - -To distinguish between `null` values and empty strings use the `strictNullHandling` flag. In the result string the `null` -values have no `=` sign: - -```javascript -var strictNull = qs.stringify({ a: null, b: '' }, { strictNullHandling: true }); -assert.equal(strictNull, 'a&b='); -``` - -To parse values without `=` back to `null` use the `strictNullHandling` flag: - -```javascript -var parsedStrictNull = qs.parse('a&b=', { strictNullHandling: true }); -assert.deepEqual(parsedStrictNull, { a: null, b: '' }); -``` - -To completely skip rendering keys with `null` values, use the `skipNulls` flag: - -```javascript -var nullsSkipped = qs.stringify({ a: 'b', c: null}, { skipNulls: true }); -assert.equal(nullsSkipped, 'a=b'); -``` - -If you're communicating with legacy systems, you can switch to `iso-8859-1` using the `charset` option: - -```javascript -var iso = qs.stringify({ æ: 'æ' }, { charset: 'iso-8859-1' }); -assert.equal(iso, '%E6=%E6'); -``` - -Characters that don't exist in `iso-8859-1` will be converted to numeric entities, similar to what browsers do: - -```javascript -var numeric = qs.stringify({ a: '☺' }, { charset: 'iso-8859-1' }); -assert.equal(numeric, 'a=%26%239786%3B'); -``` - -You can use the `charsetSentinel` option to announce the character by including an `utf8=✓` parameter with the proper encoding if the checkmark, similar to what Ruby on Rails and others do when submitting forms. - -```javascript -var sentinel = qs.stringify({ a: '☺' }, { charsetSentinel: true }); -assert.equal(sentinel, 'utf8=%E2%9C%93&a=%E2%98%BA'); - -var isoSentinel = qs.stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'iso-8859-1' }); -assert.equal(isoSentinel, 'utf8=%26%2310003%3B&a=%E6'); -``` - -### Dealing with special character sets - -By default the encoding and decoding of characters is done in `utf-8`, and `iso-8859-1` support is also built in via the `charset` parameter. - -If you wish to encode querystrings to a different character set (i.e. -[Shift JIS](https://en.wikipedia.org/wiki/Shift_JIS)) you can use the -[`qs-iconv`](https://github.com/martinheidegger/qs-iconv) library: - -```javascript -var encoder = require('qs-iconv/encoder')('shift_jis'); -var shiftJISEncoded = qs.stringify({ a: 'こんにちは!' }, { encoder: encoder }); -assert.equal(shiftJISEncoded, 'a=%82%B1%82%F1%82%C9%82%BF%82%CD%81I'); -``` - -This also works for decoding of query strings: - -```javascript -var decoder = require('qs-iconv/decoder')('shift_jis'); -var obj = qs.parse('a=%82%B1%82%F1%82%C9%82%BF%82%CD%81I', { decoder: decoder }); -assert.deepEqual(obj, { a: 'こんにちは!' }); -``` - -### RFC 3986 and RFC 1738 space encoding - -RFC3986 used as default option and encodes ' ' to *%20* which is backward compatible. -In the same time, output can be stringified as per RFC1738 with ' ' equal to '+'. - -``` -assert.equal(qs.stringify({ a: 'b c' }), 'a=b%20c'); -assert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC3986' }), 'a=b%20c'); -assert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC1738' }), 'a=b+c'); -``` - -## Security - -Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report. - -## qs for enterprise - -Available as part of the Tidelift Subscription - -The maintainers of qs and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. -Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. -[Learn more.](https://tidelift.com/subscription/pkg/npm-qs?utm_source=npm-qs&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) - -[package-url]: https://npmjs.org/package/qs -[npm-version-svg]: https://versionbadg.es/ljharb/qs.svg -[deps-svg]: https://david-dm.org/ljharb/qs.svg -[deps-url]: https://david-dm.org/ljharb/qs -[dev-deps-svg]: https://david-dm.org/ljharb/qs/dev-status.svg -[dev-deps-url]: https://david-dm.org/ljharb/qs#info=devDependencies -[npm-badge-png]: https://nodei.co/npm/qs.png?downloads=true&stars=true -[license-image]: https://img.shields.io/npm/l/qs.svg -[license-url]: LICENSE -[downloads-image]: https://img.shields.io/npm/dm/qs.svg -[downloads-url]: https://npm-stat.com/charts.html?package=qs -[codecov-image]: https://codecov.io/gh/ljharb/qs/branch/main/graphs/badge.svg -[codecov-url]: https://app.codecov.io/gh/ljharb/qs/ -[actions-image]: https://img.shields.io/github/check-runs/ljharb/qs/main -[actions-url]: https://github.com/ljharb/qs/actions - -## Acknowledgements - -qs logo by [NUMI](https://github.com/numi-hq/open-design): - -[NUMI Logo](https://numi.tech/?ref=qs) diff --git a/node_modules/body-parser/node_modules/qs/dist/qs.js b/node_modules/body-parser/node_modules/qs/dist/qs.js deleted file mode 100644 index 6b46eb5..0000000 --- a/node_modules/body-parser/node_modules/qs/dist/qs.js +++ /dev/null @@ -1,141 +0,0 @@ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Qs = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i-1)return e.split(",");if(t.throwOnLimitExceeded&&r>=t.arrayLimit)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");return e},isoSentinel="utf8=%26%2310003%3B",charsetSentinel="utf8=%E2%9C%93",parseValues=function parseQueryStringValues(e,t){var r={__proto__:null},i=t.ignoreQueryPrefix?e.replace(/^\?/,""):e;i=i.replace(/%5B/gi,"[").replace(/%5D/gi,"]");var a=t.parameterLimit===1/0?void 0:t.parameterLimit,o=i.split(t.delimiter,t.throwOnLimitExceeded&&void 0!==a?a+1:a);if(t.throwOnLimitExceeded&&void 0!==a&&o.length>a)throw new RangeError("Parameter limit exceeded. Only "+a+" parameter"+(1===a?"":"s")+" allowed.");var l,n=-1,s=t.charset;if(t.charsetSentinel)for(l=0;l-1&&(c=isArray(c)?[c]:c),t.comma&&isArray(c)&&c.length>t.arrayLimit){if(t.throwOnLimitExceeded)throw new RangeError("Array limit exceeded. Only "+t.arrayLimit+" element"+(1===t.arrayLimit?"":"s")+" allowed in an array.");c=utils.combine([],c,t.arrayLimit,t.plainObjects)}if(null!==d){var f=has.call(r,d);f&&("combine"===t.duplicates||p.indexOf("[]=")>-1)?r[d]=utils.combine(r[d],c,t.arrayLimit,t.plainObjects):f&&"last"!==t.duplicates||(r[d]=c)}}return r},parseObject=function(e,t,r,i){var a=0;if(e.length>0&&"[]"===e[e.length-1]){var o=e.slice(0,-1).join("");a=Array.isArray(t)&&t[o]?t[o].length:0}for(var l=i?t:parseArrayValue(t,r,a),n=e.length-1;n>=0;--n){var s,d=e[n];if("[]"===d&&r.parseArrays)s=utils.isOverflow(l)?l:r.allowEmptyArrays&&(""===l||r.strictNullHandling&&null===l)?[]:utils.combine([],l,r.arrayLimit,r.plainObjects);else{s=r.plainObjects?{__proto__:null}:{};var c="["===d.charAt(0)&&"]"===d.charAt(d.length-1)?d.slice(1,-1):d,p=r.decodeDotInKeys?c.replace(/%2E/g,"."):c,u=parseInt(p,10),y=!isNaN(u)&&d!==p&&String(u)===p&&u>=0&&r.parseArrays;if(r.parseArrays||""!==p)if(y&&u0?g.join(",")||null:void 0}];else if(isArray(f))S=f;else{var N=Object.keys(g);S=u?N.sort(u):N}var T=l?String(r).replace(/\./g,"%2E"):String(r),O=o&&isArray(g)&&1===g.length?T+"[]":T;if(a&&isArray(g)&&0===g.length)return O+"[]";for(var k=0;k0?c+y:""}; - -},{"1":1,"46":46,"5":5}],5:[function(require,module,exports){ -"use strict";var formats=require(1),getSideChannel=require(46),has=Object.prototype.hasOwnProperty,isArray=Array.isArray,overflowChannel=getSideChannel(),markOverflow=function markOverflow(e,r){return overflowChannel.set(e,r),e},isOverflow=function isOverflow(e){return overflowChannel.has(e)},getMaxIndex=function getMaxIndex(e){return overflowChannel.get(e)},setMaxIndex=function setMaxIndex(e,r){overflowChannel.set(e,r)},hexTable=function(){for(var e=[],r=0;r<256;++r)e[e.length]="%"+((r<16?"0":"")+r.toString(16)).toUpperCase();return e}(),compactQueue=function compactQueue(e){for(;e.length>1;){var r=e.pop(),t=r.obj[r.prop];if(isArray(t)){for(var n=[],o=0;ot.arrayLimit)return markOverflow(arrayToObject(e.concat(r),t),n);e[n]=r}else{if(!e||"object"!=typeof e)return[e,r];if(isOverflow(e)){var o=getMaxIndex(e)+1;e[o]=r,setMaxIndex(e,o)}else{if(t&&t.strictMerge)return[e,r];(t&&(t.plainObjects||t.allowPrototypes)||!has.call(Object.prototype,r))&&(e[r]=!0)}}return e}if(!e||"object"!=typeof e){if(isOverflow(r)){for(var a=Object.keys(r),i=t&&t.plainObjects?{__proto__:null,0:e}:{0:e},c=0;ct.arrayLimit?markOverflow(arrayToObject(l,t),l.length-1):l}var f=e;return isArray(e)&&!isArray(r)&&(f=arrayToObject(e,t)),isArray(e)&&isArray(r)?(r.forEach(function(r,n){if(has.call(e,n)){var o=e[n];o&&"object"==typeof o&&r&&"object"==typeof r?e[n]=merge(o,r,t):e[e.length]=r}else e[n]=r}),e):Object.keys(r).reduce(function(e,n){var o=r[n];if(has.call(e,n)?e[n]=merge(e[n],o,t):e[n]=o,isOverflow(r)&&!isOverflow(e)&&markOverflow(e,getMaxIndex(r)),isOverflow(e)){var a=parseInt(n,10);String(a)===n&&a>=0&&a>getMaxIndex(e)&&setMaxIndex(e,a)}return e},f)},assign=function assignSingleSource(e,r){return Object.keys(r).reduce(function(e,t){return e[t]=r[t],e},e)},decode=function(e,r,t){var n=e.replace(/\+/g," ");if("iso-8859-1"===t)return n.replace(/%[0-9a-f]{2}/gi,unescape);try{return decodeURIComponent(n)}catch(e){return n}},limit=1024,encode=function encode(e,r,t,n,o){if(0===e.length)return e;var a=e;if("symbol"==typeof e?a=Symbol.prototype.toString.call(e):"string"!=typeof e&&(a=String(e)),"iso-8859-1"===t)return escape(a).replace(/%u[0-9a-f]{4}/gi,function(e){return"%26%23"+parseInt(e.slice(2),16)+"%3B"});for(var i="",c=0;c=limit?a.slice(c,c+limit):a,f=[],s=0;s=48&&u<=57||u>=65&&u<=90||u>=97&&u<=122||o===formats.RFC1738&&(40===u||41===u)?f[f.length]=l.charAt(s):u<128?f[f.length]=hexTable[u]:u<2048?f[f.length]=hexTable[192|u>>6]+hexTable[128|63&u]:u<55296||u>=57344?f[f.length]=hexTable[224|u>>12]+hexTable[128|u>>6&63]+hexTable[128|63&u]:(s+=1,u=65536+((1023&u)<<10|1023&l.charCodeAt(s)),f[f.length]=hexTable[240|u>>18]+hexTable[128|u>>12&63]+hexTable[128|u>>6&63]+hexTable[128|63&u])}i+=f.join("")}return i},compact=function compact(e){for(var r=[{obj:{o:e},prop:"o"}],t=[],n=0;nt?markOverflow(arrayToObject(a,{plainObjects:n}),a.length-1):a},maybeMap=function maybeMap(e,r){if(isArray(e)){for(var t=[],n=0;n-1?callBindBasic([t]):t}; - -},{"10":10,"25":25}],25:[function(require,module,exports){ -"use strict";var undefined,$Object=require(22),$Error=require(16),$EvalError=require(15),$RangeError=require(17),$ReferenceError=require(18),$SyntaxError=require(19),$TypeError=require(20),$URIError=require(21),abs=require(34),floor=require(35),max=require(37),min=require(38),pow=require(39),round=require(40),sign=require(41),$Function=Function,getEvalledConstructor=function(r){try{return $Function('"use strict"; return ('+r+").constructor;")()}catch(r){}},$gOPD=require(30),$defineProperty=require(14),throwTypeError=function(){throw new $TypeError},ThrowTypeError=$gOPD?function(){try{return throwTypeError}catch(r){try{return $gOPD(arguments,"callee").get}catch(r){return throwTypeError}}}():throwTypeError,hasSymbols=require(31)(),getProto=require(28),$ObjectGPO=require(26),$ReflectGPO=require(27),$apply=require(8),$call=require(9),needsEval={},TypedArray="undefined"!=typeof Uint8Array&&getProto?getProto(Uint8Array):undefined,INTRINSICS={__proto__:null,"%AggregateError%":"undefined"==typeof AggregateError?undefined:AggregateError,"%Array%":Array,"%ArrayBuffer%":"undefined"==typeof ArrayBuffer?undefined:ArrayBuffer,"%ArrayIteratorPrototype%":hasSymbols&&getProto?getProto([][Symbol.iterator]()):undefined,"%AsyncFromSyncIteratorPrototype%":undefined,"%AsyncFunction%":needsEval,"%AsyncGenerator%":needsEval,"%AsyncGeneratorFunction%":needsEval,"%AsyncIteratorPrototype%":needsEval,"%Atomics%":"undefined"==typeof Atomics?undefined:Atomics,"%BigInt%":"undefined"==typeof BigInt?undefined:BigInt,"%BigInt64Array%":"undefined"==typeof BigInt64Array?undefined:BigInt64Array,"%BigUint64Array%":"undefined"==typeof BigUint64Array?undefined:BigUint64Array,"%Boolean%":Boolean,"%DataView%":"undefined"==typeof DataView?undefined:DataView,"%Date%":Date,"%decodeURI%":decodeURI,"%decodeURIComponent%":decodeURIComponent,"%encodeURI%":encodeURI,"%encodeURIComponent%":encodeURIComponent,"%Error%":$Error,"%eval%":eval,"%EvalError%":$EvalError,"%Float16Array%":"undefined"==typeof Float16Array?undefined:Float16Array,"%Float32Array%":"undefined"==typeof Float32Array?undefined:Float32Array,"%Float64Array%":"undefined"==typeof Float64Array?undefined:Float64Array,"%FinalizationRegistry%":"undefined"==typeof FinalizationRegistry?undefined:FinalizationRegistry,"%Function%":$Function,"%GeneratorFunction%":needsEval,"%Int8Array%":"undefined"==typeof Int8Array?undefined:Int8Array,"%Int16Array%":"undefined"==typeof Int16Array?undefined:Int16Array,"%Int32Array%":"undefined"==typeof Int32Array?undefined:Int32Array,"%isFinite%":isFinite,"%isNaN%":isNaN,"%IteratorPrototype%":hasSymbols&&getProto?getProto(getProto([][Symbol.iterator]())):undefined,"%JSON%":"object"==typeof JSON?JSON:undefined,"%Map%":"undefined"==typeof Map?undefined:Map,"%MapIteratorPrototype%":"undefined"!=typeof Map&&hasSymbols&&getProto?getProto((new Map)[Symbol.iterator]()):undefined,"%Math%":Math,"%Number%":Number,"%Object%":$Object,"%Object.getOwnPropertyDescriptor%":$gOPD,"%parseFloat%":parseFloat,"%parseInt%":parseInt,"%Promise%":"undefined"==typeof Promise?undefined:Promise,"%Proxy%":"undefined"==typeof Proxy?undefined:Proxy,"%RangeError%":$RangeError,"%ReferenceError%":$ReferenceError,"%Reflect%":"undefined"==typeof Reflect?undefined:Reflect,"%RegExp%":RegExp,"%Set%":"undefined"==typeof Set?undefined:Set,"%SetIteratorPrototype%":"undefined"!=typeof Set&&hasSymbols&&getProto?getProto((new Set)[Symbol.iterator]()):undefined,"%SharedArrayBuffer%":"undefined"==typeof SharedArrayBuffer?undefined:SharedArrayBuffer,"%String%":String,"%StringIteratorPrototype%":hasSymbols&&getProto?getProto(""[Symbol.iterator]()):undefined,"%Symbol%":hasSymbols?Symbol:undefined,"%SyntaxError%":$SyntaxError,"%ThrowTypeError%":ThrowTypeError,"%TypedArray%":TypedArray,"%TypeError%":$TypeError,"%Uint8Array%":"undefined"==typeof Uint8Array?undefined:Uint8Array,"%Uint8ClampedArray%":"undefined"==typeof Uint8ClampedArray?undefined:Uint8ClampedArray,"%Uint16Array%":"undefined"==typeof Uint16Array?undefined:Uint16Array,"%Uint32Array%":"undefined"==typeof Uint32Array?undefined:Uint32Array,"%URIError%":$URIError,"%WeakMap%":"undefined"==typeof WeakMap?undefined:WeakMap,"%WeakRef%":"undefined"==typeof WeakRef?undefined:WeakRef,"%WeakSet%":"undefined"==typeof WeakSet?undefined:WeakSet,"%Function.prototype.call%":$call,"%Function.prototype.apply%":$apply,"%Object.defineProperty%":$defineProperty,"%Object.getPrototypeOf%":$ObjectGPO,"%Math.abs%":abs,"%Math.floor%":floor,"%Math.max%":max,"%Math.min%":min,"%Math.pow%":pow,"%Math.round%":round,"%Math.sign%":sign,"%Reflect.getPrototypeOf%":$ReflectGPO};if(getProto)try{null.error}catch(r){var errorProto=getProto(getProto(r));INTRINSICS["%Error.prototype%"]=errorProto}var doEval=function doEval(r){var e;if("%AsyncFunction%"===r)e=getEvalledConstructor("async function () {}");else if("%GeneratorFunction%"===r)e=getEvalledConstructor("function* () {}");else if("%AsyncGeneratorFunction%"===r)e=getEvalledConstructor("async function* () {}");else if("%AsyncGenerator%"===r){var t=doEval("%AsyncGeneratorFunction%");t&&(e=t.prototype)}else if("%AsyncIteratorPrototype%"===r){var o=doEval("%AsyncGenerator%");o&&getProto&&(e=getProto(o.prototype))}return INTRINSICS[r]=e,e},LEGACY_ALIASES={__proto__:null,"%ArrayBufferPrototype%":["ArrayBuffer","prototype"],"%ArrayPrototype%":["Array","prototype"],"%ArrayProto_entries%":["Array","prototype","entries"],"%ArrayProto_forEach%":["Array","prototype","forEach"],"%ArrayProto_keys%":["Array","prototype","keys"],"%ArrayProto_values%":["Array","prototype","values"],"%AsyncFunctionPrototype%":["AsyncFunction","prototype"],"%AsyncGenerator%":["AsyncGeneratorFunction","prototype"],"%AsyncGeneratorPrototype%":["AsyncGeneratorFunction","prototype","prototype"],"%BooleanPrototype%":["Boolean","prototype"],"%DataViewPrototype%":["DataView","prototype"],"%DatePrototype%":["Date","prototype"],"%ErrorPrototype%":["Error","prototype"],"%EvalErrorPrototype%":["EvalError","prototype"],"%Float32ArrayPrototype%":["Float32Array","prototype"],"%Float64ArrayPrototype%":["Float64Array","prototype"],"%FunctionPrototype%":["Function","prototype"],"%Generator%":["GeneratorFunction","prototype"],"%GeneratorPrototype%":["GeneratorFunction","prototype","prototype"],"%Int8ArrayPrototype%":["Int8Array","prototype"],"%Int16ArrayPrototype%":["Int16Array","prototype"],"%Int32ArrayPrototype%":["Int32Array","prototype"],"%JSONParse%":["JSON","parse"],"%JSONStringify%":["JSON","stringify"],"%MapPrototype%":["Map","prototype"],"%NumberPrototype%":["Number","prototype"],"%ObjectPrototype%":["Object","prototype"],"%ObjProto_toString%":["Object","prototype","toString"],"%ObjProto_valueOf%":["Object","prototype","valueOf"],"%PromisePrototype%":["Promise","prototype"],"%PromiseProto_then%":["Promise","prototype","then"],"%Promise_all%":["Promise","all"],"%Promise_reject%":["Promise","reject"],"%Promise_resolve%":["Promise","resolve"],"%RangeErrorPrototype%":["RangeError","prototype"],"%ReferenceErrorPrototype%":["ReferenceError","prototype"],"%RegExpPrototype%":["RegExp","prototype"],"%SetPrototype%":["Set","prototype"],"%SharedArrayBufferPrototype%":["SharedArrayBuffer","prototype"],"%StringPrototype%":["String","prototype"],"%SymbolPrototype%":["Symbol","prototype"],"%SyntaxErrorPrototype%":["SyntaxError","prototype"],"%TypedArrayPrototype%":["TypedArray","prototype"],"%TypeErrorPrototype%":["TypeError","prototype"],"%Uint8ArrayPrototype%":["Uint8Array","prototype"],"%Uint8ClampedArrayPrototype%":["Uint8ClampedArray","prototype"],"%Uint16ArrayPrototype%":["Uint16Array","prototype"],"%Uint32ArrayPrototype%":["Uint32Array","prototype"],"%URIErrorPrototype%":["URIError","prototype"],"%WeakMapPrototype%":["WeakMap","prototype"],"%WeakSetPrototype%":["WeakSet","prototype"]},bind=require(24),hasOwn=require(33),$concat=bind.call($call,Array.prototype.concat),$spliceApply=bind.call($apply,Array.prototype.splice),$replace=bind.call($call,String.prototype.replace),$strSlice=bind.call($call,String.prototype.slice),$exec=bind.call($call,RegExp.prototype.exec),rePropName=/[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g,reEscapeChar=/\\(\\)?/g,stringToPath=function stringToPath(r){var e=$strSlice(r,0,1),t=$strSlice(r,-1);if("%"===e&&"%"!==t)throw new $SyntaxError("invalid intrinsic syntax, expected closing `%`");if("%"===t&&"%"!==e)throw new $SyntaxError("invalid intrinsic syntax, expected opening `%`");var o=[];return $replace(r,rePropName,function(r,e,t,n){o[o.length]=t?$replace(n,reEscapeChar,"$1"):e||r}),o},getBaseIntrinsic=function getBaseIntrinsic(r,e){var t,o=r;if(hasOwn(LEGACY_ALIASES,o)&&(o="%"+(t=LEGACY_ALIASES[o])[0]+"%"),hasOwn(INTRINSICS,o)){var n=INTRINSICS[o];if(n===needsEval&&(n=doEval(o)),void 0===n&&!e)throw new $TypeError("intrinsic "+r+" exists, but is not available. Please file an issue!");return{alias:t,name:o,value:n}}throw new $SyntaxError("intrinsic "+r+" does not exist!")};module.exports=function GetIntrinsic(r,e){if("string"!=typeof r||0===r.length)throw new $TypeError("intrinsic name must be a non-empty string");if(arguments.length>1&&"boolean"!=typeof e)throw new $TypeError('"allowMissing" argument must be a boolean');if(null===$exec(/^%?[^%]*%?$/,r))throw new $SyntaxError("`%` may not be present anywhere but at the beginning and end of the intrinsic name");var t=stringToPath(r),o=t.length>0?t[0]:"",n=getBaseIntrinsic("%"+o+"%",e),a=n.name,i=n.value,y=!1,p=n.alias;p&&(o=p[0],$spliceApply(t,$concat([0,1],p)));for(var d=1,s=!0;d=t.length){var c=$gOPD(i,f);i=(s=!!c)&&"get"in c&&!("originalValue"in c.get)?c.get:i[f]}else s=hasOwn(i,f),i=i[f];s&&!y&&(INTRINSICS[a]=i)}}return i}; - -},{"14":14,"15":15,"16":16,"17":17,"18":18,"19":19,"20":20,"21":21,"22":22,"24":24,"26":26,"27":27,"28":28,"30":30,"31":31,"33":33,"34":34,"35":35,"37":37,"38":38,"39":39,"40":40,"41":41,"8":8,"9":9}],13:[function(require,module,exports){ -"use strict";var hasProtoAccessor,callBind=require(10),gOPD=require(30);try{hasProtoAccessor=[].__proto__===Array.prototype}catch(t){if(!t||"object"!=typeof t||!("code"in t)||"ERR_PROTO_ACCESS"!==t.code)throw t}var desc=!!hasProtoAccessor&&gOPD&&gOPD(Object.prototype,"__proto__"),$Object=Object,$getPrototypeOf=$Object.getPrototypeOf;module.exports=desc&&"function"==typeof desc.get?callBind([desc.get]):"function"==typeof $getPrototypeOf&&function getDunder(t){return $getPrototypeOf(null==t?t:$Object(t))}; - -},{"10":10,"30":30}],30:[function(require,module,exports){ -"use strict";var $gOPD=require(29);if($gOPD)try{$gOPD([],"length")}catch(g){$gOPD=null}module.exports=$gOPD; - -},{"29":29}],14:[function(require,module,exports){ -"use strict";var $defineProperty=Object.defineProperty||!1;if($defineProperty)try{$defineProperty({},"a",{value:1})}catch(e){$defineProperty=!1}module.exports=$defineProperty; - -},{}],15:[function(require,module,exports){ -"use strict";module.exports=EvalError; - -},{}],16:[function(require,module,exports){ -"use strict";module.exports=Error; - -},{}],17:[function(require,module,exports){ -"use strict";module.exports=RangeError; - -},{}],18:[function(require,module,exports){ -"use strict";module.exports=ReferenceError; - -},{}],19:[function(require,module,exports){ -"use strict";module.exports=SyntaxError; - -},{}],21:[function(require,module,exports){ -"use strict";module.exports=URIError; - -},{}],22:[function(require,module,exports){ -"use strict";module.exports=Object; - -},{}],23:[function(require,module,exports){ -"use strict";var ERROR_MESSAGE="Function.prototype.bind called on incompatible ",toStr=Object.prototype.toString,max=Math.max,funcType="[object Function]",concatty=function concatty(t,n){for(var r=[],o=0;o-1e3&&t<1e3||$test.call(/e/,e))return e;var r=/[0-9](?=(?:[0-9]{3})+(?![0-9]))/g;if("number"==typeof t){var n=t<0?-$floor(-t):$floor(t);if(n!==t){var o=String(n),i=$slice.call(e,o.length+1);return $replace.call(o,r,"$&_")+"."+$replace.call($replace.call(i,/([0-9]{3})/g,"$&_"),/_$/,"")}}return $replace.call(e,r,"$&_")}var utilInspect=require(6),inspectCustom=utilInspect.custom,inspectSymbol=isSymbol(inspectCustom)?inspectCustom:null,quotes={__proto__:null,double:'"',single:"'"},quoteREs={__proto__:null,double:/(["\\])/g,single:/(['\\])/g};function wrapQuotes(t,e,r){var n=r.quoteStyle||e,o=quotes[n];return o+t+o}function quote(t){return $replace.call(String(t),/"/g,""")}function canTrustToString(t){return!toStringTag||!("object"==typeof t&&(toStringTag in t||void 0!==t[toStringTag]))}function isArray(t){return"[object Array]"===toStr(t)&&canTrustToString(t)}function isDate(t){return"[object Date]"===toStr(t)&&canTrustToString(t)}function isRegExp(t){return"[object RegExp]"===toStr(t)&&canTrustToString(t)}function isError(t){return"[object Error]"===toStr(t)&&canTrustToString(t)}function isString(t){return"[object String]"===toStr(t)&&canTrustToString(t)}function isNumber(t){return"[object Number]"===toStr(t)&&canTrustToString(t)}function isBoolean(t){return"[object Boolean]"===toStr(t)&&canTrustToString(t)}function isSymbol(t){if(hasShammedSymbols)return t&&"object"==typeof t&&t instanceof Symbol;if("symbol"==typeof t)return!0;if(!t||"object"!=typeof t||!symToString)return!1;try{return symToString.call(t),!0}catch(t){}return!1}function isBigInt(t){if(!t||"object"!=typeof t||!bigIntValueOf)return!1;try{return bigIntValueOf.call(t),!0}catch(t){}return!1}module.exports=function inspect_(t,e,r,n){var o=e||{};if(has(o,"quoteStyle")&&!has(quotes,o.quoteStyle))throw new TypeError('option "quoteStyle" must be "single" or "double"');if(has(o,"maxStringLength")&&("number"==typeof o.maxStringLength?o.maxStringLength<0&&o.maxStringLength!==1/0:null!==o.maxStringLength))throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');var i=!has(o,"customInspect")||o.customInspect;if("boolean"!=typeof i&&"symbol"!==i)throw new TypeError("option \"customInspect\", if provided, must be `true`, `false`, or `'symbol'`");if(has(o,"indent")&&null!==o.indent&&"\t"!==o.indent&&!(parseInt(o.indent,10)===o.indent&&o.indent>0))throw new TypeError('option "indent" must be "\\t", an integer > 0, or `null`');if(has(o,"numericSeparator")&&"boolean"!=typeof o.numericSeparator)throw new TypeError('option "numericSeparator", if provided, must be `true` or `false`');var a=o.numericSeparator;if(void 0===t)return"undefined";if(null===t)return"null";if("boolean"==typeof t)return t?"true":"false";if("string"==typeof t)return inspectString(t,o);if("number"==typeof t){if(0===t)return 1/0/t>0?"0":"-0";var c=String(t);return a?addNumericSeparator(t,c):c}if("bigint"==typeof t){var l=String(t)+"n";return a?addNumericSeparator(t,l):l}var u=void 0===o.depth?5:o.depth;if(void 0===r&&(r=0),r>=u&&u>0&&"object"==typeof t)return isArray(t)?"[Array]":"[Object]";var p=getIndent(o,r);if(void 0===n)n=[];else if(indexOf(n,t)>=0)return"[Circular]";function inspect(t,e,i){if(e&&(n=$arrSlice.call(n)).push(e),i){var a={depth:o.depth};return has(o,"quoteStyle")&&(a.quoteStyle=o.quoteStyle),inspect_(t,a,r+1,n)}return inspect_(t,o,r+1,n)}if("function"==typeof t&&!isRegExp(t)){var s=nameOf(t),f=arrObjKeys(t,inspect);return"[Function"+(s?": "+s:" (anonymous)")+"]"+(f.length>0?" { "+$join.call(f,", ")+" }":"")}if(isSymbol(t)){var y=hasShammedSymbols?$replace.call(String(t),/^(Symbol\(.*\))_[^)]*$/,"$1"):symToString.call(t);return"object"!=typeof t||hasShammedSymbols?y:markBoxed(y)}if(isElement(t)){for(var S="<"+$toLowerCase.call(String(t.nodeName)),g=t.attributes||[],m=0;m"}if(isArray(t)){if(0===t.length)return"[]";var b=arrObjKeys(t,inspect);return p&&!singleLineValues(b)?"["+indentedJoin(b,p)+"]":"[ "+$join.call(b,", ")+" ]"}if(isError(t)){var h=arrObjKeys(t,inspect);return"cause"in Error.prototype||!("cause"in t)||isEnumerable.call(t,"cause")?0===h.length?"["+String(t)+"]":"{ ["+String(t)+"] "+$join.call(h,", ")+" }":"{ ["+String(t)+"] "+$join.call($concat.call("[cause]: "+inspect(t.cause),h),", ")+" }"}if("object"==typeof t&&i){if(inspectSymbol&&"function"==typeof t[inspectSymbol]&&utilInspect)return utilInspect(t,{depth:u-r});if("symbol"!==i&&"function"==typeof t.inspect)return t.inspect()}if(isMap(t)){var d=[];return mapForEach&&mapForEach.call(t,function(e,r){d.push(inspect(r,t,!0)+" => "+inspect(e,t))}),collectionOf("Map",mapSize.call(t),d,p)}if(isSet(t)){var O=[];return setForEach&&setForEach.call(t,function(e){O.push(inspect(e,t))}),collectionOf("Set",setSize.call(t),O,p)}if(isWeakMap(t))return weakCollectionOf("WeakMap");if(isWeakSet(t))return weakCollectionOf("WeakSet");if(isWeakRef(t))return weakCollectionOf("WeakRef");if(isNumber(t))return markBoxed(inspect(Number(t)));if(isBigInt(t))return markBoxed(inspect(bigIntValueOf.call(t)));if(isBoolean(t))return markBoxed(booleanValueOf.call(t));if(isString(t))return markBoxed(inspect(String(t)));if("undefined"!=typeof window&&t===window)return"{ [object Window] }";if("undefined"!=typeof globalThis&&t===globalThis||"undefined"!=typeof global&&t===global)return"{ [object globalThis] }";if(!isDate(t)&&!isRegExp(t)){var j=arrObjKeys(t,inspect),w=gPO?gPO(t)===Object.prototype:t instanceof Object||t.constructor===Object,$=t instanceof Object?"":"null prototype",v=!w&&toStringTag&&Object(t)===t&&toStringTag in t?$slice.call(toStr(t),8,-1):$?"Object":"",k=(w||"function"!=typeof t.constructor?"":t.constructor.name?t.constructor.name+" ":"")+(v||$?"["+$join.call($concat.call([],v||[],$||[]),": ")+"] ":"");return 0===j.length?k+"{}":p?k+"{"+indentedJoin(j,p)+"}":k+"{ "+$join.call(j,", ")+" }"}return String(t)};var hasOwn=Object.prototype.hasOwnProperty||function(t){return t in this};function has(t,e){return hasOwn.call(t,e)}function toStr(t){return objectToString.call(t)}function nameOf(t){if(t.name)return t.name;var e=$match.call(functionToString.call(t),/^function\s*([\w$]+)/);return e?e[1]:null}function indexOf(t,e){if(t.indexOf)return t.indexOf(e);for(var r=0,n=t.length;re.maxStringLength){var r=t.length-e.maxStringLength,n="... "+r+" more character"+(r>1?"s":"");return inspectString($slice.call(t,0,e.maxStringLength),e)+n}var o=quoteREs[e.quoteStyle||"single"];return o.lastIndex=0,wrapQuotes($replace.call($replace.call(t,o,"\\$1"),/[\x00-\x1f]/g,lowbyte),"single",e)}function lowbyte(t){var e=t.charCodeAt(0),r={8:"b",9:"t",10:"n",12:"f",13:"r"}[e];return r?"\\"+r:"\\x"+(e<16?"0":"")+$toUpperCase.call(e.toString(16))}function markBoxed(t){return"Object("+t+")"}function weakCollectionOf(t){return t+" { ? }"}function collectionOf(t,e,r,n){return t+" ("+e+") {"+(n?indentedJoin(r,n):$join.call(r,", "))+"}"}function singleLineValues(t){for(var e=0;e=0)return!1;return!0}function getIndent(t,e){var r;if("\t"===t.indent)r="\t";else{if(!("number"==typeof t.indent&&t.indent>0))return null;r=$join.call(Array(t.indent+1)," ")}return{base:r,prev:$join.call(Array(e+1),r)}}function indentedJoin(t,e){if(0===t.length)return"";var r="\n"+e.prev+e.base;return r+$join.call(t,","+r)+"\n"+e.prev}function arrObjKeys(t,e){var r=isArray(t),n=[];if(r){n.length=t.length;for(var o=0;o -1) { - return val.split(','); - } - - if (options.throwOnLimitExceeded && currentArrayLength >= options.arrayLimit) { - throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.'); - } - - return val; -}; - -// This is what browsers will submit when the ✓ character occurs in an -// application/x-www-form-urlencoded body and the encoding of the page containing -// the form is iso-8859-1, or when the submitted form has an accept-charset -// attribute of iso-8859-1. Presumably also with other charsets that do not contain -// the ✓ character, such as us-ascii. -var isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('✓') - -// These are the percent-encoded utf-8 octets representing a checkmark, indicating that the request actually is utf-8 encoded. -var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓') - -var parseValues = function parseQueryStringValues(str, options) { - var obj = { __proto__: null }; - - var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str; - cleanStr = cleanStr.replace(/%5B/gi, '[').replace(/%5D/gi, ']'); - - var limit = options.parameterLimit === Infinity ? void undefined : options.parameterLimit; - var parts = cleanStr.split( - options.delimiter, - options.throwOnLimitExceeded && typeof limit !== 'undefined' ? limit + 1 : limit - ); - - if (options.throwOnLimitExceeded && typeof limit !== 'undefined' && parts.length > limit) { - throw new RangeError('Parameter limit exceeded. Only ' + limit + ' parameter' + (limit === 1 ? '' : 's') + ' allowed.'); - } - - var skipIndex = -1; // Keep track of where the utf8 sentinel was found - var i; - - var charset = options.charset; - if (options.charsetSentinel) { - for (i = 0; i < parts.length; ++i) { - if (parts[i].indexOf('utf8=') === 0) { - if (parts[i] === charsetSentinel) { - charset = 'utf-8'; - } else if (parts[i] === isoSentinel) { - charset = 'iso-8859-1'; - } - skipIndex = i; - i = parts.length; // The eslint settings do not allow break; - } - } - } - - for (i = 0; i < parts.length; ++i) { - if (i === skipIndex) { - continue; - } - var part = parts[i]; - - var bracketEqualsPos = part.indexOf(']='); - var pos = bracketEqualsPos === -1 ? part.indexOf('=') : bracketEqualsPos + 1; - - var key; - var val; - if (pos === -1) { - key = options.decoder(part, defaults.decoder, charset, 'key'); - val = options.strictNullHandling ? null : ''; - } else { - key = options.decoder(part.slice(0, pos), defaults.decoder, charset, 'key'); - - if (key !== null) { - val = utils.maybeMap( - parseArrayValue( - part.slice(pos + 1), - options, - isArray(obj[key]) ? obj[key].length : 0 - ), - function (encodedVal) { - return options.decoder(encodedVal, defaults.decoder, charset, 'value'); - } - ); - } - } - - if (val && options.interpretNumericEntities && charset === 'iso-8859-1') { - val = interpretNumericEntities(String(val)); - } - - if (part.indexOf('[]=') > -1) { - val = isArray(val) ? [val] : val; - } - - if (options.comma && isArray(val) && val.length > options.arrayLimit) { - if (options.throwOnLimitExceeded) { - throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.'); - } - val = utils.combine([], val, options.arrayLimit, options.plainObjects); - } - - if (key !== null) { - var existing = has.call(obj, key); - if (existing && (options.duplicates === 'combine' || part.indexOf('[]=') > -1)) { - obj[key] = utils.combine( - obj[key], - val, - options.arrayLimit, - options.plainObjects - ); - } else if (!existing || options.duplicates === 'last') { - obj[key] = val; - } - } - } - - return obj; -}; - -var parseObject = function (chain, val, options, valuesParsed) { - var currentArrayLength = 0; - if (chain.length > 0 && chain[chain.length - 1] === '[]') { - var parentKey = chain.slice(0, -1).join(''); - currentArrayLength = Array.isArray(val) && val[parentKey] ? val[parentKey].length : 0; - } - - var leaf = valuesParsed ? val : parseArrayValue(val, options, currentArrayLength); - - for (var i = chain.length - 1; i >= 0; --i) { - var obj; - var root = chain[i]; - - if (root === '[]' && options.parseArrays) { - if (utils.isOverflow(leaf)) { - // leaf is already an overflow object, preserve it - obj = leaf; - } else { - obj = options.allowEmptyArrays && (leaf === '' || (options.strictNullHandling && leaf === null)) - ? [] - : utils.combine( - [], - leaf, - options.arrayLimit, - options.plainObjects - ); - } - } else { - obj = options.plainObjects ? { __proto__: null } : {}; - var cleanRoot = root.charAt(0) === '[' && root.charAt(root.length - 1) === ']' ? root.slice(1, -1) : root; - var decodedRoot = options.decodeDotInKeys ? cleanRoot.replace(/%2E/g, '.') : cleanRoot; - var index = parseInt(decodedRoot, 10); - var isValidArrayIndex = !isNaN(index) - && root !== decodedRoot - && String(index) === decodedRoot - && index >= 0 - && options.parseArrays; - if (!options.parseArrays && decodedRoot === '') { - obj = { 0: leaf }; - } else if (isValidArrayIndex && index < options.arrayLimit) { - obj = []; - obj[index] = leaf; - } else if (isValidArrayIndex && options.throwOnLimitExceeded) { - throw new RangeError('Array limit exceeded. Only ' + options.arrayLimit + ' element' + (options.arrayLimit === 1 ? '' : 's') + ' allowed in an array.'); - } else if (isValidArrayIndex) { - obj[index] = leaf; - utils.markOverflow(obj, index); - } else if (decodedRoot !== '__proto__') { - obj[decodedRoot] = leaf; - } - } - - leaf = obj; - } - - return leaf; -}; - -var splitKeyIntoSegments = function splitKeyIntoSegments(givenKey, options) { - var key = options.allowDots ? givenKey.replace(/\.([^.[]+)/g, '[$1]') : givenKey; - - if (options.depth <= 0) { - if (!options.plainObjects && has.call(Object.prototype, key)) { - if (!options.allowPrototypes) { - return; - } - } - - return [key]; - } - - var brackets = /(\[[^[\]]*])/; - var child = /(\[[^[\]]*])/g; - - var segment = brackets.exec(key); - var parent = segment ? key.slice(0, segment.index) : key; - - var keys = []; - - if (parent) { - if (!options.plainObjects && has.call(Object.prototype, parent)) { - if (!options.allowPrototypes) { - return; - } - } - - keys[keys.length] = parent; - } - - var i = 0; - while ((segment = child.exec(key)) !== null && i < options.depth) { - i += 1; - - var segmentContent = segment[1].slice(1, -1); - if (!options.plainObjects && has.call(Object.prototype, segmentContent)) { - if (!options.allowPrototypes) { - return; - } - } - - keys[keys.length] = segment[1]; - } - - if (segment) { - if (options.strictDepth === true) { - throw new RangeError('Input depth exceeded depth option of ' + options.depth + ' and strictDepth is true'); - } - - keys[keys.length] = '[' + key.slice(segment.index) + ']'; - } - - return keys; -}; - -var parseKeys = function parseQueryStringKeys(givenKey, val, options, valuesParsed) { - if (!givenKey) { - return; - } - - var keys = splitKeyIntoSegments(givenKey, options); - - if (!keys) { - return; - } - - return parseObject(keys, val, options, valuesParsed); -}; - -var normalizeParseOptions = function normalizeParseOptions(opts) { - if (!opts) { - return defaults; - } - - if (typeof opts.allowEmptyArrays !== 'undefined' && typeof opts.allowEmptyArrays !== 'boolean') { - throw new TypeError('`allowEmptyArrays` option can only be `true` or `false`, when provided'); - } - - if (typeof opts.decodeDotInKeys !== 'undefined' && typeof opts.decodeDotInKeys !== 'boolean') { - throw new TypeError('`decodeDotInKeys` option can only be `true` or `false`, when provided'); - } - - if (opts.decoder !== null && typeof opts.decoder !== 'undefined' && typeof opts.decoder !== 'function') { - throw new TypeError('Decoder has to be a function.'); - } - - if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') { - throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined'); - } - - if (typeof opts.throwOnLimitExceeded !== 'undefined' && typeof opts.throwOnLimitExceeded !== 'boolean') { - throw new TypeError('`throwOnLimitExceeded` option must be a boolean'); - } - - var charset = typeof opts.charset === 'undefined' ? defaults.charset : opts.charset; - - var duplicates = typeof opts.duplicates === 'undefined' ? defaults.duplicates : opts.duplicates; - - if (duplicates !== 'combine' && duplicates !== 'first' && duplicates !== 'last') { - throw new TypeError('The duplicates option must be either combine, first, or last'); - } - - var allowDots = typeof opts.allowDots === 'undefined' ? opts.decodeDotInKeys === true ? true : defaults.allowDots : !!opts.allowDots; - - return { - allowDots: allowDots, - allowEmptyArrays: typeof opts.allowEmptyArrays === 'boolean' ? !!opts.allowEmptyArrays : defaults.allowEmptyArrays, - allowPrototypes: typeof opts.allowPrototypes === 'boolean' ? opts.allowPrototypes : defaults.allowPrototypes, - allowSparse: typeof opts.allowSparse === 'boolean' ? opts.allowSparse : defaults.allowSparse, - arrayLimit: typeof opts.arrayLimit === 'number' ? opts.arrayLimit : defaults.arrayLimit, - charset: charset, - charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel, - comma: typeof opts.comma === 'boolean' ? opts.comma : defaults.comma, - decodeDotInKeys: typeof opts.decodeDotInKeys === 'boolean' ? opts.decodeDotInKeys : defaults.decodeDotInKeys, - decoder: typeof opts.decoder === 'function' ? opts.decoder : defaults.decoder, - delimiter: typeof opts.delimiter === 'string' || utils.isRegExp(opts.delimiter) ? opts.delimiter : defaults.delimiter, - // eslint-disable-next-line no-implicit-coercion, no-extra-parens - depth: (typeof opts.depth === 'number' || opts.depth === false) ? +opts.depth : defaults.depth, - duplicates: duplicates, - ignoreQueryPrefix: opts.ignoreQueryPrefix === true, - interpretNumericEntities: typeof opts.interpretNumericEntities === 'boolean' ? opts.interpretNumericEntities : defaults.interpretNumericEntities, - parameterLimit: typeof opts.parameterLimit === 'number' ? opts.parameterLimit : defaults.parameterLimit, - parseArrays: opts.parseArrays !== false, - plainObjects: typeof opts.plainObjects === 'boolean' ? opts.plainObjects : defaults.plainObjects, - strictDepth: typeof opts.strictDepth === 'boolean' ? !!opts.strictDepth : defaults.strictDepth, - strictMerge: typeof opts.strictMerge === 'boolean' ? !!opts.strictMerge : defaults.strictMerge, - strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling, - throwOnLimitExceeded: typeof opts.throwOnLimitExceeded === 'boolean' ? opts.throwOnLimitExceeded : false - }; -}; - -module.exports = function (str, opts) { - var options = normalizeParseOptions(opts); - - if (str === '' || str === null || typeof str === 'undefined') { - return options.plainObjects ? { __proto__: null } : {}; - } - - var tempObj = typeof str === 'string' ? parseValues(str, options) : str; - var obj = options.plainObjects ? { __proto__: null } : {}; - - // Iterate over the keys and setup the new object - - var keys = Object.keys(tempObj); - for (var i = 0; i < keys.length; ++i) { - var key = keys[i]; - var newObj = parseKeys(key, tempObj[key], options, typeof str === 'string'); - obj = utils.merge(obj, newObj, options); - } - - if (options.allowSparse === true) { - return obj; - } - - return utils.compact(obj); -}; diff --git a/node_modules/body-parser/node_modules/qs/lib/stringify.js b/node_modules/body-parser/node_modules/qs/lib/stringify.js deleted file mode 100644 index 2666eaf..0000000 --- a/node_modules/body-parser/node_modules/qs/lib/stringify.js +++ /dev/null @@ -1,356 +0,0 @@ -'use strict'; - -var getSideChannel = require('side-channel'); -var utils = require('./utils'); -var formats = require('./formats'); -var has = Object.prototype.hasOwnProperty; - -var arrayPrefixGenerators = { - brackets: function brackets(prefix) { - return prefix + '[]'; - }, - comma: 'comma', - indices: function indices(prefix, key) { - return prefix + '[' + key + ']'; - }, - repeat: function repeat(prefix) { - return prefix; - } -}; - -var isArray = Array.isArray; -var push = Array.prototype.push; -var pushToArray = function (arr, valueOrArray) { - push.apply(arr, isArray(valueOrArray) ? valueOrArray : [valueOrArray]); -}; - -var toISO = Date.prototype.toISOString; - -var defaultFormat = formats['default']; -var defaults = { - addQueryPrefix: false, - allowDots: false, - allowEmptyArrays: false, - arrayFormat: 'indices', - charset: 'utf-8', - charsetSentinel: false, - commaRoundTrip: false, - delimiter: '&', - encode: true, - encodeDotInKeys: false, - encoder: utils.encode, - encodeValuesOnly: false, - filter: void undefined, - format: defaultFormat, - formatter: formats.formatters[defaultFormat], - // deprecated - indices: false, - serializeDate: function serializeDate(date) { - return toISO.call(date); - }, - skipNulls: false, - strictNullHandling: false -}; - -var isNonNullishPrimitive = function isNonNullishPrimitive(v) { - return typeof v === 'string' - || typeof v === 'number' - || typeof v === 'boolean' - || typeof v === 'symbol' - || typeof v === 'bigint'; -}; - -var sentinel = {}; - -var stringify = function stringify( - object, - prefix, - generateArrayPrefix, - commaRoundTrip, - allowEmptyArrays, - strictNullHandling, - skipNulls, - encodeDotInKeys, - encoder, - filter, - sort, - allowDots, - serializeDate, - format, - formatter, - encodeValuesOnly, - charset, - sideChannel -) { - var obj = object; - - var tmpSc = sideChannel; - var step = 0; - var findFlag = false; - while ((tmpSc = tmpSc.get(sentinel)) !== void undefined && !findFlag) { - // Where object last appeared in the ref tree - var pos = tmpSc.get(object); - step += 1; - if (typeof pos !== 'undefined') { - if (pos === step) { - throw new RangeError('Cyclic object value'); - } else { - findFlag = true; // Break while - } - } - if (typeof tmpSc.get(sentinel) === 'undefined') { - step = 0; - } - } - - if (typeof filter === 'function') { - obj = filter(prefix, obj); - } else if (obj instanceof Date) { - obj = serializeDate(obj); - } else if (generateArrayPrefix === 'comma' && isArray(obj)) { - obj = utils.maybeMap(obj, function (value) { - if (value instanceof Date) { - return serializeDate(value); - } - return value; - }); - } - - if (obj === null) { - if (strictNullHandling) { - return encoder && !encodeValuesOnly ? encoder(prefix, defaults.encoder, charset, 'key', format) : prefix; - } - - obj = ''; - } - - if (isNonNullishPrimitive(obj) || utils.isBuffer(obj)) { - if (encoder) { - var keyValue = encodeValuesOnly ? prefix : encoder(prefix, defaults.encoder, charset, 'key', format); - return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))]; - } - return [formatter(prefix) + '=' + formatter(String(obj))]; - } - - var values = []; - - if (typeof obj === 'undefined') { - return values; - } - - var objKeys; - if (generateArrayPrefix === 'comma' && isArray(obj)) { - // we need to join elements in - if (encodeValuesOnly && encoder) { - obj = utils.maybeMap(obj, encoder); - } - objKeys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }]; - } else if (isArray(filter)) { - objKeys = filter; - } else { - var keys = Object.keys(obj); - objKeys = sort ? keys.sort(sort) : keys; - } - - var encodedPrefix = encodeDotInKeys ? String(prefix).replace(/\./g, '%2E') : String(prefix); - - var adjustedPrefix = commaRoundTrip && isArray(obj) && obj.length === 1 ? encodedPrefix + '[]' : encodedPrefix; - - if (allowEmptyArrays && isArray(obj) && obj.length === 0) { - return adjustedPrefix + '[]'; - } - - for (var j = 0; j < objKeys.length; ++j) { - var key = objKeys[j]; - var value = typeof key === 'object' && key && typeof key.value !== 'undefined' - ? key.value - : obj[key]; - - if (skipNulls && value === null) { - continue; - } - - var encodedKey = allowDots && encodeDotInKeys ? String(key).replace(/\./g, '%2E') : String(key); - var keyPrefix = isArray(obj) - ? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(adjustedPrefix, encodedKey) : adjustedPrefix - : adjustedPrefix + (allowDots ? '.' + encodedKey : '[' + encodedKey + ']'); - - sideChannel.set(object, step); - var valueSideChannel = getSideChannel(); - valueSideChannel.set(sentinel, sideChannel); - pushToArray(values, stringify( - value, - keyPrefix, - generateArrayPrefix, - commaRoundTrip, - allowEmptyArrays, - strictNullHandling, - skipNulls, - encodeDotInKeys, - generateArrayPrefix === 'comma' && encodeValuesOnly && isArray(obj) ? null : encoder, - filter, - sort, - allowDots, - serializeDate, - format, - formatter, - encodeValuesOnly, - charset, - valueSideChannel - )); - } - - return values; -}; - -var normalizeStringifyOptions = function normalizeStringifyOptions(opts) { - if (!opts) { - return defaults; - } - - if (typeof opts.allowEmptyArrays !== 'undefined' && typeof opts.allowEmptyArrays !== 'boolean') { - throw new TypeError('`allowEmptyArrays` option can only be `true` or `false`, when provided'); - } - - if (typeof opts.encodeDotInKeys !== 'undefined' && typeof opts.encodeDotInKeys !== 'boolean') { - throw new TypeError('`encodeDotInKeys` option can only be `true` or `false`, when provided'); - } - - if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') { - throw new TypeError('Encoder has to be a function.'); - } - - var charset = opts.charset || defaults.charset; - if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') { - throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined'); - } - - var format = formats['default']; - if (typeof opts.format !== 'undefined') { - if (!has.call(formats.formatters, opts.format)) { - throw new TypeError('Unknown format option provided.'); - } - format = opts.format; - } - var formatter = formats.formatters[format]; - - var filter = defaults.filter; - if (typeof opts.filter === 'function' || isArray(opts.filter)) { - filter = opts.filter; - } - - var arrayFormat; - if (opts.arrayFormat in arrayPrefixGenerators) { - arrayFormat = opts.arrayFormat; - } else if ('indices' in opts) { - arrayFormat = opts.indices ? 'indices' : 'repeat'; - } else { - arrayFormat = defaults.arrayFormat; - } - - if ('commaRoundTrip' in opts && typeof opts.commaRoundTrip !== 'boolean') { - throw new TypeError('`commaRoundTrip` must be a boolean, or absent'); - } - - var allowDots = typeof opts.allowDots === 'undefined' ? opts.encodeDotInKeys === true ? true : defaults.allowDots : !!opts.allowDots; - - return { - addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix, - allowDots: allowDots, - allowEmptyArrays: typeof opts.allowEmptyArrays === 'boolean' ? !!opts.allowEmptyArrays : defaults.allowEmptyArrays, - arrayFormat: arrayFormat, - charset: charset, - charsetSentinel: typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel, - commaRoundTrip: !!opts.commaRoundTrip, - delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter, - encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode, - encodeDotInKeys: typeof opts.encodeDotInKeys === 'boolean' ? opts.encodeDotInKeys : defaults.encodeDotInKeys, - encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder, - encodeValuesOnly: typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly, - filter: filter, - format: format, - formatter: formatter, - serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate, - skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls, - sort: typeof opts.sort === 'function' ? opts.sort : null, - strictNullHandling: typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling - }; -}; - -module.exports = function (object, opts) { - var obj = object; - var options = normalizeStringifyOptions(opts); - - var objKeys; - var filter; - - if (typeof options.filter === 'function') { - filter = options.filter; - obj = filter('', obj); - } else if (isArray(options.filter)) { - filter = options.filter; - objKeys = filter; - } - - var keys = []; - - if (typeof obj !== 'object' || obj === null) { - return ''; - } - - var generateArrayPrefix = arrayPrefixGenerators[options.arrayFormat]; - var commaRoundTrip = generateArrayPrefix === 'comma' && options.commaRoundTrip; - - if (!objKeys) { - objKeys = Object.keys(obj); - } - - if (options.sort) { - objKeys.sort(options.sort); - } - - var sideChannel = getSideChannel(); - for (var i = 0; i < objKeys.length; ++i) { - var key = objKeys[i]; - var value = obj[key]; - - if (options.skipNulls && value === null) { - continue; - } - pushToArray(keys, stringify( - value, - key, - generateArrayPrefix, - commaRoundTrip, - options.allowEmptyArrays, - options.strictNullHandling, - options.skipNulls, - options.encodeDotInKeys, - options.encode ? options.encoder : null, - options.filter, - options.sort, - options.allowDots, - options.serializeDate, - options.format, - options.formatter, - options.encodeValuesOnly, - options.charset, - sideChannel - )); - } - - var joined = keys.join(options.delimiter); - var prefix = options.addQueryPrefix === true ? '?' : ''; - - if (options.charsetSentinel) { - if (options.charset === 'iso-8859-1') { - // encodeURIComponent('✓'), the "numeric entity" representation of a checkmark - prefix += 'utf8=%26%2310003%3B&'; - } else { - // encodeURIComponent('✓') - prefix += 'utf8=%E2%9C%93&'; - } - } - - return joined.length > 0 ? prefix + joined : ''; -}; diff --git a/node_modules/body-parser/node_modules/qs/lib/utils.js b/node_modules/body-parser/node_modules/qs/lib/utils.js deleted file mode 100644 index 9aa39e1..0000000 --- a/node_modules/body-parser/node_modules/qs/lib/utils.js +++ /dev/null @@ -1,342 +0,0 @@ -'use strict'; - -var formats = require('./formats'); -var getSideChannel = require('side-channel'); - -var has = Object.prototype.hasOwnProperty; -var isArray = Array.isArray; - -// Track objects created from arrayLimit overflow using side-channel -// Stores the current max numeric index for O(1) lookup -var overflowChannel = getSideChannel(); - -var markOverflow = function markOverflow(obj, maxIndex) { - overflowChannel.set(obj, maxIndex); - return obj; -}; - -var isOverflow = function isOverflow(obj) { - return overflowChannel.has(obj); -}; - -var getMaxIndex = function getMaxIndex(obj) { - return overflowChannel.get(obj); -}; - -var setMaxIndex = function setMaxIndex(obj, maxIndex) { - overflowChannel.set(obj, maxIndex); -}; - -var hexTable = (function () { - var array = []; - for (var i = 0; i < 256; ++i) { - array[array.length] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase(); - } - - return array; -}()); - -var compactQueue = function compactQueue(queue) { - while (queue.length > 1) { - var item = queue.pop(); - var obj = item.obj[item.prop]; - - if (isArray(obj)) { - var compacted = []; - - for (var j = 0; j < obj.length; ++j) { - if (typeof obj[j] !== 'undefined') { - compacted[compacted.length] = obj[j]; - } - } - - item.obj[item.prop] = compacted; - } - } -}; - -var arrayToObject = function arrayToObject(source, options) { - var obj = options && options.plainObjects ? { __proto__: null } : {}; - for (var i = 0; i < source.length; ++i) { - if (typeof source[i] !== 'undefined') { - obj[i] = source[i]; - } - } - - return obj; -}; - -var merge = function merge(target, source, options) { - /* eslint no-param-reassign: 0 */ - if (!source) { - return target; - } - - if (typeof source !== 'object' && typeof source !== 'function') { - if (isArray(target)) { - var nextIndex = target.length; - if (options && typeof options.arrayLimit === 'number' && nextIndex > options.arrayLimit) { - return markOverflow(arrayToObject(target.concat(source), options), nextIndex); - } - target[nextIndex] = source; - } else if (target && typeof target === 'object') { - if (isOverflow(target)) { - // Add at next numeric index for overflow objects - var newIndex = getMaxIndex(target) + 1; - target[newIndex] = source; - setMaxIndex(target, newIndex); - } else if (options && options.strictMerge) { - return [target, source]; - } else if ( - (options && (options.plainObjects || options.allowPrototypes)) - || !has.call(Object.prototype, source) - ) { - target[source] = true; - } - } else { - return [target, source]; - } - - return target; - } - - if (!target || typeof target !== 'object') { - if (isOverflow(source)) { - // Create new object with target at 0, source values shifted by 1 - var sourceKeys = Object.keys(source); - var result = options && options.plainObjects - ? { __proto__: null, 0: target } - : { 0: target }; - for (var m = 0; m < sourceKeys.length; m++) { - var oldKey = parseInt(sourceKeys[m], 10); - result[oldKey + 1] = source[sourceKeys[m]]; - } - return markOverflow(result, getMaxIndex(source) + 1); - } - var combined = [target].concat(source); - if (options && typeof options.arrayLimit === 'number' && combined.length > options.arrayLimit) { - return markOverflow(arrayToObject(combined, options), combined.length - 1); - } - return combined; - } - - var mergeTarget = target; - if (isArray(target) && !isArray(source)) { - mergeTarget = arrayToObject(target, options); - } - - if (isArray(target) && isArray(source)) { - source.forEach(function (item, i) { - if (has.call(target, i)) { - var targetItem = target[i]; - if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') { - target[i] = merge(targetItem, item, options); - } else { - target[target.length] = item; - } - } else { - target[i] = item; - } - }); - return target; - } - - return Object.keys(source).reduce(function (acc, key) { - var value = source[key]; - - if (has.call(acc, key)) { - acc[key] = merge(acc[key], value, options); - } else { - acc[key] = value; - } - - if (isOverflow(source) && !isOverflow(acc)) { - markOverflow(acc, getMaxIndex(source)); - } - if (isOverflow(acc)) { - var keyNum = parseInt(key, 10); - if (String(keyNum) === key && keyNum >= 0 && keyNum > getMaxIndex(acc)) { - setMaxIndex(acc, keyNum); - } - } - - return acc; - }, mergeTarget); -}; - -var assign = function assignSingleSource(target, source) { - return Object.keys(source).reduce(function (acc, key) { - acc[key] = source[key]; - return acc; - }, target); -}; - -var decode = function (str, defaultDecoder, charset) { - var strWithoutPlus = str.replace(/\+/g, ' '); - if (charset === 'iso-8859-1') { - // unescape never throws, no try...catch needed: - return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape); - } - // utf-8 - try { - return decodeURIComponent(strWithoutPlus); - } catch (e) { - return strWithoutPlus; - } -}; - -var limit = 1024; - -/* eslint operator-linebreak: [2, "before"] */ - -var encode = function encode(str, defaultEncoder, charset, kind, format) { - // This code was originally written by Brian White (mscdex) for the io.js core querystring library. - // It has been adapted here for stricter adherence to RFC 3986 - if (str.length === 0) { - return str; - } - - var string = str; - if (typeof str === 'symbol') { - string = Symbol.prototype.toString.call(str); - } else if (typeof str !== 'string') { - string = String(str); - } - - if (charset === 'iso-8859-1') { - return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) { - return '%26%23' + parseInt($0.slice(2), 16) + '%3B'; - }); - } - - var out = ''; - for (var j = 0; j < string.length; j += limit) { - var segment = string.length >= limit ? string.slice(j, j + limit) : string; - var arr = []; - - for (var i = 0; i < segment.length; ++i) { - var c = segment.charCodeAt(i); - if ( - c === 0x2D // - - || c === 0x2E // . - || c === 0x5F // _ - || c === 0x7E // ~ - || (c >= 0x30 && c <= 0x39) // 0-9 - || (c >= 0x41 && c <= 0x5A) // a-z - || (c >= 0x61 && c <= 0x7A) // A-Z - || (format === formats.RFC1738 && (c === 0x28 || c === 0x29)) // ( ) - ) { - arr[arr.length] = segment.charAt(i); - continue; - } - - if (c < 0x80) { - arr[arr.length] = hexTable[c]; - continue; - } - - if (c < 0x800) { - arr[arr.length] = hexTable[0xC0 | (c >> 6)] - + hexTable[0x80 | (c & 0x3F)]; - continue; - } - - if (c < 0xD800 || c >= 0xE000) { - arr[arr.length] = hexTable[0xE0 | (c >> 12)] - + hexTable[0x80 | ((c >> 6) & 0x3F)] - + hexTable[0x80 | (c & 0x3F)]; - continue; - } - - i += 1; - c = 0x10000 + (((c & 0x3FF) << 10) | (segment.charCodeAt(i) & 0x3FF)); - - arr[arr.length] = hexTable[0xF0 | (c >> 18)] - + hexTable[0x80 | ((c >> 12) & 0x3F)] - + hexTable[0x80 | ((c >> 6) & 0x3F)] - + hexTable[0x80 | (c & 0x3F)]; - } - - out += arr.join(''); - } - - return out; -}; - -var compact = function compact(value) { - var queue = [{ obj: { o: value }, prop: 'o' }]; - var refs = []; - - for (var i = 0; i < queue.length; ++i) { - var item = queue[i]; - var obj = item.obj[item.prop]; - - var keys = Object.keys(obj); - for (var j = 0; j < keys.length; ++j) { - var key = keys[j]; - var val = obj[key]; - if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) { - queue[queue.length] = { obj: obj, prop: key }; - refs[refs.length] = val; - } - } - } - - compactQueue(queue); - - return value; -}; - -var isRegExp = function isRegExp(obj) { - return Object.prototype.toString.call(obj) === '[object RegExp]'; -}; - -var isBuffer = function isBuffer(obj) { - if (!obj || typeof obj !== 'object') { - return false; - } - - return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); -}; - -var combine = function combine(a, b, arrayLimit, plainObjects) { - // If 'a' is already an overflow object, add to it - if (isOverflow(a)) { - var newIndex = getMaxIndex(a) + 1; - a[newIndex] = b; - setMaxIndex(a, newIndex); - return a; - } - - var result = [].concat(a, b); - if (result.length > arrayLimit) { - return markOverflow(arrayToObject(result, { plainObjects: plainObjects }), result.length - 1); - } - return result; -}; - -var maybeMap = function maybeMap(val, fn) { - if (isArray(val)) { - var mapped = []; - for (var i = 0; i < val.length; i += 1) { - mapped[mapped.length] = fn(val[i]); - } - return mapped; - } - return fn(val); -}; - -module.exports = { - arrayToObject: arrayToObject, - assign: assign, - combine: combine, - compact: compact, - decode: decode, - encode: encode, - isBuffer: isBuffer, - isOverflow: isOverflow, - isRegExp: isRegExp, - markOverflow: markOverflow, - maybeMap: maybeMap, - merge: merge -}; diff --git a/node_modules/body-parser/node_modules/qs/package.json b/node_modules/body-parser/node_modules/qs/package.json deleted file mode 100644 index cb97371..0000000 --- a/node_modules/body-parser/node_modules/qs/package.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "name": "qs", - "description": "A querystring parser that supports nesting and arrays, with a depth limit", - "homepage": "https://github.com/ljharb/qs", - "version": "6.15.1", - "repository": { - "type": "git", - "url": "https://github.com/ljharb/qs.git" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - }, - "main": "lib/index.js", - "sideEffects": false, - "contributors": [ - { - "name": "Jordan Harband", - "email": "ljharb@gmail.com", - "url": "http://ljharb.codes" - } - ], - "keywords": [ - "querystring", - "qs", - "query", - "url", - "parse", - "stringify" - ], - "engines": { - "node": ">=0.6" - }, - "dependencies": { - "side-channel": "^1.1.0" - }, - "devDependencies": { - "@browserify/envify": "^6.0.0", - "@browserify/uglifyify": "^6.0.0", - "@ljharb/eslint-config": "^22.2.2", - "browserify": "^16.5.2", - "bundle-collapser": "^1.4.0", - "common-shakeify": "~1.0.0", - "eclint": "^2.8.1", - "es-value-fixtures": "^1.7.1", - "eslint": "^9.39.2", - "evalmd": "^0.0.19", - "for-each": "^0.3.5", - "glob": "=10.3.7", - "has-bigints": "^1.1.0", - "has-override-mistake": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.2.0", - "has-symbols": "^1.1.0", - "iconv-lite": "^0.5.2", - "in-publish": "^2.0.1", - "jackspeak": "=2.1.1", - "jiti": "^0.0.0", - "mkdirp": "^0.5.5", - "mock-property": "^1.1.0", - "module-deps": "^6.2.3", - "npmignore": "^0.3.5", - "nyc": "^10.3.2", - "object-inspect": "^1.13.4", - "qs-iconv": "^1.0.4", - "safe-publish-latest": "^2.0.0", - "safer-buffer": "^2.1.2", - "tape": "^5.9.0", - "unassertify": "^3.0.1" - }, - "scripts": { - "prepack": "npmignore --auto --commentLines=autogenerated && npm run dist", - "prepublishOnly": "safe-publish-latest", - "prepublish": "not-in-publish || npm run prepublishOnly", - "pretest": "npm run --silent readme && npm run --silent lint", - "test": "npm run tests-only", - "tests-only": "nyc tape 'test/**/*.js'", - "posttest": "npx npm@'>=10.2' audit --production", - "readme": "evalmd README.md", - "postlint": "eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git' | grep -v dist/)", - "lint": "eslint .", - "dist": "mkdirp dist && browserify --standalone Qs -g unassertify -g @browserify/envify -g [@browserify/uglifyify --mangle.keep_fnames --compress.keep_fnames --format.indent_level=1 --compress.arrows=false --compress.passes=4 --compress.typeofs=false] -p common-shakeify -p bundle-collapser/plugin lib/index.js > dist/qs.js" - }, - "license": "BSD-3-Clause", - "publishConfig": { - "ignore": [ - "!dist/*", - "bower.json", - "component.json", - ".github/workflows", - "logos", - "tea.yaml" - ] - } -} diff --git a/node_modules/body-parser/node_modules/qs/test/empty-keys-cases.js b/node_modules/body-parser/node_modules/qs/test/empty-keys-cases.js deleted file mode 100644 index 2b1190e..0000000 --- a/node_modules/body-parser/node_modules/qs/test/empty-keys-cases.js +++ /dev/null @@ -1,267 +0,0 @@ -'use strict'; - -module.exports = { - emptyTestCases: [ - { - input: '&', - withEmptyKeys: {}, - stringifyOutput: { - brackets: '', - indices: '', - repeat: '' - }, - noEmptyKeys: {} - }, - { - input: '&&', - withEmptyKeys: {}, - stringifyOutput: { - brackets: '', - indices: '', - repeat: '' - }, - noEmptyKeys: {} - }, - { - input: '&=', - withEmptyKeys: { '': '' }, - stringifyOutput: { - brackets: '=', - indices: '=', - repeat: '=' - }, - noEmptyKeys: {} - }, - { - input: '&=&', - withEmptyKeys: { '': '' }, - stringifyOutput: { - brackets: '=', - indices: '=', - repeat: '=' - }, - noEmptyKeys: {} - }, - { - input: '&=&=', - withEmptyKeys: { '': ['', ''] }, - stringifyOutput: { - brackets: '[]=&[]=', - indices: '[0]=&[1]=', - repeat: '=&=' - }, - noEmptyKeys: {} - }, - { - input: '&=&=&', - withEmptyKeys: { '': ['', ''] }, - stringifyOutput: { - brackets: '[]=&[]=', - indices: '[0]=&[1]=', - repeat: '=&=' - }, - noEmptyKeys: {} - }, - { - input: '=', - withEmptyKeys: { '': '' }, - noEmptyKeys: {}, - stringifyOutput: { - brackets: '=', - indices: '=', - repeat: '=' - } - }, - { - input: '=&', - withEmptyKeys: { '': '' }, - stringifyOutput: { - brackets: '=', - indices: '=', - repeat: '=' - }, - noEmptyKeys: {} - }, - { - input: '=&&&', - withEmptyKeys: { '': '' }, - stringifyOutput: { - brackets: '=', - indices: '=', - repeat: '=' - }, - noEmptyKeys: {} - }, - { - input: '=&=&=&', - withEmptyKeys: { '': ['', '', ''] }, - stringifyOutput: { - brackets: '[]=&[]=&[]=', - indices: '[0]=&[1]=&[2]=', - repeat: '=&=&=' - }, - noEmptyKeys: {} - }, - { - input: '=&a[]=b&a[1]=c', - withEmptyKeys: { '': '', a: ['b', 'c'] }, - stringifyOutput: { - brackets: '=&a[]=b&a[]=c', - indices: '=&a[0]=b&a[1]=c', - repeat: '=&a=b&a=c' - }, - noEmptyKeys: { a: ['b', 'c'] } - }, - { - input: '=a', - withEmptyKeys: { '': 'a' }, - noEmptyKeys: {}, - stringifyOutput: { - brackets: '=a', - indices: '=a', - repeat: '=a' - } - }, - { - input: 'a==a', - withEmptyKeys: { a: '=a' }, - noEmptyKeys: { a: '=a' }, - stringifyOutput: { - brackets: 'a==a', - indices: 'a==a', - repeat: 'a==a' - } - }, - { - input: '=&a[]=b', - withEmptyKeys: { '': '', a: ['b'] }, - stringifyOutput: { - brackets: '=&a[]=b', - indices: '=&a[0]=b', - repeat: '=&a=b' - }, - noEmptyKeys: { a: ['b'] } - }, - { - input: '=&a[]=b&a[]=c&a[2]=d', - withEmptyKeys: { '': '', a: ['b', 'c', 'd'] }, - stringifyOutput: { - brackets: '=&a[]=b&a[]=c&a[]=d', - indices: '=&a[0]=b&a[1]=c&a[2]=d', - repeat: '=&a=b&a=c&a=d' - }, - noEmptyKeys: { a: ['b', 'c', 'd'] } - }, - { - input: '=a&=b', - withEmptyKeys: { '': ['a', 'b'] }, - stringifyOutput: { - brackets: '[]=a&[]=b', - indices: '[0]=a&[1]=b', - repeat: '=a&=b' - }, - noEmptyKeys: {} - }, - { - input: '=a&foo=b', - withEmptyKeys: { '': 'a', foo: 'b' }, - noEmptyKeys: { foo: 'b' }, - stringifyOutput: { - brackets: '=a&foo=b', - indices: '=a&foo=b', - repeat: '=a&foo=b' - } - }, - { - input: 'a[]=b&a=c&=', - withEmptyKeys: { '': '', a: ['b', 'c'] }, - stringifyOutput: { - brackets: '=&a[]=b&a[]=c', - indices: '=&a[0]=b&a[1]=c', - repeat: '=&a=b&a=c' - }, - noEmptyKeys: { a: ['b', 'c'] } - }, - { - input: 'a[]=b&a=c&=', - withEmptyKeys: { '': '', a: ['b', 'c'] }, - stringifyOutput: { - brackets: '=&a[]=b&a[]=c', - indices: '=&a[0]=b&a[1]=c', - repeat: '=&a=b&a=c' - }, - noEmptyKeys: { a: ['b', 'c'] } - }, - { - input: 'a[0]=b&a=c&=', - withEmptyKeys: { '': '', a: ['b', 'c'] }, - stringifyOutput: { - brackets: '=&a[]=b&a[]=c', - indices: '=&a[0]=b&a[1]=c', - repeat: '=&a=b&a=c' - }, - noEmptyKeys: { a: ['b', 'c'] } - }, - { - input: 'a=b&a[]=c&=', - withEmptyKeys: { '': '', a: ['b', 'c'] }, - stringifyOutput: { - brackets: '=&a[]=b&a[]=c', - indices: '=&a[0]=b&a[1]=c', - repeat: '=&a=b&a=c' - }, - noEmptyKeys: { a: ['b', 'c'] } - }, - { - input: 'a=b&a[0]=c&=', - withEmptyKeys: { '': '', a: ['b', 'c'] }, - stringifyOutput: { - brackets: '=&a[]=b&a[]=c', - indices: '=&a[0]=b&a[1]=c', - repeat: '=&a=b&a=c' - }, - noEmptyKeys: { a: ['b', 'c'] } - }, - { - input: '[]=a&[]=b& []=1', - withEmptyKeys: { '': ['a', 'b'], ' ': ['1'] }, - stringifyOutput: { - brackets: '[]=a&[]=b& []=1', - indices: '[0]=a&[1]=b& [0]=1', - repeat: '=a&=b& =1' - }, - noEmptyKeys: { 0: 'a', 1: 'b', ' ': ['1'] } - }, - { - input: '[0]=a&[1]=b&a[0]=1&a[1]=2', - withEmptyKeys: { '': ['a', 'b'], a: ['1', '2'] }, - noEmptyKeys: { 0: 'a', 1: 'b', a: ['1', '2'] }, - stringifyOutput: { - brackets: '[]=a&[]=b&a[]=1&a[]=2', - indices: '[0]=a&[1]=b&a[0]=1&a[1]=2', - repeat: '=a&=b&a=1&a=2' - } - }, - { - input: '[deep]=a&[deep]=2', - withEmptyKeys: { '': { deep: ['a', '2'] } - }, - stringifyOutput: { - brackets: '[deep][]=a&[deep][]=2', - indices: '[deep][0]=a&[deep][1]=2', - repeat: '[deep]=a&[deep]=2' - }, - noEmptyKeys: { deep: ['a', '2'] } - }, - { - input: '%5B0%5D=a&%5B1%5D=b', - withEmptyKeys: { '': ['a', 'b'] }, - stringifyOutput: { - brackets: '[]=a&[]=b', - indices: '[0]=a&[1]=b', - repeat: '=a&=b' - }, - noEmptyKeys: { 0: 'a', 1: 'b' } - } - ] -}; diff --git a/node_modules/body-parser/node_modules/qs/test/parse.js b/node_modules/body-parser/node_modules/qs/test/parse.js deleted file mode 100644 index 0dee310..0000000 --- a/node_modules/body-parser/node_modules/qs/test/parse.js +++ /dev/null @@ -1,1654 +0,0 @@ -'use strict'; - -var test = require('tape'); -var hasPropertyDescriptors = require('has-property-descriptors')(); -var iconv = require('iconv-lite'); -var mockProperty = require('mock-property'); -var hasOverrideMistake = require('has-override-mistake')(); -var SaferBuffer = require('safer-buffer').Buffer; -var v = require('es-value-fixtures'); -var inspect = require('object-inspect'); -var emptyTestCases = require('./empty-keys-cases').emptyTestCases; -var hasProto = require('has-proto')(); - -var qs = require('../'); -var utils = require('../lib/utils'); - -test('parse()', function (t) { - t.test('parses a simple string', function (st) { - st.deepEqual(qs.parse('0=foo'), { 0: 'foo' }); - st.deepEqual(qs.parse('foo=c++'), { foo: 'c ' }); - st.deepEqual(qs.parse('a[>=]=23'), { a: { '>=': '23' } }); - st.deepEqual(qs.parse('a[<=>]==23'), { a: { '<=>': '=23' } }); - st.deepEqual(qs.parse('a[==]=23'), { a: { '==': '23' } }); - st.deepEqual(qs.parse('foo', { strictNullHandling: true }), { foo: null }); - st.deepEqual(qs.parse('foo'), { foo: '' }); - st.deepEqual(qs.parse('foo='), { foo: '' }); - st.deepEqual(qs.parse('foo=bar'), { foo: 'bar' }); - st.deepEqual(qs.parse(' foo = bar = baz '), { ' foo ': ' bar = baz ' }); - st.deepEqual(qs.parse('foo=bar=baz'), { foo: 'bar=baz' }); - st.deepEqual(qs.parse('foo=bar&bar=baz'), { foo: 'bar', bar: 'baz' }); - st.deepEqual(qs.parse('foo2=bar2&baz2='), { foo2: 'bar2', baz2: '' }); - st.deepEqual(qs.parse('foo=bar&baz', { strictNullHandling: true }), { foo: 'bar', baz: null }); - st.deepEqual(qs.parse('foo=bar&baz'), { foo: 'bar', baz: '' }); - st.deepEqual(qs.parse('cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World'), { - cht: 'p3', - chd: 't:60,40', - chs: '250x100', - chl: 'Hello|World' - }); - st.end(); - }); - - t.test('comma: false', function (st) { - st.deepEqual(qs.parse('a[]=b&a[]=c'), { a: ['b', 'c'] }); - st.deepEqual(qs.parse('a[0]=b&a[1]=c'), { a: ['b', 'c'] }); - st.deepEqual(qs.parse('a=b,c'), { a: 'b,c' }); - st.deepEqual(qs.parse('a=b&a=c'), { a: ['b', 'c'] }); - st.end(); - }); - - t.test('comma: true', function (st) { - st.deepEqual(qs.parse('a[]=b&a[]=c', { comma: true }), { a: ['b', 'c'] }); - st.deepEqual(qs.parse('a[0]=b&a[1]=c', { comma: true }), { a: ['b', 'c'] }); - st.deepEqual(qs.parse('a=b,c', { comma: true }), { a: ['b', 'c'] }); - st.deepEqual(qs.parse('a=b&a=c', { comma: true }), { a: ['b', 'c'] }); - st.end(); - }); - - t.test('allows enabling dot notation', function (st) { - st.deepEqual(qs.parse('a.b=c'), { 'a.b': 'c' }); - st.deepEqual(qs.parse('a.b=c', { allowDots: true }), { a: { b: 'c' } }); - - st.end(); - }); - - t.test('decode dot keys correctly', function (st) { - st.deepEqual( - qs.parse('name%252Eobj.first=John&name%252Eobj.last=Doe', { allowDots: false, decodeDotInKeys: false }), - { 'name%2Eobj.first': 'John', 'name%2Eobj.last': 'Doe' }, - 'with allowDots false and decodeDotInKeys false' - ); - st.deepEqual( - qs.parse('name.obj.first=John&name.obj.last=Doe', { allowDots: true, decodeDotInKeys: false }), - { name: { obj: { first: 'John', last: 'Doe' } } }, - 'with allowDots false and decodeDotInKeys false' - ); - st.deepEqual( - qs.parse('name%252Eobj.first=John&name%252Eobj.last=Doe', { allowDots: true, decodeDotInKeys: false }), - { 'name%2Eobj': { first: 'John', last: 'Doe' } }, - 'with allowDots true and decodeDotInKeys false' - ); - st.deepEqual( - qs.parse('name%252Eobj.first=John&name%252Eobj.last=Doe', { allowDots: true, decodeDotInKeys: true }), - { 'name.obj': { first: 'John', last: 'Doe' } }, - 'with allowDots true and decodeDotInKeys true' - ); - - st.deepEqual( - qs.parse( - 'name%252Eobj%252Esubobject.first%252Egodly%252Ename=John&name%252Eobj%252Esubobject.last=Doe', - { allowDots: false, decodeDotInKeys: false } - ), - { 'name%2Eobj%2Esubobject.first%2Egodly%2Ename': 'John', 'name%2Eobj%2Esubobject.last': 'Doe' }, - 'with allowDots false and decodeDotInKeys false' - ); - st.deepEqual( - qs.parse( - 'name.obj.subobject.first.godly.name=John&name.obj.subobject.last=Doe', - { allowDots: true, decodeDotInKeys: false } - ), - { name: { obj: { subobject: { first: { godly: { name: 'John' } }, last: 'Doe' } } } }, - 'with allowDots true and decodeDotInKeys false' - ); - st.deepEqual( - qs.parse( - 'name%252Eobj%252Esubobject.first%252Egodly%252Ename=John&name%252Eobj%252Esubobject.last=Doe', - { allowDots: true, decodeDotInKeys: true } - ), - { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, - 'with allowDots true and decodeDotInKeys true' - ); - st.deepEqual( - qs.parse('name%252Eobj.first=John&name%252Eobj.last=Doe'), - { 'name%2Eobj.first': 'John', 'name%2Eobj.last': 'Doe' }, - 'with allowDots and decodeDotInKeys undefined' - ); - - st.end(); - }); - - t.test('decodes dot in key of object, and allow enabling dot notation when decodeDotInKeys is set to true and allowDots is undefined', function (st) { - st.deepEqual( - qs.parse( - 'name%252Eobj%252Esubobject.first%252Egodly%252Ename=John&name%252Eobj%252Esubobject.last=Doe', - { decodeDotInKeys: true } - ), - { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, - 'with allowDots undefined and decodeDotInKeys true' - ); - - st.end(); - }); - - t.test('throws when decodeDotInKeys is not of type boolean', function (st) { - st['throws']( - function () { qs.parse('foo[]&bar=baz', { decodeDotInKeys: 'foobar' }); }, - TypeError - ); - - st['throws']( - function () { qs.parse('foo[]&bar=baz', { decodeDotInKeys: 0 }); }, - TypeError - ); - st['throws']( - function () { qs.parse('foo[]&bar=baz', { decodeDotInKeys: NaN }); }, - TypeError - ); - - st['throws']( - function () { qs.parse('foo[]&bar=baz', { decodeDotInKeys: null }); }, - TypeError - ); - - st.end(); - }); - - t.test('allows empty arrays in obj values', function (st) { - st.deepEqual(qs.parse('foo[]&bar=baz', { allowEmptyArrays: true }), { foo: [], bar: 'baz' }); - st.deepEqual(qs.parse('foo[]&bar=baz', { allowEmptyArrays: false }), { foo: [''], bar: 'baz' }); - - st.end(); - }); - - t.test('throws when allowEmptyArrays is not of type boolean', function (st) { - st['throws']( - function () { qs.parse('foo[]&bar=baz', { allowEmptyArrays: 'foobar' }); }, - TypeError - ); - - st['throws']( - function () { qs.parse('foo[]&bar=baz', { allowEmptyArrays: 0 }); }, - TypeError - ); - st['throws']( - function () { qs.parse('foo[]&bar=baz', { allowEmptyArrays: NaN }); }, - TypeError - ); - - st['throws']( - function () { qs.parse('foo[]&bar=baz', { allowEmptyArrays: null }); }, - TypeError - ); - - st.end(); - }); - - t.test('allowEmptyArrays + strictNullHandling', function (st) { - st.deepEqual( - qs.parse('testEmptyArray[]', { strictNullHandling: true, allowEmptyArrays: true }), - { testEmptyArray: [] } - ); - - st.end(); - }); - - t.deepEqual(qs.parse('a[b]=c'), { a: { b: 'c' } }, 'parses a single nested string'); - t.deepEqual(qs.parse('a[b][c]=d'), { a: { b: { c: 'd' } } }, 'parses a double nested string'); - t.deepEqual( - qs.parse('a[b][c][d][e][f][g][h]=i'), - { a: { b: { c: { d: { e: { f: { '[g][h]': 'i' } } } } } } }, - 'defaults to a depth of 5' - ); - - t.test('only parses one level when depth = 1', function (st) { - st.deepEqual(qs.parse('a[b][c]=d', { depth: 1 }), { a: { b: { '[c]': 'd' } } }); - st.deepEqual(qs.parse('a[b][c][d]=e', { depth: 1 }), { a: { b: { '[c][d]': 'e' } } }); - st.end(); - }); - - t.test('uses original key when depth = 0', function (st) { - st.deepEqual(qs.parse('a[0]=b&a[1]=c', { depth: 0 }), { 'a[0]': 'b', 'a[1]': 'c' }); - st.deepEqual(qs.parse('a[0][0]=b&a[0][1]=c&a[1]=d&e=2', { depth: 0 }), { 'a[0][0]': 'b', 'a[0][1]': 'c', 'a[1]': 'd', e: '2' }); - st.end(); - }); - - t.test('ignores prototype keys when depth = 0 and allowPrototypes is false', function (st) { - st.deepEqual(qs.parse('toString=foo', { depth: 0 }), {}); - st.deepEqual(qs.parse('hasOwnProperty=bar', { depth: 0 }), {}); - st.deepEqual(qs.parse('toString=foo&a=b', { depth: 0 }), { a: 'b' }); - st.end(); - }); - - t.test('allows prototype keys when depth = 0 and allowPrototypes is true', function (st) { - st.deepEqual(qs.parse('toString=foo', { depth: 0, allowPrototypes: true }), { toString: 'foo' }); - st.end(); - }); - - t.test('uses original key when depth = false', function (st) { - st.deepEqual(qs.parse('a[0]=b&a[1]=c', { depth: false }), { 'a[0]': 'b', 'a[1]': 'c' }); - st.deepEqual(qs.parse('a[0][0]=b&a[0][1]=c&a[1]=d&e=2', { depth: false }), { 'a[0][0]': 'b', 'a[0][1]': 'c', 'a[1]': 'd', e: '2' }); - st.end(); - }); - - t.deepEqual(qs.parse('a=b&a=c'), { a: ['b', 'c'] }, 'parses a simple array'); - - t.test('parses an explicit array', function (st) { - st.deepEqual(qs.parse('a[]=b'), { a: ['b'] }); - st.deepEqual(qs.parse('a[]=b&a[]=c'), { a: ['b', 'c'] }); - st.deepEqual(qs.parse('a[]=b&a[]=c&a[]=d'), { a: ['b', 'c', 'd'] }); - st.end(); - }); - - t.test('parses a mix of simple and explicit arrays', function (st) { - st.deepEqual(qs.parse('a=b&a[]=c'), { a: ['b', 'c'] }); - st.deepEqual(qs.parse('a[]=b&a=c'), { a: ['b', 'c'] }); - st.deepEqual(qs.parse('a[0]=b&a=c'), { a: ['b', 'c'] }); - st.deepEqual(qs.parse('a=b&a[0]=c'), { a: ['b', 'c'] }); - - st.deepEqual(qs.parse('a[1]=b&a=c', { arrayLimit: 20 }), { a: ['b', 'c'] }); - st.deepEqual(qs.parse('a[]=b&a=c', { arrayLimit: 0 }), { a: { 0: 'b', 1: 'c' } }); - st.deepEqual(qs.parse('a[]=b&a=c'), { a: ['b', 'c'] }); - - st.deepEqual(qs.parse('a=b&a[1]=c', { arrayLimit: 20 }), { a: ['b', 'c'] }); - st.deepEqual(qs.parse('a=b&a[]=c', { arrayLimit: 0 }), { a: { 0: 'b', 1: 'c' } }); - st.deepEqual(qs.parse('a=b&a[]=c'), { a: ['b', 'c'] }); - - st.end(); - }); - - t.test('parses a nested array', function (st) { - st.deepEqual(qs.parse('a[b][]=c&a[b][]=d'), { a: { b: ['c', 'd'] } }); - st.deepEqual(qs.parse('a[>=]=25'), { a: { '>=': '25' } }); - st.end(); - }); - - t.test('allows to specify array indices', function (st) { - st.deepEqual(qs.parse('a[1]=c&a[0]=b&a[2]=d'), { a: ['b', 'c', 'd'] }); - st.deepEqual(qs.parse('a[1]=c&a[0]=b'), { a: ['b', 'c'] }); - st.deepEqual(qs.parse('a[1]=c', { arrayLimit: 20 }), { a: ['c'] }); - st.deepEqual(qs.parse('a[1]=c', { arrayLimit: 0 }), { a: { 1: 'c' } }); - st.deepEqual(qs.parse('a[1]=c'), { a: ['c'] }); - st.end(); - }); - - t.test('limits specific array indices to arrayLimit', function (st) { - st.deepEqual(qs.parse('a[19]=a', { arrayLimit: 20 }), { a: ['a'] }); - st.deepEqual(qs.parse('a[20]=a', { arrayLimit: 20 }), { a: { 20: 'a' } }); - - st.deepEqual(qs.parse('a[19]=a'), { a: ['a'] }); - st.deepEqual(qs.parse('a[20]=a'), { a: { 20: 'a' } }); - st.end(); - }); - - t.deepEqual(qs.parse('a[12b]=c'), { a: { '12b': 'c' } }, 'supports keys that begin with a number'); - - t.test('supports encoded = signs', function (st) { - st.deepEqual(qs.parse('he%3Dllo=th%3Dere'), { 'he=llo': 'th=ere' }); - st.end(); - }); - - t.test('is ok with url encoded strings', function (st) { - st.deepEqual(qs.parse('a[b%20c]=d'), { a: { 'b c': 'd' } }); - st.deepEqual(qs.parse('a[b]=c%20d'), { a: { b: 'c d' } }); - st.end(); - }); - - t.test('allows brackets in the value', function (st) { - st.deepEqual(qs.parse('pets=["tobi"]'), { pets: '["tobi"]' }); - st.deepEqual(qs.parse('operators=[">=", "<="]'), { operators: '[">=", "<="]' }); - st.end(); - }); - - t.test('allows empty values', function (st) { - st.deepEqual(qs.parse(''), {}); - st.deepEqual(qs.parse(null), {}); - st.deepEqual(qs.parse(undefined), {}); - st.end(); - }); - - t.test('transforms arrays to objects', function (st) { - st.deepEqual(qs.parse('foo[0]=bar&foo[bad]=baz'), { foo: { 0: 'bar', bad: 'baz' } }); - st.deepEqual(qs.parse('foo[bad]=baz&foo[0]=bar'), { foo: { bad: 'baz', 0: 'bar' } }); - st.deepEqual(qs.parse('foo[bad]=baz&foo[]=bar'), { foo: { bad: 'baz', 0: 'bar' } }); - st.deepEqual(qs.parse('foo[]=bar&foo[bad]=baz'), { foo: { 0: 'bar', bad: 'baz' } }); - st.deepEqual(qs.parse('foo[bad]=baz&foo[]=bar&foo[]=foo'), { foo: { bad: 'baz', 0: 'bar', 1: 'foo' } }); - st.deepEqual(qs.parse('foo[0][a]=a&foo[0][b]=b&foo[1][a]=aa&foo[1][b]=bb'), { foo: [{ a: 'a', b: 'b' }, { a: 'aa', b: 'bb' }] }); - - st.deepEqual(qs.parse('a[]=b&a[t]=u&a[hasOwnProperty]=c', { allowPrototypes: false }), { a: { 0: 'b', t: 'u' } }); - st.deepEqual(qs.parse('a[]=b&a[t]=u&a[hasOwnProperty]=c', { allowPrototypes: true }), { a: { 0: 'b', t: 'u', hasOwnProperty: 'c' } }); - st.deepEqual(qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y', { allowPrototypes: false }), { a: { 0: 'b', x: 'y' } }); - st.deepEqual(qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y', { allowPrototypes: true }), { a: { 0: 'b', hasOwnProperty: 'c', x: 'y' } }); - st.end(); - }); - - t.test('transforms arrays to objects (dot notation)', function (st) { - st.deepEqual(qs.parse('foo[0].baz=bar&fool.bad=baz', { allowDots: true }), { foo: [{ baz: 'bar' }], fool: { bad: 'baz' } }); - st.deepEqual(qs.parse('foo[0].baz=bar&fool.bad.boo=baz', { allowDots: true }), { foo: [{ baz: 'bar' }], fool: { bad: { boo: 'baz' } } }); - st.deepEqual(qs.parse('foo[0][0].baz=bar&fool.bad=baz', { allowDots: true }), { foo: [[{ baz: 'bar' }]], fool: { bad: 'baz' } }); - st.deepEqual(qs.parse('foo[0].baz[0]=15&foo[0].bar=2', { allowDots: true }), { foo: [{ baz: ['15'], bar: '2' }] }); - st.deepEqual(qs.parse('foo[0].baz[0]=15&foo[0].baz[1]=16&foo[0].bar=2', { allowDots: true }), { foo: [{ baz: ['15', '16'], bar: '2' }] }); - st.deepEqual(qs.parse('foo.bad=baz&foo[0]=bar', { allowDots: true }), { foo: { bad: 'baz', 0: 'bar' } }); - st.deepEqual(qs.parse('foo.bad=baz&foo[]=bar', { allowDots: true }), { foo: { bad: 'baz', 0: 'bar' } }); - st.deepEqual(qs.parse('foo[]=bar&foo.bad=baz', { allowDots: true }), { foo: { 0: 'bar', bad: 'baz' } }); - st.deepEqual(qs.parse('foo.bad=baz&foo[]=bar&foo[]=foo', { allowDots: true }), { foo: { bad: 'baz', 0: 'bar', 1: 'foo' } }); - st.deepEqual(qs.parse('foo[0].a=a&foo[0].b=b&foo[1].a=aa&foo[1].b=bb', { allowDots: true }), { foo: [{ a: 'a', b: 'b' }, { a: 'aa', b: 'bb' }] }); - st.end(); - }); - - t.test('correctly prunes undefined values when converting an array to an object', function (st) { - st.deepEqual(qs.parse('a[2]=b&a[99999999]=c'), { a: { 2: 'b', 99999999: 'c' } }); - st.end(); - }); - - t.test('supports malformed uri characters', function (st) { - st.deepEqual(qs.parse('{%:%}', { strictNullHandling: true }), { '{%:%}': null }); - st.deepEqual(qs.parse('{%:%}='), { '{%:%}': '' }); - st.deepEqual(qs.parse('foo=%:%}'), { foo: '%:%}' }); - st.end(); - }); - - t.test('doesn\'t produce empty keys', function (st) { - st.deepEqual(qs.parse('_r=1&'), { _r: '1' }); - st.end(); - }); - - t.test('cannot access Object prototype', function (st) { - qs.parse('constructor[prototype][bad]=bad'); - qs.parse('bad[constructor][prototype][bad]=bad'); - st.equal(typeof Object.prototype.bad, 'undefined'); - st.end(); - }); - - t.test('parses arrays of objects', function (st) { - st.deepEqual(qs.parse('a[][b]=c'), { a: [{ b: 'c' }] }); - st.deepEqual(qs.parse('a[0][b]=c'), { a: [{ b: 'c' }] }); - st.end(); - }); - - t.test('allows for empty strings in arrays', function (st) { - st.deepEqual(qs.parse('a[]=b&a[]=&a[]=c'), { a: ['b', '', 'c'] }); - - st.deepEqual( - qs.parse('a[0]=b&a[1]&a[2]=c&a[19]=', { strictNullHandling: true, arrayLimit: 20 }), - { a: ['b', null, 'c', ''] }, - 'with arrayLimit 20 + array indices: null then empty string works' - ); - st.deepEqual( - qs.parse('a[]=b&a[]&a[]=c&a[]=', { strictNullHandling: true, arrayLimit: 0 }), - { a: { 0: 'b', 1: null, 2: 'c', 3: '' } }, - 'with arrayLimit 0 + array brackets: null then empty string works' - ); - - st.deepEqual( - qs.parse('a[0]=b&a[1]=&a[2]=c&a[19]', { strictNullHandling: true, arrayLimit: 20 }), - { a: ['b', '', 'c', null] }, - 'with arrayLimit 20 + array indices: empty string then null works' - ); - st.deepEqual( - qs.parse('a[]=b&a[]=&a[]=c&a[]', { strictNullHandling: true, arrayLimit: 0 }), - { a: { 0: 'b', 1: '', 2: 'c', 3: null } }, - 'with arrayLimit 0 + array brackets: empty string then null works' - ); - - st.deepEqual( - qs.parse('a[]=&a[]=b&a[]=c'), - { a: ['', 'b', 'c'] }, - 'array brackets: empty strings work' - ); - st.end(); - }); - - t.test('compacts sparse arrays', function (st) { - st.deepEqual(qs.parse('a[10]=1&a[2]=2', { arrayLimit: 20 }), { a: ['2', '1'] }); - st.deepEqual(qs.parse('a[1][b][2][c]=1', { arrayLimit: 20 }), { a: [{ b: [{ c: '1' }] }] }); - st.deepEqual(qs.parse('a[1][2][3][c]=1', { arrayLimit: 20 }), { a: [[[{ c: '1' }]]] }); - st.deepEqual(qs.parse('a[1][2][3][c][1]=1', { arrayLimit: 20 }), { a: [[[{ c: ['1'] }]]] }); - st.end(); - }); - - t.test('parses sparse arrays', function (st) { - /* eslint no-sparse-arrays: 0 */ - st.deepEqual(qs.parse('a[4]=1&a[1]=2', { allowSparse: true }), { a: [, '2', , , '1'] }); - st.deepEqual(qs.parse('a[1][b][2][c]=1', { allowSparse: true }), { a: [, { b: [, , { c: '1' }] }] }); - st.deepEqual(qs.parse('a[1][2][3][c]=1', { allowSparse: true }), { a: [, [, , [, , , { c: '1' }]]] }); - st.deepEqual(qs.parse('a[1][2][3][c][1]=1', { allowSparse: true }), { a: [, [, , [, , , { c: [, '1'] }]]] }); - st.end(); - }); - - t.test('parses semi-parsed strings', function (st) { - st.deepEqual(qs.parse({ 'a[b]': 'c' }), { a: { b: 'c' } }); - st.deepEqual(qs.parse({ 'a[b]': 'c', 'a[d]': 'e' }), { a: { b: 'c', d: 'e' } }); - st.end(); - }); - - t.test('parses buffers correctly', function (st) { - var b = SaferBuffer.from('test'); - st.deepEqual(qs.parse({ a: b }), { a: b }); - st.end(); - }); - - t.test('parses jquery-param strings', function (st) { - // readable = 'filter[0][]=int1&filter[0][]==&filter[0][]=77&filter[]=and&filter[2][]=int2&filter[2][]==&filter[2][]=8' - var encoded = 'filter%5B0%5D%5B%5D=int1&filter%5B0%5D%5B%5D=%3D&filter%5B0%5D%5B%5D=77&filter%5B%5D=and&filter%5B2%5D%5B%5D=int2&filter%5B2%5D%5B%5D=%3D&filter%5B2%5D%5B%5D=8'; - var expected = { filter: [['int1', '=', '77'], 'and', ['int2', '=', '8']] }; - st.deepEqual(qs.parse(encoded), expected); - st.end(); - }); - - t.test('continues parsing when no parent is found', function (st) { - st.deepEqual(qs.parse('[]=&a=b'), { 0: '', a: 'b' }); - st.deepEqual(qs.parse('[]&a=b', { strictNullHandling: true }), { 0: null, a: 'b' }); - st.deepEqual(qs.parse('[foo]=bar'), { foo: 'bar' }); - st.end(); - }); - - t.test('does not error when parsing a very long array', function (st) { - var str = 'a[]=a'; - while (Buffer.byteLength(str) < 128 * 1024) { - str = str + '&' + str; - } - - st.doesNotThrow(function () { - qs.parse(str); - }); - - st.end(); - }); - - t.test('does not throw when a native prototype has an enumerable property', function (st) { - st.intercept(Object.prototype, 'crash', { value: '' }); - st.intercept(Array.prototype, 'crash', { value: '' }); - - st.doesNotThrow(qs.parse.bind(null, 'a=b')); - st.deepEqual(qs.parse('a=b'), { a: 'b' }); - st.doesNotThrow(qs.parse.bind(null, 'a[][b]=c')); - st.deepEqual(qs.parse('a[][b]=c'), { a: [{ b: 'c' }] }); - - st.end(); - }); - - t.test('parses a string with an alternative string delimiter', function (st) { - st.deepEqual(qs.parse('a=b;c=d', { delimiter: ';' }), { a: 'b', c: 'd' }); - st.end(); - }); - - t.test('parses a string with an alternative RegExp delimiter', function (st) { - st.deepEqual(qs.parse('a=b; c=d', { delimiter: /[;,] */ }), { a: 'b', c: 'd' }); - st.end(); - }); - - t.test('does not use non-splittable objects as delimiters', function (st) { - st.deepEqual(qs.parse('a=b&c=d', { delimiter: true }), { a: 'b', c: 'd' }); - st.end(); - }); - - t.test('allows overriding parameter limit', function (st) { - st.deepEqual(qs.parse('a=b&c=d', { parameterLimit: 1 }), { a: 'b' }); - st.end(); - }); - - t.test('allows setting the parameter limit to Infinity', function (st) { - st.deepEqual(qs.parse('a=b&c=d', { parameterLimit: Infinity }), { a: 'b', c: 'd' }); - st.end(); - }); - - t.test('allows overriding array limit', function (st) { - st.deepEqual(qs.parse('a[0]=b', { arrayLimit: -1 }), { a: { 0: 'b' } }); - st.deepEqual(qs.parse('a[0]=b', { arrayLimit: 0 }), { a: { 0: 'b' } }); - - st.deepEqual(qs.parse('a[-1]=b', { arrayLimit: -1 }), { a: { '-1': 'b' } }); - st.deepEqual(qs.parse('a[-1]=b', { arrayLimit: 0 }), { a: { '-1': 'b' } }); - - st.deepEqual(qs.parse('a[0]=b&a[1]=c', { arrayLimit: -1 }), { a: { 0: 'b', 1: 'c' } }); - st.deepEqual(qs.parse('a[0]=b&a[1]=c', { arrayLimit: 0 }), { a: { 0: 'b', 1: 'c' } }); - - st.end(); - }); - - t.test('allows disabling array parsing', function (st) { - var indices = qs.parse('a[0]=b&a[1]=c', { parseArrays: false }); - st.deepEqual(indices, { a: { 0: 'b', 1: 'c' } }); - st.equal(Array.isArray(indices.a), false, 'parseArrays:false, indices case is not an array'); - - var emptyBrackets = qs.parse('a[]=b', { parseArrays: false }); - st.deepEqual(emptyBrackets, { a: { 0: 'b' } }); - st.equal(Array.isArray(emptyBrackets.a), false, 'parseArrays:false, empty brackets case is not an array'); - - st.end(); - }); - - t.test('allows for query string prefix', function (st) { - st.deepEqual(qs.parse('?foo=bar', { ignoreQueryPrefix: true }), { foo: 'bar' }); - st.deepEqual(qs.parse('foo=bar', { ignoreQueryPrefix: true }), { foo: 'bar' }); - st.deepEqual(qs.parse('?foo=bar', { ignoreQueryPrefix: false }), { '?foo': 'bar' }); - - st.end(); - }); - - t.test('parses an object', function (st) { - var input = { - 'user[name]': { 'pop[bob]': 3 }, - 'user[email]': null - }; - - var expected = { - user: { - name: { 'pop[bob]': 3 }, - email: null - } - }; - - var result = qs.parse(input); - - st.deepEqual(result, expected); - st.end(); - }); - - t.test('parses string with comma as array divider', function (st) { - st.deepEqual(qs.parse('foo=bar,tee', { comma: true }), { foo: ['bar', 'tee'] }); - st.deepEqual(qs.parse('foo[bar]=coffee,tee', { comma: true }), { foo: { bar: ['coffee', 'tee'] } }); - st.deepEqual(qs.parse('foo=', { comma: true }), { foo: '' }); - st.deepEqual(qs.parse('foo', { comma: true }), { foo: '' }); - st.deepEqual(qs.parse('foo', { comma: true, strictNullHandling: true }), { foo: null }); - - // test cases inversed from from stringify tests - st.deepEqual(qs.parse('a[0]=c'), { a: ['c'] }); - st.deepEqual(qs.parse('a[]=c'), { a: ['c'] }); - st.deepEqual(qs.parse('a[]=c', { comma: true }), { a: ['c'] }); - - st.deepEqual(qs.parse('a[0]=c&a[1]=d'), { a: ['c', 'd'] }); - st.deepEqual(qs.parse('a[]=c&a[]=d'), { a: ['c', 'd'] }); - st.deepEqual(qs.parse('a=c,d', { comma: true }), { a: ['c', 'd'] }); - - st.end(); - }); - - t.test('parses values with comma as array divider', function (st) { - st.deepEqual(qs.parse({ foo: 'bar,tee' }, { comma: false }), { foo: 'bar,tee' }); - st.deepEqual(qs.parse({ foo: 'bar,tee' }, { comma: true }), { foo: ['bar', 'tee'] }); - st.end(); - }); - - t.test('use number decoder, parses string that has one number with comma option enabled', function (st) { - var decoder = function (str, defaultDecoder, charset, type) { - if (!isNaN(Number(str))) { - return parseFloat(str); - } - return defaultDecoder(str, defaultDecoder, charset, type); - }; - - st.deepEqual(qs.parse('foo=1', { comma: true, decoder: decoder }), { foo: 1 }); - st.deepEqual(qs.parse('foo=0', { comma: true, decoder: decoder }), { foo: 0 }); - - st.end(); - }); - - t.test('parses brackets holds array of arrays when having two parts of strings with comma as array divider', function (st) { - st.deepEqual(qs.parse('foo[]=1,2,3&foo[]=4,5,6', { comma: true }), { foo: [['1', '2', '3'], ['4', '5', '6']] }); - st.deepEqual(qs.parse('foo[]=1,2,3&foo[]=', { comma: true }), { foo: [['1', '2', '3'], ''] }); - st.deepEqual(qs.parse('foo[]=1,2,3&foo[]=,', { comma: true }), { foo: [['1', '2', '3'], ['', '']] }); - st.deepEqual(qs.parse('foo[]=1,2,3&foo[]=a', { comma: true }), { foo: [['1', '2', '3'], 'a'] }); - - st.end(); - }); - - t.test('parses url-encoded brackets holds array of arrays when having two parts of strings with comma as array divider', function (st) { - st.deepEqual(qs.parse('foo%5B%5D=1,2,3&foo%5B%5D=4,5,6', { comma: true }), { foo: [['1', '2', '3'], ['4', '5', '6']] }); - st.deepEqual(qs.parse('foo%5B%5D=1,2,3&foo%5B%5D=', { comma: true }), { foo: [['1', '2', '3'], ''] }); - st.deepEqual(qs.parse('foo%5B%5D=1,2,3&foo%5B%5D=,', { comma: true }), { foo: [['1', '2', '3'], ['', '']] }); - st.deepEqual(qs.parse('foo%5B%5D=1,2,3&foo%5B%5D=a', { comma: true }), { foo: [['1', '2', '3'], 'a'] }); - - st.end(); - }); - - t.test('parses comma delimited array while having percent-encoded comma treated as normal text', function (st) { - st.deepEqual(qs.parse('foo=a%2Cb', { comma: true }), { foo: 'a,b' }); - st.deepEqual(qs.parse('foo=a%2C%20b,d', { comma: true }), { foo: ['a, b', 'd'] }); - st.deepEqual(qs.parse('foo=a%2C%20b,c%2C%20d', { comma: true }), { foo: ['a, b', 'c, d'] }); - - st.end(); - }); - - t.test('parses an object in dot notation', function (st) { - var input = { - 'user.name': { 'pop[bob]': 3 }, - 'user.email.': null - }; - - var expected = { - user: { - name: { 'pop[bob]': 3 }, - email: null - } - }; - - var result = qs.parse(input, { allowDots: true }); - - st.deepEqual(result, expected); - st.end(); - }); - - t.test('parses an object and not child values', function (st) { - var input = { - 'user[name]': { 'pop[bob]': { test: 3 } }, - 'user[email]': null - }; - - var expected = { - user: { - name: { 'pop[bob]': { test: 3 } }, - email: null - } - }; - - var result = qs.parse(input); - - st.deepEqual(result, expected); - st.end(); - }); - - t.test('does not blow up when Buffer global is missing', function (st) { - var restore = mockProperty(global, 'Buffer', { 'delete': true }); - - var result = qs.parse('a=b&c=d'); - - restore(); - - st.deepEqual(result, { a: 'b', c: 'd' }); - st.end(); - }); - - t.test('does not crash when parsing circular references', function (st) { - var a = {}; - a.b = a; - - var parsed; - - st.doesNotThrow(function () { - parsed = qs.parse({ 'foo[bar]': 'baz', 'foo[baz]': a }); - }); - - st.equal('foo' in parsed, true, 'parsed has "foo" property'); - st.equal('bar' in parsed.foo, true); - st.equal('baz' in parsed.foo, true); - st.equal(parsed.foo.bar, 'baz'); - st.deepEqual(parsed.foo.baz, a); - st.end(); - }); - - t.test('does not crash when parsing deep objects', function (st) { - var parsed; - var str = 'foo'; - - for (var i = 0; i < 5000; i++) { - str += '[p]'; - } - - str += '=bar'; - - st.doesNotThrow(function () { - parsed = qs.parse(str, { depth: 5000 }); - }); - - st.equal('foo' in parsed, true, 'parsed has "foo" property'); - - var depth = 0; - var ref = parsed.foo; - while ((ref = ref.p)) { - depth += 1; - } - - st.equal(depth, 5000, 'parsed is 5000 properties deep'); - - st.end(); - }); - - t.test('parses null objects correctly', { skip: !hasProto }, function (st) { - var a = { __proto__: null, b: 'c' }; - - st.deepEqual(qs.parse(a), { b: 'c' }); - var result = qs.parse({ a: a }); - st.equal('a' in result, true, 'result has "a" property'); - st.deepEqual(result.a, a); - st.end(); - }); - - t.test('parses dates correctly', function (st) { - var now = new Date(); - st.deepEqual(qs.parse({ a: now }), { a: now }); - st.end(); - }); - - t.test('parses regular expressions correctly', function (st) { - var re = /^test$/; - st.deepEqual(qs.parse({ a: re }), { a: re }); - st.end(); - }); - - t.test('does not allow overwriting prototype properties', function (st) { - st.deepEqual(qs.parse('a[hasOwnProperty]=b', { allowPrototypes: false }), {}); - st.deepEqual(qs.parse('hasOwnProperty=b', { allowPrototypes: false }), {}); - - st.deepEqual( - qs.parse('toString', { allowPrototypes: false }), - {}, - 'bare "toString" results in {}' - ); - - st.end(); - }); - - t.test('can allow overwriting prototype properties', function (st) { - st.deepEqual(qs.parse('a[hasOwnProperty]=b', { allowPrototypes: true }), { a: { hasOwnProperty: 'b' } }); - st.deepEqual(qs.parse('hasOwnProperty=b', { allowPrototypes: true }), { hasOwnProperty: 'b' }); - - st.deepEqual( - qs.parse('toString', { allowPrototypes: true }), - { toString: '' }, - 'bare "toString" results in { toString: "" }' - ); - - st.end(); - }); - - t.test('does not crash when the global Object prototype is frozen', { skip: !hasPropertyDescriptors || !hasOverrideMistake }, function (st) { - // We can't actually freeze the global Object prototype as that will interfere with other tests, and once an object is frozen, it - // can't be unfrozen. Instead, we add a new non-writable property to simulate this. - st.teardown(mockProperty(Object.prototype, 'frozenProp', { value: 'foo', nonWritable: true, nonEnumerable: true })); - - st['throws']( - function () { - var obj = {}; - obj.frozenProp = 'bar'; - }, - // node < 6 has a different error message - /^TypeError: Cannot assign to read only property 'frozenProp' of (?:object '#'|#)/, - 'regular assignment of an inherited non-writable property throws' - ); - - var parsed; - st.doesNotThrow( - function () { - parsed = qs.parse('frozenProp', { allowPrototypes: false }); - }, - 'parsing a nonwritable Object.prototype property does not throw' - ); - - st.deepEqual(parsed, {}, 'bare "frozenProp" results in {}'); - - st.end(); - }); - - t.test('params starting with a closing bracket', function (st) { - st.deepEqual(qs.parse(']=toString'), { ']': 'toString' }); - st.deepEqual(qs.parse(']]=toString'), { ']]': 'toString' }); - st.deepEqual(qs.parse(']hello]=toString'), { ']hello]': 'toString' }); - st.end(); - }); - - t.test('params starting with a starting bracket', function (st) { - st.deepEqual(qs.parse('[=toString'), { '[': 'toString' }); - st.deepEqual(qs.parse('[[=toString'), { '[[': 'toString' }); - st.deepEqual(qs.parse('[hello[=toString'), { '[hello[': 'toString' }); - st.end(); - }); - - t.test('add keys to objects', function (st) { - st.deepEqual( - qs.parse('a[b]=c&a=d', { strictMerge: false }), - { a: { b: 'c', d: true } }, - 'can add keys to objects' - ); - - st.deepEqual( - qs.parse('a[b]=c&a=toString', { strictMerge: false }), - { a: { b: 'c' } }, - 'can not overwrite prototype' - ); - - st.deepEqual( - qs.parse('a[b]=c&a=toString', { strictMerge: false, allowPrototypes: true }), - { a: { b: 'c', toString: true } }, - 'can overwrite prototype with allowPrototypes true' - ); - - st.deepEqual( - qs.parse('a[b]=c&a=toString', { strictMerge: false, plainObjects: true }), - { __proto__: null, a: { __proto__: null, b: 'c', toString: true } }, - 'can overwrite prototype with plainObjects true' - ); - - st.end(); - }); - - t.test('strictMerge wraps object and primitive into an array', function (st) { - st.deepEqual( - qs.parse('a[b]=c&a=d'), - { a: [{ b: 'c' }, 'd'] }, - 'object then primitive produces array' - ); - - st.deepEqual( - qs.parse('a=d&a[b]=c'), - { a: ['d', { b: 'c' }] }, - 'primitive then object produces array' - ); - - st.deepEqual( - qs.parse('a[b]=c&a=toString'), - { a: [{ b: 'c' }, 'toString'] }, - 'prototype-colliding value is preserved in array' - ); - - st.deepEqual( - qs.parse('a[b]=c&a=toString', { plainObjects: true }), - { __proto__: null, a: [{ __proto__: null, b: 'c' }, 'toString'] }, - 'plainObjects preserved in array wrapping' - ); - - st.end(); - }); - - t.test('dunder proto is ignored', function (st) { - var payload = 'categories[__proto__]=login&categories[__proto__]&categories[length]=42'; - var result = qs.parse(payload, { allowPrototypes: true }); - - st.deepEqual( - result, - { - categories: { - length: '42' - } - }, - 'silent [[Prototype]] payload' - ); - - var plainResult = qs.parse(payload, { allowPrototypes: true, plainObjects: true }); - - st.deepEqual( - plainResult, - { - __proto__: null, - categories: { - __proto__: null, - length: '42' - } - }, - 'silent [[Prototype]] payload: plain objects' - ); - - var query = qs.parse('categories[__proto__]=cats&categories[__proto__]=dogs&categories[some][json]=toInject', { allowPrototypes: true }); - - st.notOk(Array.isArray(query.categories), 'is not an array'); - st.notOk(query.categories instanceof Array, 'is not instanceof an array'); - st.deepEqual(query.categories, { some: { json: 'toInject' } }); - st.equal(JSON.stringify(query.categories), '{"some":{"json":"toInject"}}', 'stringifies as a non-array'); - - st.deepEqual( - qs.parse('foo[__proto__][hidden]=value&foo[bar]=stuffs', { allowPrototypes: true }), - { - foo: { - bar: 'stuffs' - } - }, - 'hidden values' - ); - - st.deepEqual( - qs.parse('foo[__proto__][hidden]=value&foo[bar]=stuffs', { allowPrototypes: true, plainObjects: true }), - { - __proto__: null, - foo: { - __proto__: null, - bar: 'stuffs' - } - }, - 'hidden values: plain objects' - ); - - st.end(); - }); - - t.test('can return null objects', { skip: !hasProto }, function (st) { - var expected = { - __proto__: null, - a: { - __proto__: null, - b: 'c', - hasOwnProperty: 'd' - } - }; - st.deepEqual(qs.parse('a[b]=c&a[hasOwnProperty]=d', { plainObjects: true }), expected); - st.deepEqual(qs.parse(null, { plainObjects: true }), { __proto__: null }); - var expectedArray = { - __proto__: null, - a: { - __proto__: null, - 0: 'b', - c: 'd' - } - }; - st.deepEqual(qs.parse('a[]=b&a[c]=d', { plainObjects: true }), expectedArray); - st.end(); - }); - - t.test('can parse with custom encoding', function (st) { - st.deepEqual(qs.parse('%8c%a7=%91%e5%8d%e3%95%7b', { - decoder: function (str) { - var reg = /%([0-9A-F]{2})/ig; - var result = []; - var parts = reg.exec(str); - while (parts) { - result.push(parseInt(parts[1], 16)); - parts = reg.exec(str); - } - return String(iconv.decode(SaferBuffer.from(result), 'shift_jis')); - } - }), { 県: '大阪府' }); - st.end(); - }); - - t.test('receives the default decoder as a second argument', function (st) { - st.plan(1); - qs.parse('a', { - decoder: function (str, defaultDecoder) { - st.equal(defaultDecoder, utils.decode); - } - }); - st.end(); - }); - - t.test('throws error with wrong decoder', function (st) { - st['throws'](function () { - qs.parse({}, { decoder: 'string' }); - }, new TypeError('Decoder has to be a function.')); - st.end(); - }); - - t.test('does not mutate the options argument', function (st) { - var options = {}; - qs.parse('a[b]=true', options); - st.deepEqual(options, {}); - st.end(); - }); - - t.test('throws if an invalid charset is specified', function (st) { - st['throws'](function () { - qs.parse('a=b', { charset: 'foobar' }); - }, new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined')); - st.end(); - }); - - t.test('parses an iso-8859-1 string if asked to', function (st) { - st.deepEqual(qs.parse('%A2=%BD', { charset: 'iso-8859-1' }), { '¢': '½' }); - st.end(); - }); - - var urlEncodedCheckmarkInUtf8 = '%E2%9C%93'; - var urlEncodedOSlashInUtf8 = '%C3%B8'; - var urlEncodedNumCheckmark = '%26%2310003%3B'; - var urlEncodedNumSmiley = '%26%239786%3B'; - - t.test('prefers an utf-8 charset specified by the utf8 sentinel to a default charset of iso-8859-1', function (st) { - st.deepEqual(qs.parse('utf8=' + urlEncodedCheckmarkInUtf8 + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true, charset: 'iso-8859-1' }), { ø: 'ø' }); - st.end(); - }); - - t.test('prefers an iso-8859-1 charset specified by the utf8 sentinel to a default charset of utf-8', function (st) { - st.deepEqual(qs.parse('utf8=' + urlEncodedNumCheckmark + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true, charset: 'utf-8' }), { 'ø': 'ø' }); - st.end(); - }); - - t.test('does not require the utf8 sentinel to be defined before the parameters whose decoding it affects', function (st) { - st.deepEqual(qs.parse('a=' + urlEncodedOSlashInUtf8 + '&utf8=' + urlEncodedNumCheckmark, { charsetSentinel: true, charset: 'utf-8' }), { a: 'ø' }); - st.end(); - }); - - t.test('ignores an utf8 sentinel with an unknown value', function (st) { - st.deepEqual(qs.parse('utf8=foo&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true, charset: 'utf-8' }), { ø: 'ø' }); - st.end(); - }); - - t.test('uses the utf8 sentinel to switch to utf-8 when no default charset is given', function (st) { - st.deepEqual(qs.parse('utf8=' + urlEncodedCheckmarkInUtf8 + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true }), { ø: 'ø' }); - st.end(); - }); - - t.test('uses the utf8 sentinel to switch to iso-8859-1 when no default charset is given', function (st) { - st.deepEqual(qs.parse('utf8=' + urlEncodedNumCheckmark + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true }), { 'ø': 'ø' }); - st.end(); - }); - - t.test('interprets numeric entities in iso-8859-1 when `interpretNumericEntities`', function (st) { - st.deepEqual(qs.parse('foo=' + urlEncodedNumSmiley, { charset: 'iso-8859-1', interpretNumericEntities: true }), { foo: '☺' }); - st.end(); - }); - - t.test('handles a custom decoder returning `null`, in the `iso-8859-1` charset, when `interpretNumericEntities`', function (st) { - st.deepEqual(qs.parse('foo=&bar=' + urlEncodedNumSmiley, { - charset: 'iso-8859-1', - decoder: function (str, defaultDecoder, charset) { - return str ? defaultDecoder(str, defaultDecoder, charset) : null; - }, - interpretNumericEntities: true - }), { foo: null, bar: '☺' }); - st.end(); - }); - - t.test('handles a custom decoder returning `null`, with a string key of `null`', function (st) { - st.deepEqual( - qs.parse('null=1&ToNull=2', { - decoder: function (str, defaultDecoder, charset) { - return str === 'ToNull' ? null : defaultDecoder(str, defaultDecoder, charset); - } - }), - { 'null': '1' }, - '"null" key is not overridden by `null` decoder result' - ); - - st.end(); - }); - - t.test('does not interpret numeric entities in iso-8859-1 when `interpretNumericEntities` is absent', function (st) { - st.deepEqual(qs.parse('foo=' + urlEncodedNumSmiley, { charset: 'iso-8859-1' }), { foo: '☺' }); - st.end(); - }); - - t.test('does not interpret numeric entities when the charset is utf-8, even when `interpretNumericEntities`', function (st) { - st.deepEqual(qs.parse('foo=' + urlEncodedNumSmiley, { charset: 'utf-8', interpretNumericEntities: true }), { foo: '☺' }); - st.end(); - }); - - t.test('interpretNumericEntities with comma:true and iso charset does not crash', function (st) { - st.deepEqual( - qs.parse('b&a[]=1,' + urlEncodedNumSmiley, { comma: true, charset: 'iso-8859-1', interpretNumericEntities: true }), - { b: '', a: ['1,☺'] } - ); - - st.end(); - }); - - t.test('does not interpret %uXXXX syntax in iso-8859-1 mode', function (st) { - st.deepEqual(qs.parse('%u263A=%u263A', { charset: 'iso-8859-1' }), { '%u263A': '%u263A' }); - st.end(); - }); - - t.test('allows for decoding keys and values differently', function (st) { - var decoder = function (str, defaultDecoder, charset, type) { - if (type === 'key') { - return defaultDecoder(str, defaultDecoder, charset, type).toLowerCase(); - } - if (type === 'value') { - return defaultDecoder(str, defaultDecoder, charset, type).toUpperCase(); - } - throw 'this should never happen! type: ' + type; - }; - - st.deepEqual(qs.parse('KeY=vAlUe', { decoder: decoder }), { key: 'VALUE' }); - - var noopDecoder = function () { return 'x'; }; - noopDecoder(); - st['throws']( - function () { decoder('x', noopDecoder, 'utf-8', 'unknown'); }, - 'this should never happen! type: unknown', - 'decoder throws for unexpected type' - ); - - st.end(); - }); - - t.test('parameter limit tests', function (st) { - st.test('does not throw error when within parameter limit', function (sst) { - var result = qs.parse('a=1&b=2&c=3', { parameterLimit: 5, throwOnLimitExceeded: true }); - sst.deepEqual(result, { a: '1', b: '2', c: '3' }, 'parses without errors'); - sst.end(); - }); - - st.test('throws error when throwOnLimitExceeded is present but not boolean', function (sst) { - sst['throws']( - function () { - qs.parse('a=1&b=2&c=3&d=4&e=5&f=6', { parameterLimit: 3, throwOnLimitExceeded: 'true' }); - }, - new TypeError('`throwOnLimitExceeded` option must be a boolean'), - 'throws error when throwOnLimitExceeded is present and not boolean' - ); - sst.end(); - }); - - st.test('throws error when parameter limit exceeded', function (sst) { - sst['throws']( - function () { - qs.parse('a=1&b=2&c=3&d=4&e=5&f=6', { parameterLimit: 3, throwOnLimitExceeded: true }); - }, - new RangeError('Parameter limit exceeded. Only 3 parameters allowed.'), - 'throws error when parameter limit is exceeded' - ); - - sst['throws']( - function () { - qs.parse('a=1&b=2', { parameterLimit: 1, throwOnLimitExceeded: true }); - }, - new RangeError('Parameter limit exceeded. Only 1 parameter allowed.'), - 'throws error with singular "parameter" when parameterLimit is 1' - ); - sst.end(); - }); - - st.test('silently truncates when throwOnLimitExceeded is not given', function (sst) { - var result = qs.parse('a=1&b=2&c=3&d=4&e=5', { parameterLimit: 3 }); - sst.deepEqual(result, { a: '1', b: '2', c: '3' }, 'parses and truncates silently'); - sst.end(); - }); - - st.test('silently truncates when parameter limit exceeded without error', function (sst) { - var result = qs.parse('a=1&b=2&c=3&d=4&e=5', { parameterLimit: 3, throwOnLimitExceeded: false }); - sst.deepEqual(result, { a: '1', b: '2', c: '3' }, 'parses and truncates silently'); - sst.end(); - }); - - st.test('allows unlimited parameters when parameterLimit set to Infinity', function (sst) { - var result = qs.parse('a=1&b=2&c=3&d=4&e=5&f=6', { parameterLimit: Infinity }); - sst.deepEqual(result, { a: '1', b: '2', c: '3', d: '4', e: '5', f: '6' }, 'parses all parameters without truncation'); - sst.end(); - }); - - st.test('allows unlimited parameters when parameterLimit is Infinity and throwOnLimitExceeded is true', function (sst) { - var result = qs.parse('a=1&b=2&c=3&d=4&e=5&f=6', { parameterLimit: Infinity, throwOnLimitExceeded: true }); - sst.deepEqual(result, { a: '1', b: '2', c: '3', d: '4', e: '5', f: '6' }, 'parses all parameters without truncation or throwing'); - sst.end(); - }); - - st.end(); - }); - - t.test('array limit tests', function (st) { - st.test('does not throw error when array is within limit', function (sst) { - var result = qs.parse('a[]=1&a[]=2&a[]=3', { arrayLimit: 5, throwOnLimitExceeded: true }); - sst.deepEqual(result, { a: ['1', '2', '3'] }, 'parses array without errors'); - sst.end(); - }); - - st.test('throws error when throwOnLimitExceeded is present but not boolean for array limit', function (sst) { - sst['throws']( - function () { - qs.parse('a[]=1&a[]=2&a[]=3&a[]=4', { arrayLimit: 3, throwOnLimitExceeded: 'true' }); - }, - new TypeError('`throwOnLimitExceeded` option must be a boolean'), - 'throws error when throwOnLimitExceeded is present and not boolean for array limit' - ); - sst.end(); - }); - - st.test('throws error when array limit exceeded', function (sst) { - // 4 elements exceeds limit of 3 - sst['throws']( - function () { - qs.parse('a[]=1&a[]=2&a[]=3&a[]=4', { arrayLimit: 3, throwOnLimitExceeded: true }); - }, - new RangeError('Array limit exceeded. Only 3 elements allowed in an array.'), - 'throws error when array limit is exceeded' - ); - sst.end(); - }); - - st.test('does not throw when at limit', function (sst) { - // 3 elements = limit of 3, should not throw - var result = qs.parse('a[]=1&a[]=2&a[]=3', { arrayLimit: 3, throwOnLimitExceeded: true }); - sst.ok(Array.isArray(result.a), 'result is an array'); - sst.deepEqual(result.a, ['1', '2', '3'], 'all values present'); - sst.end(); - }); - - st.test('converts array to object if length is greater than limit', function (sst) { - var result = qs.parse('a[1]=1&a[2]=2&a[3]=3&a[4]=4&a[5]=5&a[6]=6', { arrayLimit: 5 }); - - sst.deepEqual(result, { a: { 1: '1', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6' } }, 'parses into object if array length is greater than limit'); - sst.end(); - }); - - st.test('throws error when indexed notation exceeds arrayLimit with throwOnLimitExceeded', function (sst) { - sst['throws']( - function () { - qs.parse('a[1001]=b', { arrayLimit: 1000, throwOnLimitExceeded: true }); - }, - new RangeError('Array limit exceeded. Only 1000 elements allowed in an array.'), - 'throws error for a single index exceeding arrayLimit' - ); - - sst['throws']( - function () { - qs.parse('a[0]=1&a[1]=2&a[2]=3&a[10]=4', { arrayLimit: 6, throwOnLimitExceeded: true, allowSparse: true }); - }, - new RangeError('Array limit exceeded. Only 6 elements allowed in an array.'), - 'throws error when a sparse index exceeds arrayLimit' - ); - - sst['throws']( - function () { - qs.parse('a[2]=b', { arrayLimit: 1, throwOnLimitExceeded: true }); - }, - new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), - 'throws error with singular "element" when arrayLimit is 1' - ); - - sst.end(); - }); - - st.test('does not throw for indexed notation within arrayLimit with throwOnLimitExceeded', function (sst) { - var result = qs.parse('a[4]=b', { arrayLimit: 5, throwOnLimitExceeded: true, allowSparse: true }); - sst.ok(Array.isArray(result.a), 'result is an array'); - sst.equal(result.a.length, 5, 'array has correct length'); - sst.equal(result.a[4], 'b', 'value at index 4 is correct'); - sst.end(); - }); - - st.test('silently converts to object for indexed notation exceeding arrayLimit without throwOnLimitExceeded', function (sst) { - var result = qs.parse('a[1001]=b', { arrayLimit: 1000 }); - sst.deepEqual(result, { a: { 1001: 'b' } }, 'converts to object without throwing'); - sst.end(); - }); - - st.test('throws when duplicate bracket keys exceed arrayLimit with throwOnLimitExceeded', function (sst) { - sst['throws']( - function () { - qs.parse('a[]=1&a[]=2&a[]=3&a[]=4&a[]=5&a[]=6', { arrayLimit: 5, throwOnLimitExceeded: true }); - }, - new RangeError('Array limit exceeded. Only 5 elements allowed in an array.'), - 'throws error when duplicate bracket notation exceeds array limit' - ); - sst.end(); - }); - - st.end(); - }); - - t.end(); -}); - -test('parses empty keys', function (t) { - emptyTestCases.forEach(function (testCase) { - t.test('skips empty string key with ' + testCase.input, function (st) { - st.deepEqual(qs.parse(testCase.input), testCase.noEmptyKeys); - - st.end(); - }); - }); -}); - -test('`duplicates` option', function (t) { - v.nonStrings.concat('not a valid option').forEach(function (invalidOption) { - if (typeof invalidOption !== 'undefined') { - t['throws']( - function () { qs.parse('', { duplicates: invalidOption }); }, - TypeError, - 'throws on invalid option: ' + inspect(invalidOption) - ); - } - }); - - t.deepEqual( - qs.parse('foo=bar&foo=baz'), - { foo: ['bar', 'baz'] }, - 'duplicates: default, combine' - ); - - t.deepEqual( - qs.parse('foo=bar&foo=baz', { duplicates: 'combine' }), - { foo: ['bar', 'baz'] }, - 'duplicates: combine' - ); - - t.deepEqual( - qs.parse('foo=bar&foo=baz', { duplicates: 'first' }), - { foo: 'bar' }, - 'duplicates: first' - ); - - t.deepEqual( - qs.parse('foo=bar&foo=baz', { duplicates: 'last' }), - { foo: 'baz' }, - 'duplicates: last' - ); - - t.test('bracket notation always combines regardless of duplicates', function (st) { - st.deepEqual( - qs.parse('a=1&a=2&b[]=1&b[]=2', { duplicates: 'last' }), - { a: '2', b: ['1', '2'] }, - 'duplicates last: unbracketed takes last, bracketed combines' - ); - - st.deepEqual( - qs.parse('b[]=1&b[]=2', { duplicates: 'last' }), - { b: ['1', '2'] }, - 'duplicates last: bracketed always combines' - ); - - st.deepEqual( - qs.parse('b[]=1&b[]=2', { duplicates: 'first' }), - { b: ['1', '2'] }, - 'duplicates first: bracketed always combines' - ); - - st.deepEqual( - qs.parse('a=1&a=2&b[]=1&b[]=2', { duplicates: 'first' }), - { a: '1', b: ['1', '2'] }, - 'duplicates first: unbracketed takes first, bracketed combines' - ); - - st.end(); - }); - - t.end(); -}); - -test('qs strictDepth option - throw cases', function (t) { - t.test('throws an exception when depth exceeds the limit with strictDepth: true', function (st) { - st['throws']( - function () { - qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1, strictDepth: true }); - }, - RangeError, - 'throws RangeError' - ); - st.end(); - }); - - t.test('throws an exception for multiple nested arrays with strictDepth: true', function (st) { - st['throws']( - function () { - qs.parse('a[0][1][2][3][4]=b', { depth: 3, strictDepth: true }); - }, - RangeError, - 'throws RangeError' - ); - st.end(); - }); - - t.test('throws an exception for nested objects and arrays with strictDepth: true', function (st) { - st['throws']( - function () { - qs.parse('a[b][c][0][d][e]=f', { depth: 3, strictDepth: true }); - }, - RangeError, - 'throws RangeError' - ); - st.end(); - }); - - t.test('throws an exception for different types of values with strictDepth: true', function (st) { - st['throws']( - function () { - qs.parse('a[b][c][d][e]=true&a[b][c][d][f]=42', { depth: 3, strictDepth: true }); - }, - RangeError, - 'throws RangeError' - ); - st.end(); - }); - -}); - -test('qs strictDepth option - non-throw cases', function (t) { - t.test('when depth is 0 and strictDepth true, do not throw', function (st) { - st.doesNotThrow( - function () { - qs.parse('a[b][c][d][e]=true&a[b][c][d][f]=42', { depth: 0, strictDepth: true }); - }, - RangeError, - 'does not throw RangeError' - ); - st.end(); - }); - - t.test('parses successfully when depth is within the limit with strictDepth: true', function (st) { - st.doesNotThrow( - function () { - var result = qs.parse('a[b]=c', { depth: 1, strictDepth: true }); - st.deepEqual(result, { a: { b: 'c' } }, 'parses correctly'); - } - ); - st.end(); - }); - - t.test('does not throw an exception when depth exceeds the limit with strictDepth: false', function (st) { - st.doesNotThrow( - function () { - var result = qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1 }); - st.deepEqual(result, { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } }, 'parses with depth limit'); - } - ); - st.end(); - }); - - t.test('parses successfully when depth is within the limit with strictDepth: false', function (st) { - st.doesNotThrow( - function () { - var result = qs.parse('a[b]=c', { depth: 1 }); - st.deepEqual(result, { a: { b: 'c' } }, 'parses correctly'); - } - ); - st.end(); - }); - - t.test('does not throw when depth is exactly at the limit with strictDepth: true', function (st) { - st.doesNotThrow( - function () { - var result = qs.parse('a[b][c]=d', { depth: 2, strictDepth: true }); - st.deepEqual(result, { a: { b: { c: 'd' } } }, 'parses correctly'); - } - ); - st.end(); - }); -}); - -test('DOS', function (t) { - var arr = []; - for (var i = 0; i < 105; i++) { - arr[arr.length] = 'x'; - } - var attack = 'a[]=' + arr.join('&a[]='); - var result = qs.parse(attack, { arrayLimit: 100 }); - - t.notOk(Array.isArray(result.a), 'arrayLimit is respected: result is an object, not an array'); - t.equal(Object.keys(result.a).length, 105, 'all values are preserved'); - - t.end(); -}); - -test('arrayLimit boundary conditions', function (t) { - // arrayLimit is the max number of elements allowed in an array - t.test('exactly at the limit stays as array', function (st) { - // 3 elements = limit of 3 - var result = qs.parse('a[]=1&a[]=2&a[]=3', { arrayLimit: 3 }); - st.ok(Array.isArray(result.a), 'result is an array when count equals limit'); - st.deepEqual(result.a, ['1', '2', '3'], 'all values present'); - st.end(); - }); - - t.test('one over the limit converts to object', function (st) { - // 4 elements exceeds limit of 3 - var result = qs.parse('a[]=1&a[]=2&a[]=3&a[]=4', { arrayLimit: 3 }); - st.notOk(Array.isArray(result.a), 'result is not an array when over limit'); - st.deepEqual(result.a, { 0: '1', 1: '2', 2: '3', 3: '4' }, 'all values preserved as object'); - st.end(); - }); - - t.test('arrayLimit 1 with one value', function (st) { - // 1 element = limit of 1 - var result = qs.parse('a[]=1', { arrayLimit: 1 }); - st.ok(Array.isArray(result.a), 'result is an array when count equals limit'); - st.deepEqual(result.a, ['1'], 'value preserved as array'); - st.end(); - }); - - t.test('arrayLimit 1 with two values converts to object', function (st) { - // 2 elements exceeds limit of 1 - var result = qs.parse('a[]=1&a[]=2', { arrayLimit: 1 }); - st.notOk(Array.isArray(result.a), 'result is not an array'); - st.deepEqual(result.a, { 0: '1', 1: '2' }, 'all values preserved as object'); - st.end(); - }); - - t.end(); -}); - -test('comma + arrayLimit', function (t) { - t.test('comma-separated values within arrayLimit stay as array', function (st) { - var result = qs.parse('a=1,2,3', { comma: true, arrayLimit: 5 }); - st.ok(Array.isArray(result.a), 'result is an array'); - st.deepEqual(result.a, ['1', '2', '3'], 'all values present'); - st.end(); - }); - - t.test('comma-separated values exceeding arrayLimit convert to object', function (st) { - var result = qs.parse('a=1,2,3,4', { comma: true, arrayLimit: 3 }); - st.notOk(Array.isArray(result.a), 'result is not an array when over limit'); - st.deepEqual(result.a, { 0: '1', 1: '2', 2: '3', 3: '4' }, 'all values preserved as object'); - st.end(); - }); - - t.test('comma-separated values exceeding arrayLimit with throwOnLimitExceeded throws', function (st) { - st['throws']( - function () { - qs.parse('a=1,2,3,4', { comma: true, arrayLimit: 3, throwOnLimitExceeded: true }); - }, - new RangeError('Array limit exceeded. Only 3 elements allowed in an array.'), - 'throws error when comma-split exceeds array limit' - ); - - st['throws']( - function () { - qs.parse('a=1,2,3', { comma: true, arrayLimit: 1, throwOnLimitExceeded: true }); - }, - new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), - 'throws error with singular "element" when arrayLimit is 1' - ); - st.end(); - }); - - t.test('comma-separated values at exactly arrayLimit stay as array', function (st) { - var result = qs.parse('a=1,2,3', { comma: true, arrayLimit: 3 }); - st.ok(Array.isArray(result.a), 'result is an array when exactly at limit'); - st.deepEqual(result.a, ['1', '2', '3'], 'all values present'); - st.end(); - }); - - t.end(); -}); - -test('mixed array and object notation', function (t) { - t.test('array brackets with object key - under limit', function (st) { - st.deepEqual( - qs.parse('a[]=b&a[c]=d'), - { a: { 0: 'b', c: 'd' } }, - 'mixing [] and [key] converts to object' - ); - st.end(); - }); - - t.test('array index with object key - under limit', function (st) { - st.deepEqual( - qs.parse('a[0]=b&a[c]=d'), - { a: { 0: 'b', c: 'd' } }, - 'mixing [0] and [key] produces object' - ); - st.end(); - }); - - t.test('plain value with array brackets - under limit', function (st) { - st.deepEqual( - qs.parse('a=b&a[]=c', { arrayLimit: 20 }), - { a: ['b', 'c'] }, - 'plain value combined with [] stays as array under limit' - ); - st.end(); - }); - - t.test('array brackets with plain value - under limit', function (st) { - st.deepEqual( - qs.parse('a[]=b&a=c', { arrayLimit: 20 }), - { a: ['b', 'c'] }, - '[] combined with plain value stays as array under limit' - ); - st.end(); - }); - - t.test('plain value with array index - under limit', function (st) { - st.deepEqual( - qs.parse('a=b&a[0]=c', { arrayLimit: 20 }), - { a: ['b', 'c'] }, - 'plain value combined with [0] stays as array under limit' - ); - st.end(); - }); - - t.test('multiple plain values with duplicates combine', function (st) { - st.deepEqual( - qs.parse('a=b&a=c&a=d', { arrayLimit: 20 }), - { a: ['b', 'c', 'd'] }, - 'duplicate plain keys combine into array' - ); - st.end(); - }); - - t.test('multiple plain values exceeding limit', function (st) { - // 3 elements (indices 0-2), max index 2 > limit 1 - st.deepEqual( - qs.parse('a=b&a=c&a=d', { arrayLimit: 1 }), - { a: { 0: 'b', 1: 'c', 2: 'd' } }, - 'duplicate plain keys convert to object when exceeding limit' - ); - st.end(); - }); - - t.test('mixed notation produces consistent results when arrayLimit is exceeded', function (st) { - var expected = { a: { 0: 'b', 1: 'c', 2: 'd' } }; - - st.deepEqual( - qs.parse('a[]=b&a[1]=c&a=d', { arrayLimit: -1 }), - expected, - 'arrayLimit -1' - ); - - st.deepEqual( - qs.parse('a[]=b&a[1]=c&a=d', { arrayLimit: 0 }), - expected, - 'arrayLimit 0' - ); - - st.deepEqual( - qs.parse('a[]=b&a[1]=c&a=d', { arrayLimit: 1 }), - expected, - 'arrayLimit 1' - ); - - st.end(); - }); - - t.test('uses existing array length for currentArrayLength when parsing object input with bracket keys', function (st) { - var input = {}; - var arr = ['x', 'y']; - arr.a = ['z', 'w']; - input['a[]'] = arr; - st.deepEqual(qs.parse(input), { a: ['x', 'y'] }, 'parses object input with bracket keys using existing array values'); - st.end(); - }); - - t.test('throws with singular message when object input bracket key exceeds arrayLimit of 1', function (st) { - var input = {}; - var arr = ['x']; - arr.a = ['z', 'w']; - input['a[]'] = arr; - st['throws']( - function () { - qs.parse(input, { throwOnLimitExceeded: true, arrayLimit: 1 }); - }, - new RangeError('Array limit exceeded. Only 1 element allowed in an array.'), - 'throws singular error for object input exceeding arrayLimit 1' - ); - st.end(); - }); - - t.end(); -}); diff --git a/node_modules/body-parser/node_modules/qs/test/stringify.js b/node_modules/body-parser/node_modules/qs/test/stringify.js deleted file mode 100644 index 1c1efbc..0000000 --- a/node_modules/body-parser/node_modules/qs/test/stringify.js +++ /dev/null @@ -1,1319 +0,0 @@ -'use strict'; - -var test = require('tape'); -var qs = require('../'); -var utils = require('../lib/utils'); -var iconv = require('iconv-lite'); -var SaferBuffer = require('safer-buffer').Buffer; -var hasSymbols = require('has-symbols'); -var mockProperty = require('mock-property'); -var emptyTestCases = require('./empty-keys-cases').emptyTestCases; -var hasProto = require('has-proto')(); -var hasBigInt = require('has-bigints')(); - -test('stringify()', function (t) { - t.test('stringifies a querystring object', function (st) { - st.equal(qs.stringify({ a: 'b' }), 'a=b'); - st.equal(qs.stringify({ a: 1 }), 'a=1'); - st.equal(qs.stringify({ a: 1, b: 2 }), 'a=1&b=2'); - st.equal(qs.stringify({ a: 'A_Z' }), 'a=A_Z'); - st.equal(qs.stringify({ a: '€' }), 'a=%E2%82%AC'); - st.equal(qs.stringify({ a: '' }), 'a=%EE%80%80'); - st.equal(qs.stringify({ a: 'א' }), 'a=%D7%90'); - st.equal(qs.stringify({ a: '𐐷' }), 'a=%F0%90%90%B7'); - st.end(); - }); - - t.test('stringifies falsy values', function (st) { - st.equal(qs.stringify(undefined), ''); - st.equal(qs.stringify(null), ''); - st.equal(qs.stringify(null, { strictNullHandling: true }), ''); - st.equal(qs.stringify(false), ''); - st.equal(qs.stringify(0), ''); - st.end(); - }); - - t.test('stringifies symbols', { skip: !hasSymbols() }, function (st) { - st.equal(qs.stringify(Symbol.iterator), ''); - st.equal(qs.stringify([Symbol.iterator]), '0=Symbol%28Symbol.iterator%29'); - st.equal(qs.stringify({ a: Symbol.iterator }), 'a=Symbol%28Symbol.iterator%29'); - st.equal( - qs.stringify({ a: [Symbol.iterator] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), - 'a[]=Symbol%28Symbol.iterator%29' - ); - st.end(); - }); - - t.test('stringifies bigints', { skip: !hasBigInt }, function (st) { - var three = BigInt(3); - var encodeWithN = function (value, defaultEncoder, charset) { - var result = defaultEncoder(value, defaultEncoder, charset); - return typeof value === 'bigint' ? result + 'n' : result; - }; - st.equal(qs.stringify(three), ''); - st.equal(qs.stringify([three]), '0=3'); - st.equal(qs.stringify([three], { encoder: encodeWithN }), '0=3n'); - st.equal(qs.stringify({ a: three }), 'a=3'); - st.equal(qs.stringify({ a: three }, { encoder: encodeWithN }), 'a=3n'); - st.equal( - qs.stringify({ a: [three] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), - 'a[]=3' - ); - st.equal( - qs.stringify({ a: [three] }, { encodeValuesOnly: true, encoder: encodeWithN, arrayFormat: 'brackets' }), - 'a[]=3n' - ); - st.end(); - }); - - t.test('encodes dot in key of object when encodeDotInKeys and allowDots is provided', function (st) { - st.equal( - qs.stringify( - { 'name.obj': { first: 'John', last: 'Doe' } }, - { allowDots: false, encodeDotInKeys: false } - ), - 'name.obj%5Bfirst%5D=John&name.obj%5Blast%5D=Doe', - 'with allowDots false and encodeDotInKeys false' - ); - st.equal( - qs.stringify( - { 'name.obj': { first: 'John', last: 'Doe' } }, - { allowDots: true, encodeDotInKeys: false } - ), - 'name.obj.first=John&name.obj.last=Doe', - 'with allowDots true and encodeDotInKeys false' - ); - st.equal( - qs.stringify( - { 'name.obj': { first: 'John', last: 'Doe' } }, - { allowDots: false, encodeDotInKeys: true } - ), - 'name%252Eobj%5Bfirst%5D=John&name%252Eobj%5Blast%5D=Doe', - 'with allowDots false and encodeDotInKeys true' - ); - st.equal( - qs.stringify( - { 'name.obj': { first: 'John', last: 'Doe' } }, - { allowDots: true, encodeDotInKeys: true } - ), - 'name%252Eobj.first=John&name%252Eobj.last=Doe', - 'with allowDots true and encodeDotInKeys true' - ); - - st.equal( - qs.stringify( - { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, - { allowDots: false, encodeDotInKeys: false } - ), - 'name.obj.subobject%5Bfirst.godly.name%5D=John&name.obj.subobject%5Blast%5D=Doe', - 'with allowDots false and encodeDotInKeys false' - ); - st.equal( - qs.stringify( - { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, - { allowDots: true, encodeDotInKeys: false } - ), - 'name.obj.subobject.first.godly.name=John&name.obj.subobject.last=Doe', - 'with allowDots false and encodeDotInKeys false' - ); - st.equal( - qs.stringify( - { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, - { allowDots: false, encodeDotInKeys: true } - ), - 'name%252Eobj%252Esubobject%5Bfirst.godly.name%5D=John&name%252Eobj%252Esubobject%5Blast%5D=Doe', - 'with allowDots false and encodeDotInKeys true' - ); - st.equal( - qs.stringify( - { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, - { allowDots: true, encodeDotInKeys: true } - ), - 'name%252Eobj%252Esubobject.first%252Egodly%252Ename=John&name%252Eobj%252Esubobject.last=Doe', - 'with allowDots true and encodeDotInKeys true' - ); - - st.end(); - }); - - t.test('should encode dot in key of object, and automatically set allowDots to `true` when encodeDotInKeys is true and allowDots in undefined', function (st) { - st.equal( - qs.stringify( - { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, - { encodeDotInKeys: true } - ), - 'name%252Eobj%252Esubobject.first%252Egodly%252Ename=John&name%252Eobj%252Esubobject.last=Doe', - 'with allowDots undefined and encodeDotInKeys true' - ); - st.end(); - }); - - t.test('should encode dot in key of object when encodeDotInKeys and allowDots is provided, and nothing else when encodeValuesOnly is provided', function (st) { - st.equal( - qs.stringify({ 'name.obj': { first: 'John', last: 'Doe' } }, { - encodeDotInKeys: true, allowDots: true, encodeValuesOnly: true - }), - 'name%2Eobj.first=John&name%2Eobj.last=Doe' - ); - - st.equal( - qs.stringify({ 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, { allowDots: true, encodeDotInKeys: true, encodeValuesOnly: true }), - 'name%2Eobj%2Esubobject.first%2Egodly%2Ename=John&name%2Eobj%2Esubobject.last=Doe' - ); - - st.end(); - }); - - t.test('throws when `commaRoundTrip` is not a boolean', function (st) { - st['throws']( - function () { qs.stringify({}, { commaRoundTrip: 'not a boolean' }); }, - TypeError, - 'throws when `commaRoundTrip` is not a boolean' - ); - - st.end(); - }); - - t.test('throws when `encodeDotInKeys` is not a boolean', function (st) { - st['throws']( - function () { qs.stringify({ a: [], b: 'zz' }, { encodeDotInKeys: 'foobar' }); }, - TypeError - ); - - st['throws']( - function () { qs.stringify({ a: [], b: 'zz' }, { encodeDotInKeys: 0 }); }, - TypeError - ); - - st['throws']( - function () { qs.stringify({ a: [], b: 'zz' }, { encodeDotInKeys: NaN }); }, - TypeError - ); - - st['throws']( - function () { qs.stringify({ a: [], b: 'zz' }, { encodeDotInKeys: null }); }, - TypeError - ); - - st.end(); - }); - - t.test('adds query prefix', function (st) { - st.equal(qs.stringify({ a: 'b' }, { addQueryPrefix: true }), '?a=b'); - st.end(); - }); - - t.test('with query prefix, outputs blank string given an empty object', function (st) { - st.equal(qs.stringify({}, { addQueryPrefix: true }), ''); - st.end(); - }); - - t.test('stringifies nested falsy values', function (st) { - st.equal(qs.stringify({ a: { b: { c: null } } }), 'a%5Bb%5D%5Bc%5D='); - st.equal(qs.stringify({ a: { b: { c: null } } }, { strictNullHandling: true }), 'a%5Bb%5D%5Bc%5D'); - st.equal(qs.stringify({ a: { b: { c: false } } }), 'a%5Bb%5D%5Bc%5D=false'); - st.end(); - }); - - t.test('stringifies a nested object', function (st) { - st.equal(qs.stringify({ a: { b: 'c' } }), 'a%5Bb%5D=c'); - st.equal(qs.stringify({ a: { b: { c: { d: 'e' } } } }), 'a%5Bb%5D%5Bc%5D%5Bd%5D=e'); - st.end(); - }); - - t.test('`allowDots` option: stringifies a nested object with dots notation', function (st) { - st.equal(qs.stringify({ a: { b: 'c' } }, { allowDots: true }), 'a.b=c'); - st.equal(qs.stringify({ a: { b: { c: { d: 'e' } } } }, { allowDots: true }), 'a.b.c.d=e'); - st.end(); - }); - - t.test('stringifies an array value', function (st) { - st.equal( - qs.stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'indices' }), - 'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d', - 'indices => indices' - ); - st.equal( - qs.stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'brackets' }), - 'a%5B%5D=b&a%5B%5D=c&a%5B%5D=d', - 'brackets => brackets' - ); - st.equal( - qs.stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'comma' }), - 'a=b%2Cc%2Cd', - 'comma => comma' - ); - st.equal( - qs.stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'comma', commaRoundTrip: true }), - 'a=b%2Cc%2Cd', - 'comma round trip => comma' - ); - st.equal( - qs.stringify({ a: ['b', 'c', 'd'] }), - 'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d', - 'default => indices' - ); - st.end(); - }); - - t.test('`skipNulls` option', function (st) { - st.equal( - qs.stringify({ a: 'b', c: null }, { skipNulls: true }), - 'a=b', - 'omits nulls when asked' - ); - - st.equal( - qs.stringify({ a: { b: 'c', d: null } }, { skipNulls: true }), - 'a%5Bb%5D=c', - 'omits nested nulls when asked' - ); - - st.end(); - }); - - t.test('omits array indices when asked', function (st) { - st.equal(qs.stringify({ a: ['b', 'c', 'd'] }, { indices: false }), 'a=b&a=c&a=d'); - - st.end(); - }); - - t.test('omits object key/value pair when value is empty array', function (st) { - st.equal(qs.stringify({ a: [], b: 'zz' }), 'b=zz'); - - st.end(); - }); - - t.test('should not omit object key/value pair when value is empty array and when asked', function (st) { - st.equal(qs.stringify({ a: [], b: 'zz' }), 'b=zz'); - st.equal(qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: false }), 'b=zz'); - st.equal(qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: true }), 'a[]&b=zz'); - - st.end(); - }); - - t.test('should throw when allowEmptyArrays is not of type boolean', function (st) { - st['throws']( - function () { qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: 'foobar' }); }, - TypeError - ); - - st['throws']( - function () { qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: 0 }); }, - TypeError - ); - - st['throws']( - function () { qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: NaN }); }, - TypeError - ); - - st['throws']( - function () { qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: null }); }, - TypeError - ); - - st.end(); - }); - - t.test('allowEmptyArrays + strictNullHandling', function (st) { - st.equal( - qs.stringify( - { testEmptyArray: [] }, - { strictNullHandling: true, allowEmptyArrays: true } - ), - 'testEmptyArray[]' - ); - - st.end(); - }); - - t.test('stringifies an array value with one item vs multiple items', function (st) { - st.test('non-array item', function (s2t) { - s2t.equal(qs.stringify({ a: 'c' }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a=c'); - s2t.equal(qs.stringify({ a: 'c' }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a=c'); - s2t.equal(qs.stringify({ a: 'c' }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=c'); - s2t.equal(qs.stringify({ a: 'c' }, { encodeValuesOnly: true }), 'a=c'); - - s2t.end(); - }); - - st.test('array with a single item', function (s2t) { - s2t.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[0]=c'); - s2t.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=c'); - s2t.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=c'); - s2t.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'comma', commaRoundTrip: true }), 'a[]=c'); // so it parses back as an array - s2t.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true }), 'a[0]=c'); - - s2t.end(); - }); - - st.test('array with multiple items', function (s2t) { - s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[0]=c&a[1]=d'); - s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=c&a[]=d'); - s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=c,d'); - s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'comma', commaRoundTrip: true }), 'a=c,d'); - s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true }), 'a[0]=c&a[1]=d'); - - s2t.end(); - }); - - st.test('array with multiple items with a comma inside', function (s2t) { - s2t.equal(qs.stringify({ a: ['c,d', 'e'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=c%2Cd,e'); - s2t.equal(qs.stringify({ a: ['c,d', 'e'] }, { arrayFormat: 'comma' }), 'a=c%2Cd%2Ce'); - - s2t.equal(qs.stringify({ a: ['c,d', 'e'] }, { encodeValuesOnly: true, arrayFormat: 'comma', commaRoundTrip: true }), 'a=c%2Cd,e'); - s2t.equal(qs.stringify({ a: ['c,d', 'e'] }, { arrayFormat: 'comma', commaRoundTrip: true }), 'a=c%2Cd%2Ce'); - - s2t.end(); - }); - - st.end(); - }); - - t.test('stringifies a nested array value', function (st) { - st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[b][0]=c&a[b][1]=d'); - st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[b][]=c&a[b][]=d'); - st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a[b]=c,d'); - st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true }), 'a[b][0]=c&a[b][1]=d'); - st.end(); - }); - - t.test('stringifies comma and empty array values', function (st) { - st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: false, arrayFormat: 'indices' }), 'a[0]=,&a[1]=&a[2]=c,d%'); - st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: false, arrayFormat: 'brackets' }), 'a[]=,&a[]=&a[]=c,d%'); - st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: false, arrayFormat: 'comma' }), 'a=,,,c,d%'); - st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: false, arrayFormat: 'repeat' }), 'a=,&a=&a=c,d%'); - - st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[0]=%2C&a[1]=&a[2]=c%2Cd%25'); - st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=%2C&a[]=&a[]=c%2Cd%25'); - st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=%2C,,c%2Cd%25'); - st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: true, arrayFormat: 'repeat' }), 'a=%2C&a=&a=c%2Cd%25'); - - st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: false, arrayFormat: 'indices' }), 'a%5B0%5D=%2C&a%5B1%5D=&a%5B2%5D=c%2Cd%25'); - st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: false, arrayFormat: 'brackets' }), 'a%5B%5D=%2C&a%5B%5D=&a%5B%5D=c%2Cd%25'); - st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: false, arrayFormat: 'comma' }), 'a=%2C%2C%2Cc%2Cd%25'); - st.equal(qs.stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: false, arrayFormat: 'repeat' }), 'a=%2C&a=&a=c%2Cd%25'); - - st.end(); - }); - - t.test('stringifies comma and empty non-array values', function (st) { - st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: false, arrayFormat: 'indices' }), 'a=,&b=&c=c,d%'); - st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: false, arrayFormat: 'brackets' }), 'a=,&b=&c=c,d%'); - st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: false, arrayFormat: 'comma' }), 'a=,&b=&c=c,d%'); - st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: false, arrayFormat: 'repeat' }), 'a=,&b=&c=c,d%'); - - st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: true, encodeValuesOnly: true, arrayFormat: 'indices' }), 'a=%2C&b=&c=c%2Cd%25'); - st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: true, encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a=%2C&b=&c=c%2Cd%25'); - st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: true, encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=%2C&b=&c=c%2Cd%25'); - st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: true, encodeValuesOnly: true, arrayFormat: 'repeat' }), 'a=%2C&b=&c=c%2Cd%25'); - - st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: true, encodeValuesOnly: false, arrayFormat: 'indices' }), 'a=%2C&b=&c=c%2Cd%25'); - st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: true, encodeValuesOnly: false, arrayFormat: 'brackets' }), 'a=%2C&b=&c=c%2Cd%25'); - st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: true, encodeValuesOnly: false, arrayFormat: 'comma' }), 'a=%2C&b=&c=c%2Cd%25'); - st.equal(qs.stringify({ a: ',', b: '', c: 'c,d%' }, { encode: true, encodeValuesOnly: false, arrayFormat: 'repeat' }), 'a=%2C&b=&c=c%2Cd%25'); - - st.end(); - }); - - t.test('stringifies a nested array value with dots notation', function (st) { - st.equal( - qs.stringify( - { a: { b: ['c', 'd'] } }, - { allowDots: true, encodeValuesOnly: true, arrayFormat: 'indices' } - ), - 'a.b[0]=c&a.b[1]=d', - 'indices: stringifies with dots + indices' - ); - st.equal( - qs.stringify( - { a: { b: ['c', 'd'] } }, - { allowDots: true, encodeValuesOnly: true, arrayFormat: 'brackets' } - ), - 'a.b[]=c&a.b[]=d', - 'brackets: stringifies with dots + brackets' - ); - st.equal( - qs.stringify( - { a: { b: ['c', 'd'] } }, - { allowDots: true, encodeValuesOnly: true, arrayFormat: 'comma' } - ), - 'a.b=c,d', - 'comma: stringifies with dots + comma' - ); - st.equal( - qs.stringify( - { a: { b: ['c', 'd'] } }, - { allowDots: true, encodeValuesOnly: true } - ), - 'a.b[0]=c&a.b[1]=d', - 'default: stringifies with dots + indices' - ); - st.end(); - }); - - t.test('stringifies an object inside an array', function (st) { - st.equal( - qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'indices', encodeValuesOnly: true }), - 'a[0][b]=c', - 'indices => indices' - ); - st.equal( - qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'repeat', encodeValuesOnly: true }), - 'a[b]=c', - 'repeat => repeat' - ); - st.equal( - qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'brackets', encodeValuesOnly: true }), - 'a[][b]=c', - 'brackets => brackets' - ); - st.equal( - qs.stringify({ a: [{ b: 'c' }] }, { encodeValuesOnly: true }), - 'a[0][b]=c', - 'default => indices' - ); - - st.equal( - qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'indices', encodeValuesOnly: true }), - 'a[0][b][c][0]=1', - 'indices => indices' - ); - st.equal( - qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'repeat', encodeValuesOnly: true }), - 'a[b][c]=1', - 'repeat => repeat' - ); - st.equal( - qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'brackets', encodeValuesOnly: true }), - 'a[][b][c][]=1', - 'brackets => brackets' - ); - st.equal( - qs.stringify({ a: [{ b: { c: [1] } }] }, { encodeValuesOnly: true }), - 'a[0][b][c][0]=1', - 'default => indices' - ); - - st.end(); - }); - - t.test('stringifies an array with mixed objects and primitives', function (st) { - st.equal( - qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), - 'a[0][b]=1&a[1]=2&a[2]=3', - 'indices => indices' - ); - st.equal( - qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), - 'a[][b]=1&a[]=2&a[]=3', - 'brackets => brackets' - ); - st.equal( - qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), - '???', - 'brackets => brackets', - { skip: 'TODO: figure out what this should do' } - ); - st.equal( - qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true }), - 'a[0][b]=1&a[1]=2&a[2]=3', - 'default => indices' - ); - - st.end(); - }); - - t.test('stringifies an object inside an array with dots notation', function (st) { - st.equal( - qs.stringify( - { a: [{ b: 'c' }] }, - { allowDots: true, encode: false, arrayFormat: 'indices' } - ), - 'a[0].b=c', - 'indices => indices' - ); - st.equal( - qs.stringify( - { a: [{ b: 'c' }] }, - { allowDots: true, encode: false, arrayFormat: 'brackets' } - ), - 'a[].b=c', - 'brackets => brackets' - ); - st.equal( - qs.stringify( - { a: [{ b: 'c' }] }, - { allowDots: true, encode: false } - ), - 'a[0].b=c', - 'default => indices' - ); - - st.equal( - qs.stringify( - { a: [{ b: { c: [1] } }] }, - { allowDots: true, encode: false, arrayFormat: 'indices' } - ), - 'a[0].b.c[0]=1', - 'indices => indices' - ); - st.equal( - qs.stringify( - { a: [{ b: { c: [1] } }] }, - { allowDots: true, encode: false, arrayFormat: 'brackets' } - ), - 'a[].b.c[]=1', - 'brackets => brackets' - ); - st.equal( - qs.stringify( - { a: [{ b: { c: [1] } }] }, - { allowDots: true, encode: false } - ), - 'a[0].b.c[0]=1', - 'default => indices' - ); - - st.end(); - }); - - t.test('does not omit object keys when indices = false', function (st) { - st.equal(qs.stringify({ a: [{ b: 'c' }] }, { indices: false }), 'a%5Bb%5D=c'); - st.end(); - }); - - t.test('uses indices notation for arrays when indices=true', function (st) { - st.equal(qs.stringify({ a: ['b', 'c'] }, { indices: true }), 'a%5B0%5D=b&a%5B1%5D=c'); - st.end(); - }); - - t.test('uses indices notation for arrays when no arrayFormat is specified', function (st) { - st.equal(qs.stringify({ a: ['b', 'c'] }), 'a%5B0%5D=b&a%5B1%5D=c'); - st.end(); - }); - - t.test('uses indices notation for arrays when arrayFormat=indices', function (st) { - st.equal(qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' }), 'a%5B0%5D=b&a%5B1%5D=c'); - st.end(); - }); - - t.test('uses repeat notation for arrays when arrayFormat=repeat', function (st) { - st.equal(qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' }), 'a=b&a=c'); - st.end(); - }); - - t.test('uses brackets notation for arrays when arrayFormat=brackets', function (st) { - st.equal(qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' }), 'a%5B%5D=b&a%5B%5D=c'); - st.end(); - }); - - t.test('stringifies a complicated object', function (st) { - st.equal(qs.stringify({ a: { b: 'c', d: 'e' } }), 'a%5Bb%5D=c&a%5Bd%5D=e'); - st.end(); - }); - - t.test('stringifies an empty value', function (st) { - st.equal(qs.stringify({ a: '' }), 'a='); - st.equal(qs.stringify({ a: null }, { strictNullHandling: true }), 'a'); - - st.equal(qs.stringify({ a: '', b: '' }), 'a=&b='); - st.equal(qs.stringify({ a: null, b: '' }, { strictNullHandling: true }), 'a&b='); - - st.equal(qs.stringify({ a: { b: '' } }), 'a%5Bb%5D='); - st.equal(qs.stringify({ a: { b: null } }, { strictNullHandling: true }), 'a%5Bb%5D'); - st.equal(qs.stringify({ a: { b: null } }, { strictNullHandling: false }), 'a%5Bb%5D='); - - st.end(); - }); - - t.test('stringifies an empty array in different arrayFormat', function (st) { - st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false }), 'b[0]=&c=c'); - // arrayFormat default - st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'indices' }), 'b[0]=&c=c'); - st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'brackets' }), 'b[]=&c=c'); - st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'repeat' }), 'b=&c=c'); - st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'comma' }), 'b=&c=c'); - st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'comma', commaRoundTrip: true }), 'b[]=&c=c'); - // with strictNullHandling - st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'indices', strictNullHandling: true }), 'b[0]&c=c'); - st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'brackets', strictNullHandling: true }), 'b[]&c=c'); - st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'repeat', strictNullHandling: true }), 'b&c=c'); - st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'comma', strictNullHandling: true }), 'b&c=c'); - st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'comma', strictNullHandling: true, commaRoundTrip: true }), 'b[]&c=c'); - // with skipNulls - st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'indices', skipNulls: true }), 'c=c'); - st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'brackets', skipNulls: true }), 'c=c'); - st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'repeat', skipNulls: true }), 'c=c'); - st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'comma', skipNulls: true }), 'c=c'); - - st.end(); - }); - - t.test('stringifies a null object', { skip: !hasProto }, function (st) { - st.equal(qs.stringify({ __proto__: null, a: 'b' }), 'a=b'); - st.end(); - }); - - t.test('returns an empty string for invalid input', function (st) { - st.equal(qs.stringify(undefined), ''); - st.equal(qs.stringify(false), ''); - st.equal(qs.stringify(null), ''); - st.equal(qs.stringify(''), ''); - st.end(); - }); - - t.test('stringifies an object with a null object as a child', { skip: !hasProto }, function (st) { - st.equal(qs.stringify({ a: { __proto__: null, b: 'c' } }), 'a%5Bb%5D=c'); - st.end(); - }); - - t.test('drops keys with a value of undefined', function (st) { - st.equal(qs.stringify({ a: undefined }), ''); - - st.equal(qs.stringify({ a: { b: undefined, c: null } }, { strictNullHandling: true }), 'a%5Bc%5D'); - st.equal(qs.stringify({ a: { b: undefined, c: null } }, { strictNullHandling: false }), 'a%5Bc%5D='); - st.equal(qs.stringify({ a: { b: undefined, c: '' } }), 'a%5Bc%5D='); - st.end(); - }); - - t.test('url encodes values', function (st) { - st.equal(qs.stringify({ a: 'b c' }), 'a=b%20c'); - st.end(); - }); - - t.test('stringifies a date', function (st) { - var now = new Date(); - var str = 'a=' + encodeURIComponent(now.toISOString()); - st.equal(qs.stringify({ a: now }), str); - st.end(); - }); - - t.test('stringifies the weird object from qs', function (st) { - st.equal(qs.stringify({ 'my weird field': '~q1!2"\'w$5&7/z8)?' }), 'my%20weird%20field=~q1%212%22%27w%245%267%2Fz8%29%3F'); - st.end(); - }); - - t.test('skips properties that are part of the object prototype', function (st) { - st.intercept(Object.prototype, 'crash', { value: 'test' }); - - st.equal(qs.stringify({ a: 'b' }), 'a=b'); - st.equal(qs.stringify({ a: { b: 'c' } }), 'a%5Bb%5D=c'); - - st.end(); - }); - - t.test('stringifies boolean values', function (st) { - st.equal(qs.stringify({ a: true }), 'a=true'); - st.equal(qs.stringify({ a: { b: true } }), 'a%5Bb%5D=true'); - st.equal(qs.stringify({ b: false }), 'b=false'); - st.equal(qs.stringify({ b: { c: false } }), 'b%5Bc%5D=false'); - st.end(); - }); - - t.test('stringifies buffer values', function (st) { - st.equal(qs.stringify({ a: SaferBuffer.from('test') }), 'a=test'); - st.equal(qs.stringify({ a: { b: SaferBuffer.from('test') } }), 'a%5Bb%5D=test'); - st.end(); - }); - - t.test('stringifies an object using an alternative delimiter', function (st) { - st.equal(qs.stringify({ a: 'b', c: 'd' }, { delimiter: ';' }), 'a=b;c=d'); - st.end(); - }); - - t.test('does not blow up when Buffer global is missing', function (st) { - var restore = mockProperty(global, 'Buffer', { 'delete': true }); - - var result = qs.stringify({ a: 'b', c: 'd' }); - - restore(); - - st.equal(result, 'a=b&c=d'); - st.end(); - }); - - t.test('does not crash when parsing circular references', function (st) { - var a = {}; - a.b = a; - - st['throws']( - function () { qs.stringify({ 'foo[bar]': 'baz', 'foo[baz]': a }); }, - /RangeError: Cyclic object value/, - 'cyclic values throw' - ); - - var circular = { - a: 'value' - }; - circular.a = circular; - st['throws']( - function () { qs.stringify(circular); }, - /RangeError: Cyclic object value/, - 'cyclic values throw' - ); - - var arr = ['a']; - st.doesNotThrow( - function () { qs.stringify({ x: arr, y: arr }); }, - 'non-cyclic values do not throw' - ); - - st.end(); - }); - - t.test('non-circular duplicated references can still work', function (st) { - var hourOfDay = { - 'function': 'hour_of_day' - }; - - var p1 = { - 'function': 'gte', - arguments: [hourOfDay, 0] - }; - var p2 = { - 'function': 'lte', - arguments: [hourOfDay, 23] - }; - - st.equal( - qs.stringify({ filters: { $and: [p1, p2] } }, { encodeValuesOnly: true, arrayFormat: 'indices' }), - 'filters[$and][0][function]=gte&filters[$and][0][arguments][0][function]=hour_of_day&filters[$and][0][arguments][1]=0&filters[$and][1][function]=lte&filters[$and][1][arguments][0][function]=hour_of_day&filters[$and][1][arguments][1]=23' - ); - st.equal( - qs.stringify({ filters: { $and: [p1, p2] } }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), - 'filters[$and][][function]=gte&filters[$and][][arguments][][function]=hour_of_day&filters[$and][][arguments][]=0&filters[$and][][function]=lte&filters[$and][][arguments][][function]=hour_of_day&filters[$and][][arguments][]=23' - ); - st.equal( - qs.stringify({ filters: { $and: [p1, p2] } }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), - 'filters[$and][function]=gte&filters[$and][arguments][function]=hour_of_day&filters[$and][arguments]=0&filters[$and][function]=lte&filters[$and][arguments][function]=hour_of_day&filters[$and][arguments]=23' - ); - - st.end(); - }); - - t.test('selects properties when filter=array', function (st) { - st.equal(qs.stringify({ a: 'b' }, { filter: ['a'] }), 'a=b'); - st.equal(qs.stringify({ a: 1 }, { filter: [] }), ''); - - st.equal( - qs.stringify( - { a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' }, - { filter: ['a', 'b', 0, 2], arrayFormat: 'indices' } - ), - 'a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3', - 'indices => indices' - ); - st.equal( - qs.stringify( - { a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' }, - { filter: ['a', 'b', 0, 2], arrayFormat: 'brackets' } - ), - 'a%5Bb%5D%5B%5D=1&a%5Bb%5D%5B%5D=3', - 'brackets => brackets' - ); - st.equal( - qs.stringify( - { a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' }, - { filter: ['a', 'b', 0, 2] } - ), - 'a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3', - 'default => indices' - ); - - st.end(); - }); - - t.test('supports custom representations when filter=function', function (st) { - var calls = 0; - var obj = { a: 'b', c: 'd', e: { f: new Date(1257894000000) } }; - var filterFunc = function (prefix, value) { - calls += 1; - if (calls === 1) { - st.equal(prefix, '', 'prefix is empty'); - st.equal(value, obj); - } else if (prefix === 'c') { - return void 0; - } else if (value instanceof Date) { - st.equal(prefix, 'e[f]'); - return value.getTime(); - } - return value; - }; - - st.equal(qs.stringify(obj, { filter: filterFunc }), 'a=b&e%5Bf%5D=1257894000000'); - st.equal(calls, 5); - st.end(); - }); - - t.test('can disable uri encoding', function (st) { - st.equal(qs.stringify({ a: 'b' }, { encode: false }), 'a=b'); - st.equal(qs.stringify({ a: { b: 'c' } }, { encode: false }), 'a[b]=c'); - st.equal(qs.stringify({ a: 'b', c: null }, { strictNullHandling: true, encode: false }), 'a=b&c'); - st.end(); - }); - - t.test('can sort the keys', function (st) { - var sort = function (a, b) { - return a.localeCompare(b); - }; - st.equal(qs.stringify({ a: 'c', z: 'y', b: 'f' }, { sort: sort }), 'a=c&b=f&z=y'); - st.equal(qs.stringify({ a: 'c', z: { j: 'a', i: 'b' }, b: 'f' }, { sort: sort }), 'a=c&b=f&z%5Bi%5D=b&z%5Bj%5D=a'); - st.end(); - }); - - t.test('can sort the keys at depth 3 or more too', function (st) { - var sort = function (a, b) { - return a.localeCompare(b); - }; - st.equal( - qs.stringify( - { a: 'a', z: { zj: { zjb: 'zjb', zja: 'zja' }, zi: { zib: 'zib', zia: 'zia' } }, b: 'b' }, - { sort: sort, encode: false } - ), - 'a=a&b=b&z[zi][zia]=zia&z[zi][zib]=zib&z[zj][zja]=zja&z[zj][zjb]=zjb' - ); - st.equal( - qs.stringify( - { a: 'a', z: { zj: { zjb: 'zjb', zja: 'zja' }, zi: { zib: 'zib', zia: 'zia' } }, b: 'b' }, - { sort: null, encode: false } - ), - 'a=a&z[zj][zjb]=zjb&z[zj][zja]=zja&z[zi][zib]=zib&z[zi][zia]=zia&b=b' - ); - st.end(); - }); - - t.test('can stringify with custom encoding', function (st) { - st.equal(qs.stringify({ 県: '大阪府', '': '' }, { - encoder: function (str) { - if (str.length === 0) { - return ''; - } - var buf = iconv.encode(str, 'shiftjis'); - var result = []; - for (var i = 0; i < buf.length; ++i) { - result.push(buf.readUInt8(i).toString(16)); - } - return '%' + result.join('%'); - } - }), '%8c%a7=%91%e5%8d%e3%95%7b&='); - st.end(); - }); - - t.test('receives the default encoder as a second argument', function (st) { - st.plan(8); - - qs.stringify({ a: 1, b: new Date(), c: true, d: [1] }, { - encoder: function (str) { - st.match(typeof str, /^(?:string|number|boolean)$/); - return ''; - } - }); - - st.end(); - }); - - t.test('receives the default encoder as a second argument', function (st) { - st.plan(2); - - qs.stringify({ a: 1 }, { - encoder: function (str, defaultEncoder) { - st.equal(defaultEncoder, utils.encode); - } - }); - - st.end(); - }); - - t.test('throws error with wrong encoder', function (st) { - st['throws'](function () { - qs.stringify({}, { encoder: 'string' }); - }, new TypeError('Encoder has to be a function.')); - st.end(); - }); - - t.test('can use custom encoder for a buffer object', { skip: typeof Buffer === 'undefined' }, function (st) { - st.equal(qs.stringify({ a: SaferBuffer.from([1]) }, { - encoder: function (buffer) { - if (typeof buffer === 'string') { - return buffer; - } - return String.fromCharCode(buffer.readUInt8(0) + 97); - } - }), 'a=b'); - - st.equal(qs.stringify({ a: SaferBuffer.from('a b') }, { - encoder: function (buffer) { - return buffer; - } - }), 'a=a b'); - st.end(); - }); - - t.test('serializeDate option', function (st) { - var date = new Date(); - st.equal( - qs.stringify({ a: date }), - 'a=' + date.toISOString().replace(/:/g, '%3A'), - 'default is toISOString' - ); - - var mutatedDate = new Date(); - mutatedDate.toISOString = function () { - throw new SyntaxError(); - }; - st['throws'](function () { - mutatedDate.toISOString(); - }, SyntaxError); - st.equal( - qs.stringify({ a: mutatedDate }), - 'a=' + Date.prototype.toISOString.call(mutatedDate).replace(/:/g, '%3A'), - 'toISOString works even when method is not locally present' - ); - - var specificDate = new Date(6); - st.equal( - qs.stringify( - { a: specificDate }, - { serializeDate: function (d) { return d.getTime() * 7; } } - ), - 'a=42', - 'custom serializeDate function called' - ); - - st.equal( - qs.stringify( - { a: [date] }, - { - serializeDate: function (d) { return d.getTime(); }, - arrayFormat: 'comma' - } - ), - 'a=' + date.getTime(), - 'works with arrayFormat comma' - ); - st.equal( - qs.stringify( - { a: [date] }, - { - serializeDate: function (d) { return d.getTime(); }, - arrayFormat: 'comma', - commaRoundTrip: true - } - ), - 'a%5B%5D=' + date.getTime(), - 'works with arrayFormat comma' - ); - - st.end(); - }); - - t.test('RFC 1738 serialization', function (st) { - st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC1738 }), 'a=b+c'); - st.equal(qs.stringify({ 'a b': 'c d' }, { format: qs.formats.RFC1738 }), 'a+b=c+d'); - st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }, { format: qs.formats.RFC1738 }), 'a+b=a+b'); - - st.equal(qs.stringify({ 'foo(ref)': 'bar' }, { format: qs.formats.RFC1738 }), 'foo(ref)=bar'); - - st.end(); - }); - - t.test('RFC 3986 spaces serialization', function (st) { - st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC3986 }), 'a=b%20c'); - st.equal(qs.stringify({ 'a b': 'c d' }, { format: qs.formats.RFC3986 }), 'a%20b=c%20d'); - st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }, { format: qs.formats.RFC3986 }), 'a%20b=a%20b'); - - st.end(); - }); - - t.test('Backward compatibility to RFC 3986', function (st) { - st.equal(qs.stringify({ a: 'b c' }), 'a=b%20c'); - st.equal(qs.stringify({ 'a b': SaferBuffer.from('a b') }), 'a%20b=a%20b'); - - st.end(); - }); - - t.test('Edge cases and unknown formats', function (st) { - ['UFO1234', false, 1234, null, {}, []].forEach(function (format) { - st['throws']( - function () { - qs.stringify({ a: 'b c' }, { format: format }); - }, - new TypeError('Unknown format option provided.') - ); - }); - st.end(); - }); - - t.test('encodeValuesOnly', function (st) { - st.equal( - qs.stringify( - { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] }, - { encodeValuesOnly: true, arrayFormat: 'indices' } - ), - 'a=b&c[0]=d&c[1]=e%3Df&f[0][0]=g&f[1][0]=h', - 'encodeValuesOnly + indices' - ); - st.equal( - qs.stringify( - { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] }, - { encodeValuesOnly: true, arrayFormat: 'brackets' } - ), - 'a=b&c[]=d&c[]=e%3Df&f[][]=g&f[][]=h', - 'encodeValuesOnly + brackets' - ); - st.equal( - qs.stringify( - { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] }, - { encodeValuesOnly: true, arrayFormat: 'repeat' } - ), - 'a=b&c=d&c=e%3Df&f=g&f=h', - 'encodeValuesOnly + repeat' - ); - - st.equal( - qs.stringify( - { a: 'b', c: ['d', 'e'], f: [['g'], ['h']] }, - { arrayFormat: 'indices' } - ), - 'a=b&c%5B0%5D=d&c%5B1%5D=e&f%5B0%5D%5B0%5D=g&f%5B1%5D%5B0%5D=h', - 'no encodeValuesOnly + indices' - ); - st.equal( - qs.stringify( - { a: 'b', c: ['d', 'e'], f: [['g'], ['h']] }, - { arrayFormat: 'brackets' } - ), - 'a=b&c%5B%5D=d&c%5B%5D=e&f%5B%5D%5B%5D=g&f%5B%5D%5B%5D=h', - 'no encodeValuesOnly + brackets' - ); - st.equal( - qs.stringify( - { a: 'b', c: ['d', 'e'], f: [['g'], ['h']] }, - { arrayFormat: 'repeat' } - ), - 'a=b&c=d&c=e&f=g&f=h', - 'no encodeValuesOnly + repeat' - ); - - st.end(); - }); - - t.test('encodeValuesOnly - strictNullHandling', function (st) { - st.equal( - qs.stringify( - { a: { b: null } }, - { encodeValuesOnly: true, strictNullHandling: true } - ), - 'a[b]' - ); - st.end(); - }); - - t.test('throws if an invalid charset is specified', function (st) { - st['throws'](function () { - qs.stringify({ a: 'b' }, { charset: 'foobar' }); - }, new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined')); - st.end(); - }); - - t.test('respects a charset of iso-8859-1', function (st) { - st.equal(qs.stringify({ æ: 'æ' }, { charset: 'iso-8859-1' }), '%E6=%E6'); - st.end(); - }); - - t.test('encodes unrepresentable chars as numeric entities in iso-8859-1 mode', function (st) { - st.equal(qs.stringify({ a: '☺' }, { charset: 'iso-8859-1' }), 'a=%26%239786%3B'); - st.end(); - }); - - t.test('respects an explicit charset of utf-8 (the default)', function (st) { - st.equal(qs.stringify({ a: 'æ' }, { charset: 'utf-8' }), 'a=%C3%A6'); - st.end(); - }); - - t.test('`charsetSentinel` option', function (st) { - st.equal( - qs.stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'utf-8' }), - 'utf8=%E2%9C%93&a=%C3%A6', - 'adds the right sentinel when instructed to and the charset is utf-8' - ); - - st.equal( - qs.stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'iso-8859-1' }), - 'utf8=%26%2310003%3B&a=%E6', - 'adds the right sentinel when instructed to and the charset is iso-8859-1' - ); - - st.end(); - }); - - t.test('does not mutate the options argument', function (st) { - var options = {}; - qs.stringify({}, options); - st.deepEqual(options, {}); - st.end(); - }); - - t.test('strictNullHandling works with custom filter', function (st) { - var filter = function (prefix, value) { - return value; - }; - - var options = { strictNullHandling: true, filter: filter }; - st.equal(qs.stringify({ key: null }, options), 'key'); - st.end(); - }); - - t.test('strictNullHandling works with null serializeDate', function (st) { - var serializeDate = function () { - return null; - }; - var options = { strictNullHandling: true, serializeDate: serializeDate }; - var date = new Date(); - st.equal(qs.stringify({ key: date }, options), 'key'); - st.end(); - }); - - t.test('allows for encoding keys and values differently', function (st) { - var encoder = function (str, defaultEncoder, charset, type) { - if (type === 'key') { - return defaultEncoder(str, defaultEncoder, charset, type).toLowerCase(); - } - if (type === 'value') { - return defaultEncoder(str, defaultEncoder, charset, type).toUpperCase(); - } - throw 'this should never happen! type: ' + type; - }; - - st.deepEqual(qs.stringify({ KeY: 'vAlUe' }, { encoder: encoder }), 'key=VALUE'); - - var noopEncoder = function () { return 'x'; }; - noopEncoder(); - st['throws']( - function () { encoder('x', noopEncoder, 'utf-8', 'unknown'); }, - 'this should never happen! type: unknown', - 'encoder throws for unexpected type' - ); - - st.end(); - }); - - t.test('objects inside arrays', function (st) { - var obj = { a: { b: { c: 'd', e: 'f' } } }; - var withArray = { a: { b: [{ c: 'd', e: 'f' }] } }; - - st.equal(qs.stringify(obj, { encode: false }), 'a[b][c]=d&a[b][e]=f', 'no array, no arrayFormat'); - st.equal(qs.stringify(obj, { encode: false, arrayFormat: 'brackets' }), 'a[b][c]=d&a[b][e]=f', 'no array, bracket'); - st.equal(qs.stringify(obj, { encode: false, arrayFormat: 'indices' }), 'a[b][c]=d&a[b][e]=f', 'no array, indices'); - st.equal(qs.stringify(obj, { encode: false, arrayFormat: 'repeat' }), 'a[b][c]=d&a[b][e]=f', 'no array, repeat'); - st.equal(qs.stringify(obj, { encode: false, arrayFormat: 'comma' }), 'a[b][c]=d&a[b][e]=f', 'no array, comma'); - - st.equal(qs.stringify(withArray, { encode: false }), 'a[b][0][c]=d&a[b][0][e]=f', 'array, no arrayFormat'); - st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'brackets' }), 'a[b][][c]=d&a[b][][e]=f', 'array, bracket'); - st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'indices' }), 'a[b][0][c]=d&a[b][0][e]=f', 'array, indices'); - st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'repeat' }), 'a[b][c]=d&a[b][e]=f', 'array, repeat'); - st.equal( - qs.stringify(withArray, { encode: false, arrayFormat: 'comma' }), - '???', - 'array, comma', - { skip: 'TODO: figure out what this should do' } - ); - - st.end(); - }); - - t.test('stringifies sparse arrays', function (st) { - /* eslint no-sparse-arrays: 0 */ - st.equal(qs.stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[1]=2&a[4]=1'); - st.equal(qs.stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=2&a[]=1'); - st.equal(qs.stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), 'a=2&a=1'); - - st.equal(qs.stringify({ a: [, { b: [, , { c: '1' }] }] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[1][b][2][c]=1'); - st.equal(qs.stringify({ a: [, { b: [, , { c: '1' }] }] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[][b][][c]=1'); - st.equal(qs.stringify({ a: [, { b: [, , { c: '1' }] }] }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), 'a[b][c]=1'); - - st.equal(qs.stringify({ a: [, [, , [, , , { c: '1' }]]] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[1][2][3][c]=1'); - st.equal(qs.stringify({ a: [, [, , [, , , { c: '1' }]]] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[][][][c]=1'); - st.equal(qs.stringify({ a: [, [, , [, , , { c: '1' }]]] }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), 'a[c]=1'); - - st.equal(qs.stringify({ a: [, [, , [, , , { c: [, '1'] }]]] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[1][2][3][c][1]=1'); - st.equal(qs.stringify({ a: [, [, , [, , , { c: [, '1'] }]]] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[][][][c][]=1'); - st.equal(qs.stringify({ a: [, [, , [, , , { c: [, '1'] }]]] }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), 'a[c]=1'); - - st.end(); - }); - - t.test('encodes a very long string', function (st) { - var chars = []; - var expected = []; - for (var i = 0; i < 5e3; i++) { - chars.push(' ' + i); - - expected.push('%20' + i); - } - - var obj = { - foo: chars.join('') - }; - - st.equal( - qs.stringify(obj, { arrayFormat: 'brackets', charset: 'utf-8' }), - 'foo=' + expected.join('') - ); - - st.end(); - }); - - t.end(); -}); - -test('stringifies empty keys', function (t) { - emptyTestCases.forEach(function (testCase) { - t.test('stringifies an object with empty string key with ' + testCase.input, function (st) { - st.deepEqual( - qs.stringify(testCase.withEmptyKeys, { encode: false, arrayFormat: 'indices' }), - testCase.stringifyOutput.indices, - 'test case: ' + testCase.input + ', indices' - ); - st.deepEqual( - qs.stringify(testCase.withEmptyKeys, { encode: false, arrayFormat: 'brackets' }), - testCase.stringifyOutput.brackets, - 'test case: ' + testCase.input + ', brackets' - ); - st.deepEqual( - qs.stringify(testCase.withEmptyKeys, { encode: false, arrayFormat: 'repeat' }), - testCase.stringifyOutput.repeat, - 'test case: ' + testCase.input + ', repeat' - ); - - st.end(); - }); - }); - - t.test('edge case with object/arrays', function (st) { - st.deepEqual(qs.stringify({ '': { '': [2, 3] } }, { encode: false }), '[][0]=2&[][1]=3'); - st.deepEqual(qs.stringify({ '': { '': [2, 3], a: 2 } }, { encode: false }), '[][0]=2&[][1]=3&[a]=2'); - st.deepEqual(qs.stringify({ '': { '': [2, 3] } }, { encode: false, arrayFormat: 'indices' }), '[][0]=2&[][1]=3'); - st.deepEqual(qs.stringify({ '': { '': [2, 3], a: 2 } }, { encode: false, arrayFormat: 'indices' }), '[][0]=2&[][1]=3&[a]=2'); - - st.end(); - }); - - t.test('stringifies non-string keys', function (st) { - var S = Object('abc'); - S.toString = function () { - return 'd'; - }; - var actual = qs.stringify({ a: 'b', 'false': {}, 1e+22: 'c', d: 'e' }, { - filter: ['a', false, null, 10000000000000000000000, S], - allowDots: true, - encodeDotInKeys: true - }); - - st.equal(actual, 'a=b&1e%2B22=c&d=e', 'stringifies correctly'); - - st.end(); - }); -}); diff --git a/node_modules/body-parser/node_modules/qs/test/utils.js b/node_modules/body-parser/node_modules/qs/test/utils.js deleted file mode 100644 index 049c010..0000000 --- a/node_modules/body-parser/node_modules/qs/test/utils.js +++ /dev/null @@ -1,432 +0,0 @@ -'use strict'; - -var test = require('tape'); -var inspect = require('object-inspect'); -var SaferBuffer = require('safer-buffer').Buffer; -var forEach = require('for-each'); -var v = require('es-value-fixtures'); - -var utils = require('../lib/utils'); - -test('merge()', function (t) { - t.deepEqual(utils.merge(null, true), [null, true], 'merges true into null'); - - t.deepEqual(utils.merge(null, [42]), [null, 42], 'merges null into an array'); - - t.deepEqual(utils.merge({ a: 'b' }, { a: 'c' }), { a: ['b', 'c'] }, 'merges two objects with the same key'); - - var oneMerged = utils.merge({ foo: 'bar' }, { foo: { first: '123' } }); - t.deepEqual(oneMerged, { foo: ['bar', { first: '123' }] }, 'merges a standalone and an object into an array'); - - var twoMerged = utils.merge({ foo: ['bar', { first: '123' }] }, { foo: { second: '456' } }); - t.deepEqual(twoMerged, { foo: { 0: 'bar', 1: { first: '123' }, second: '456' } }, 'merges a standalone and two objects into an array'); - - var sandwiched = utils.merge({ foo: ['bar', { first: '123', second: '456' }] }, { foo: 'baz' }); - t.deepEqual(sandwiched, { foo: ['bar', { first: '123', second: '456' }, 'baz'] }, 'merges an object sandwiched by two standalones into an array'); - - var nestedArrays = utils.merge({ foo: ['baz'] }, { foo: ['bar', 'xyzzy'] }); - t.deepEqual(nestedArrays, { foo: ['baz', 'bar', 'xyzzy'] }); - - var noOptionsNonObjectSource = utils.merge({ foo: 'baz' }, 'bar'); - t.deepEqual(noOptionsNonObjectSource, { foo: 'baz', bar: true }); - - var func = function f() {}; - func(); - t.deepEqual( - utils.merge(func, { foo: 'bar' }), - [func, { foo: 'bar' }], - 'functions can not be merged into' - ); - - func.bar = 'baz'; - t.deepEqual( - utils.merge({ foo: 'bar' }, func), - { foo: 'bar', bar: 'baz' }, - 'functions can be merge sources' - ); - - t.test( - 'avoids invoking array setters unnecessarily', - { skip: typeof Object.defineProperty !== 'function' }, - function (st) { - var setCount = 0; - var getCount = 0; - var observed = []; - Object.defineProperty(observed, 0, { - get: function () { - getCount += 1; - return { bar: 'baz' }; - }, - set: function () { setCount += 1; } - }); - utils.merge(observed, [null]); - st.equal(setCount, 0); - st.equal(getCount, 1); - observed[0] = observed[0]; // eslint-disable-line no-self-assign - st.equal(setCount, 1); - st.equal(getCount, 2); - st.end(); - } - ); - - t.test('with overflow objects (from arrayLimit)', function (st) { - // arrayLimit is max index, so with limit 0, max index 0 is allowed (1 element) - // To create overflow, need 2+ elements with limit 0, or 3+ with limit 1, etc. - st.test('merges primitive into overflow object at next index', function (s2t) { - // Create an overflow object via combine: 3 elements (indices 0-2) with limit 0 - var overflow = utils.combine(['a', 'b'], 'c', 0, false); - s2t.ok(utils.isOverflow(overflow), 'overflow object is marked'); - var merged = utils.merge(overflow, 'd'); - s2t.deepEqual(merged, { 0: 'a', 1: 'b', 2: 'c', 3: 'd' }, 'adds primitive at next numeric index'); - s2t.end(); - }); - - st.test('merges primitive into regular object with numeric keys normally', function (s2t) { - var obj = { 0: 'a', 1: 'b' }; - s2t.notOk(utils.isOverflow(obj), 'plain object is not marked as overflow'); - var merged = utils.merge(obj, 'c'); - s2t.deepEqual(merged, { 0: 'a', 1: 'b', c: true }, 'adds primitive as key (not at next index)'); - s2t.end(); - }); - - st.test('merges primitive into object with non-numeric keys normally', function (s2t) { - var obj = { foo: 'bar' }; - var merged = utils.merge(obj, 'baz'); - s2t.deepEqual(merged, { foo: 'bar', baz: true }, 'adds primitive as key with value true'); - s2t.end(); - }); - - st.test('with strictMerge, wraps object and primitive in array', function (s2t) { - var obj = { foo: 'bar' }; - var merged = utils.merge(obj, 'baz', { strictMerge: true }); - s2t.deepEqual(merged, [{ foo: 'bar' }, 'baz'], 'wraps in array with strictMerge'); - s2t.end(); - }); - - st.test('merges overflow object into primitive', function (s2t) { - // Create an overflow object via combine: 2 elements (indices 0-1) with limit 0 - var overflow = utils.combine(['a'], 'b', 0, false); - s2t.ok(utils.isOverflow(overflow), 'overflow object is marked'); - var merged = utils.merge('c', overflow); - s2t.ok(utils.isOverflow(merged), 'result is also marked as overflow'); - s2t.deepEqual(merged, { 0: 'c', 1: 'a', 2: 'b' }, 'creates object with primitive at 0, source values shifted'); - s2t.end(); - }); - - st.test('merges overflow object into primitive with plainObjects', function (s2t) { - var overflow = utils.combine(['a'], 'b', 0, false); - s2t.ok(utils.isOverflow(overflow), 'overflow object is marked'); - var merged = utils.merge('c', overflow, { plainObjects: true }); - s2t.ok(utils.isOverflow(merged), 'result is also marked as overflow'); - s2t.deepEqual(merged, { __proto__: null, 0: 'c', 1: 'a', 2: 'b' }, 'creates null-proto object with primitive at 0'); - s2t.end(); - }); - - st.test('merges overflow object with multiple values into primitive', function (s2t) { - // Create an overflow object via combine: 3 elements (indices 0-2) with limit 0 - var overflow = utils.combine(['b', 'c'], 'd', 0, false); - s2t.ok(utils.isOverflow(overflow), 'overflow object is marked'); - var merged = utils.merge('a', overflow); - s2t.deepEqual(merged, { 0: 'a', 1: 'b', 2: 'c', 3: 'd' }, 'shifts all source indices by 1'); - s2t.end(); - }); - - st.test('merges regular object into primitive as array', function (s2t) { - var obj = { foo: 'bar' }; - var merged = utils.merge('a', obj); - s2t.deepEqual(merged, ['a', { foo: 'bar' }], 'creates array with primitive and object'); - s2t.end(); - }); - - st.test('merges primitive into array that exceeds arrayLimit', function (s2t) { - var arr = ['a', 'b', 'c']; - var merged = utils.merge(arr, 'd', { arrayLimit: 1 }); - s2t.ok(utils.isOverflow(merged), 'result is marked as overflow'); - s2t.deepEqual(merged, { 0: 'a', 1: 'b', 2: 'c', 3: 'd' }, 'converts to overflow object with primitive appended'); - s2t.end(); - }); - - st.test('merges array into primitive that exceeds arrayLimit', function (s2t) { - var merged = utils.merge('a', ['b', 'c'], { arrayLimit: 1 }); - s2t.ok(utils.isOverflow(merged), 'result is marked as overflow'); - s2t.deepEqual(merged, { 0: 'a', 1: 'b', 2: 'c' }, 'converts to overflow object'); - s2t.end(); - }); - - st.end(); - }); - - t.end(); -}); - -test('assign()', function (t) { - var target = { a: 1, b: 2 }; - var source = { b: 3, c: 4 }; - var result = utils.assign(target, source); - - t.equal(result, target, 'returns the target'); - t.deepEqual(target, { a: 1, b: 3, c: 4 }, 'target and source are merged'); - t.deepEqual(source, { b: 3, c: 4 }, 'source is untouched'); - - t.end(); -}); - -test('combine()', function (t) { - t.test('both arrays', function (st) { - var a = [1]; - var b = [2]; - var combined = utils.combine(a, b); - - st.deepEqual(a, [1], 'a is not mutated'); - st.deepEqual(b, [2], 'b is not mutated'); - st.notEqual(a, combined, 'a !== combined'); - st.notEqual(b, combined, 'b !== combined'); - st.deepEqual(combined, [1, 2], 'combined is a + b'); - - st.end(); - }); - - t.test('one array, one non-array', function (st) { - var aN = 1; - var a = [aN]; - var bN = 2; - var b = [bN]; - - var combinedAnB = utils.combine(aN, b); - st.deepEqual(b, [bN], 'b is not mutated'); - st.notEqual(aN, combinedAnB, 'aN + b !== aN'); - st.notEqual(a, combinedAnB, 'aN + b !== a'); - st.notEqual(bN, combinedAnB, 'aN + b !== bN'); - st.notEqual(b, combinedAnB, 'aN + b !== b'); - st.deepEqual([1, 2], combinedAnB, 'first argument is array-wrapped when not an array'); - - var combinedABn = utils.combine(a, bN); - st.deepEqual(a, [aN], 'a is not mutated'); - st.notEqual(aN, combinedABn, 'a + bN !== aN'); - st.notEqual(a, combinedABn, 'a + bN !== a'); - st.notEqual(bN, combinedABn, 'a + bN !== bN'); - st.notEqual(b, combinedABn, 'a + bN !== b'); - st.deepEqual([1, 2], combinedABn, 'second argument is array-wrapped when not an array'); - - st.end(); - }); - - t.test('neither is an array', function (st) { - var combined = utils.combine(1, 2); - st.notEqual(1, combined, '1 + 2 !== 1'); - st.notEqual(2, combined, '1 + 2 !== 2'); - st.deepEqual([1, 2], combined, 'both arguments are array-wrapped when not an array'); - - st.end(); - }); - - t.test('with arrayLimit', function (st) { - st.test('under the limit', function (s2t) { - var combined = utils.combine(['a', 'b'], 'c', 10, false); - s2t.deepEqual(combined, ['a', 'b', 'c'], 'returns array when under limit'); - s2t.ok(Array.isArray(combined), 'result is an array'); - s2t.end(); - }); - - st.test('exactly at the limit stays as array', function (s2t) { - var combined = utils.combine(['a', 'b'], 'c', 3, false); - s2t.deepEqual(combined, ['a', 'b', 'c'], 'stays as array when count equals limit'); - s2t.ok(Array.isArray(combined), 'result is an array'); - s2t.end(); - }); - - st.test('over the limit', function (s2t) { - var combined = utils.combine(['a', 'b', 'c'], 'd', 3, false); - s2t.deepEqual(combined, { 0: 'a', 1: 'b', 2: 'c', 3: 'd' }, 'converts to object when over limit'); - s2t.notOk(Array.isArray(combined), 'result is not an array'); - s2t.end(); - }); - - st.test('with arrayLimit 1', function (s2t) { - var combined = utils.combine([], 'a', 1, false); - s2t.deepEqual(combined, ['a'], 'stays as array when count equals limit'); - s2t.ok(Array.isArray(combined), 'result is an array'); - s2t.end(); - }); - - st.test('with arrayLimit 0 converts single element to object', function (s2t) { - var combined = utils.combine([], 'a', 0, false); - s2t.deepEqual(combined, { 0: 'a' }, 'converts to object when count exceeds limit'); - s2t.notOk(Array.isArray(combined), 'result is not an array'); - s2t.end(); - }); - - st.test('with arrayLimit 0 and two elements converts to object', function (s2t) { - var combined = utils.combine(['a'], 'b', 0, false); - s2t.deepEqual(combined, { 0: 'a', 1: 'b' }, 'converts to object when count exceeds limit'); - s2t.notOk(Array.isArray(combined), 'result is not an array'); - s2t.end(); - }); - - st.test('with plainObjects option', function (s2t) { - var combined = utils.combine(['a', 'b'], 'c', 1, true); - var expected = { __proto__: null, 0: 'a', 1: 'b', 2: 'c' }; - s2t.deepEqual(combined, expected, 'converts to object with null prototype'); - s2t.equal(Object.getPrototypeOf(combined), null, 'result has null prototype when plainObjects is true'); - s2t.end(); - }); - - st.end(); - }); - - t.test('with existing overflow object', function (st) { - st.test('adds to existing overflow object at next index', function (s2t) { - // Create overflow object first via combine: 3 elements (indices 0-2) with limit 0 - var overflow = utils.combine(['a', 'b'], 'c', 0, false); - s2t.ok(utils.isOverflow(overflow), 'initial object is marked as overflow'); - - var combined = utils.combine(overflow, 'd', 10, false); - s2t.equal(combined, overflow, 'returns the same object (mutated)'); - s2t.deepEqual(combined, { 0: 'a', 1: 'b', 2: 'c', 3: 'd' }, 'adds value at next numeric index'); - s2t.end(); - }); - - st.test('does not treat plain object with numeric keys as overflow', function (s2t) { - var plainObj = { 0: 'a', 1: 'b' }; - s2t.notOk(utils.isOverflow(plainObj), 'plain object is not marked as overflow'); - - // combine treats this as a regular value, not an overflow object to append to - var combined = utils.combine(plainObj, 'c', 10, false); - s2t.deepEqual(combined, [{ 0: 'a', 1: 'b' }, 'c'], 'concatenates as regular values'); - s2t.end(); - }); - - st.end(); - }); - - t.end(); -}); - -test('decode', function (t) { - t.equal( - utils.decode('a+b'), - 'a b', - 'decodes + to space' - ); - - t.equal( - utils.decode('name%2Eobj'), - 'name.obj', - 'decodes a string' - ); - t.equal( - utils.decode('name%2Eobj%2Efoo', null, 'iso-8859-1'), - 'name.obj.foo', - 'decodes a string in iso-8859-1' - ); - - t.end(); -}); - -test('encode', function (t) { - forEach(v.nullPrimitives, function (nullish) { - t['throws']( - function () { utils.encode(nullish); }, - TypeError, - inspect(nullish) + ' is not a string' - ); - }); - - t.equal(utils.encode(''), '', 'empty string returns itself'); - t.deepEqual(utils.encode([]), [], 'empty array returns itself'); - t.deepEqual(utils.encode({ length: 0 }), { length: 0 }, 'empty arraylike returns itself'); - - t.test('symbols', { skip: !v.hasSymbols }, function (st) { - st.equal(utils.encode(Symbol('x')), 'Symbol%28x%29', 'symbol is encoded'); - - st.end(); - }); - - t.equal( - utils.encode('(abc)'), - '%28abc%29', - 'encodes parentheses' - ); - t.equal( - utils.encode({ toString: function () { return '(abc)'; } }), - '%28abc%29', - 'toStrings and encodes parentheses' - ); - - t.equal( - utils.encode('abc 123 💩', null, 'iso-8859-1'), - 'abc%20123%20%26%2355357%3B%26%2356489%3B', - 'encodes in iso-8859-1' - ); - - var longString = ''; - var expectedString = ''; - for (var i = 0; i < 1500; i++) { - longString += ' '; - expectedString += '%20'; - } - - t.equal( - utils.encode(longString), - expectedString, - 'encodes a long string' - ); - - t.equal( - utils.encode('\x28\x29'), - '%28%29', - 'encodes parens normally' - ); - t.equal( - utils.encode('\x28\x29', null, null, null, 'RFC1738'), - '()', - 'does not encode parens in RFC1738' - ); - - // todo RFC1738 format - - t.equal( - utils.encode('Āက豈'), - '%C4%80%E1%80%80%EF%A4%80', - 'encodes multibyte chars' - ); - - t.equal( - utils.encode('\uD83D \uDCA9'), - '%F0%9F%90%A0%F0%BA%90%80', - 'encodes lone surrogates' - ); - - t.end(); -}); - -test('isBuffer()', function (t) { - var fn = function () {}; - fn(); - forEach([null, undefined, true, false, '', 'abc', 42, 0, NaN, {}, [], fn, /a/g], function (x) { - t.equal(utils.isBuffer(x), false, inspect(x) + ' is not a buffer'); - }); - - var fakeBuffer = { constructor: Buffer }; - t.equal(utils.isBuffer(fakeBuffer), false, 'fake buffer is not a buffer'); - - var saferBuffer = SaferBuffer.from('abc'); - t.equal(utils.isBuffer(saferBuffer), true, 'SaferBuffer instance is a buffer'); - - var buffer = SaferBuffer.from('abc'); - t.notEqual(saferBuffer, buffer, 'different buffer instances'); - t.equal(utils.isBuffer(buffer), true, 'another Buffer instance is a buffer'); - t.end(); -}); - -test('isRegExp()', function (t) { - t.equal(utils.isRegExp(/a/g), true, 'RegExp is a RegExp'); - t.equal(utils.isRegExp(new RegExp('a', 'g')), true, 'new RegExp is a RegExp'); - t.equal(utils.isRegExp(new Date()), false, 'Date is not a RegExp'); - - forEach(v.primitives, function (primitive) { - t.equal(utils.isRegExp(primitive), false, inspect(primitive) + ' is not a RegExp'); - }); - - t.end(); -}); diff --git a/node_modules/body-parser/package.json b/node_modules/body-parser/package.json deleted file mode 100644 index a1d16f8..0000000 --- a/node_modules/body-parser/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "body-parser", - "description": "Node.js body parsing middleware", - "version": "1.20.5", - "contributors": [ - "Douglas Christopher Wilson ", - "Jonathan Ong (http://jongleberry.com)" - ], - "license": "MIT", - "repository": "expressjs/body-parser", - "dependencies": { - "bytes": "~3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "~1.2.0", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "on-finished": "~2.4.1", - "qs": "~6.15.1", - "raw-body": "~2.5.3", - "type-is": "~1.6.18", - "unpipe": "~1.0.0" - }, - "devDependencies": { - "eslint": "8.34.0", - "eslint-config-standard": "14.1.1", - "eslint-plugin-import": "2.27.5", - "eslint-plugin-markdown": "3.0.0", - "eslint-plugin-node": "11.1.0", - "eslint-plugin-promise": "6.1.1", - "eslint-plugin-standard": "4.1.0", - "methods": "1.1.2", - "mocha": "10.2.0", - "nyc": "15.1.0", - "safe-buffer": "5.2.1", - "supertest": "6.3.3" - }, - "files": [ - "lib/", - "LICENSE", - "HISTORY.md", - "index.js" - ], - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - }, - "scripts": { - "lint": "eslint .", - "test": "mocha --require test/support/env --reporter spec --check-leaks --bail test/", - "test-ci": "nyc --reporter=lcov --reporter=text npm test", - "test-cov": "nyc --reporter=html --reporter=text npm test" - } -} diff --git a/node_modules/bytes/History.md b/node_modules/bytes/History.md deleted file mode 100644 index d60ce0e..0000000 --- a/node_modules/bytes/History.md +++ /dev/null @@ -1,97 +0,0 @@ -3.1.2 / 2022-01-27 -================== - - * Fix return value for un-parsable strings - -3.1.1 / 2021-11-15 -================== - - * Fix "thousandsSeparator" incorrecting formatting fractional part - -3.1.0 / 2019-01-22 -================== - - * Add petabyte (`pb`) support - -3.0.0 / 2017-08-31 -================== - - * Change "kB" to "KB" in format output - * Remove support for Node.js 0.6 - * Remove support for ComponentJS - -2.5.0 / 2017-03-24 -================== - - * Add option "unit" - -2.4.0 / 2016-06-01 -================== - - * Add option "unitSeparator" - -2.3.0 / 2016-02-15 -================== - - * Drop partial bytes on all parsed units - * Fix non-finite numbers to `.format` to return `null` - * Fix parsing byte string that looks like hex - * perf: hoist regular expressions - -2.2.0 / 2015-11-13 -================== - - * add option "decimalPlaces" - * add option "fixedDecimals" - -2.1.0 / 2015-05-21 -================== - - * add `.format` export - * add `.parse` export - -2.0.2 / 2015-05-20 -================== - - * remove map recreation - * remove unnecessary object construction - -2.0.1 / 2015-05-07 -================== - - * fix browserify require - * remove node.extend dependency - -2.0.0 / 2015-04-12 -================== - - * add option "case" - * add option "thousandsSeparator" - * return "null" on invalid parse input - * support proper round-trip: bytes(bytes(num)) === num - * units no longer case sensitive when parsing - -1.0.0 / 2014-05-05 -================== - - * add negative support. fixes #6 - -0.3.0 / 2014-03-19 -================== - - * added terabyte support - -0.2.1 / 2013-04-01 -================== - - * add .component - -0.2.0 / 2012-10-28 -================== - - * bytes(200).should.eql('200b') - -0.1.0 / 2012-07-04 -================== - - * add bytes to string conversion [yields] diff --git a/node_modules/bytes/LICENSE b/node_modules/bytes/LICENSE deleted file mode 100644 index 63e95a9..0000000 --- a/node_modules/bytes/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -(The MIT License) - -Copyright (c) 2012-2014 TJ Holowaychuk -Copyright (c) 2015 Jed Watson - -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. diff --git a/node_modules/bytes/Readme.md b/node_modules/bytes/Readme.md deleted file mode 100644 index 5790e23..0000000 --- a/node_modules/bytes/Readme.md +++ /dev/null @@ -1,152 +0,0 @@ -# Bytes utility - -[![NPM Version][npm-image]][npm-url] -[![NPM Downloads][downloads-image]][downloads-url] -[![Build Status][ci-image]][ci-url] -[![Test Coverage][coveralls-image]][coveralls-url] - -Utility to parse a string bytes (ex: `1TB`) to bytes (`1099511627776`) and vice-versa. - -## Installation - -This is a [Node.js](https://nodejs.org/en/) module available through the -[npm registry](https://www.npmjs.com/). Installation is done using the -[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): - -```bash -$ npm install bytes -``` - -## Usage - -```js -var bytes = require('bytes'); -``` - -#### bytes(number|string value, [options]): number|string|null - -Default export function. Delegates to either `bytes.format` or `bytes.parse` based on the type of `value`. - -**Arguments** - -| Name | Type | Description | -|---------|----------|--------------------| -| value | `number`|`string` | Number value to format or string value to parse | -| options | `Object` | Conversion options for `format` | - -**Returns** - -| Name | Type | Description | -|---------|------------------|-------------------------------------------------| -| results | `string`|`number`|`null` | Return null upon error. Numeric value in bytes, or string value otherwise. | - -**Example** - -```js -bytes(1024); -// output: '1KB' - -bytes('1KB'); -// output: 1024 -``` - -#### bytes.format(number value, [options]): string|null - -Format the given value in bytes into a string. If the value is negative, it is kept as such. If it is a float, it is - rounded. - -**Arguments** - -| Name | Type | Description | -|---------|----------|--------------------| -| value | `number` | Value in bytes | -| options | `Object` | Conversion options | - -**Options** - -| Property | Type | Description | -|-------------------|--------|-----------------------------------------------------------------------------------------| -| decimalPlaces | `number`|`null` | Maximum number of decimal places to include in output. Default value to `2`. | -| fixedDecimals | `boolean`|`null` | Whether to always display the maximum number of decimal places. Default value to `false` | -| thousandsSeparator | `string`|`null` | Example of values: `' '`, `','` and `'.'`... Default value to `''`. | -| unit | `string`|`null` | The unit in which the result will be returned (B/KB/MB/GB/TB). Default value to `''` (which means auto detect). | -| unitSeparator | `string`|`null` | Separator to use between number and unit. Default value to `''`. | - -**Returns** - -| Name | Type | Description | -|---------|------------------|-------------------------------------------------| -| results | `string`|`null` | Return null upon error. String value otherwise. | - -**Example** - -```js -bytes.format(1024); -// output: '1KB' - -bytes.format(1000); -// output: '1000B' - -bytes.format(1000, {thousandsSeparator: ' '}); -// output: '1 000B' - -bytes.format(1024 * 1.7, {decimalPlaces: 0}); -// output: '2KB' - -bytes.format(1024, {unitSeparator: ' '}); -// output: '1 KB' -``` - -#### bytes.parse(string|number value): number|null - -Parse the string value into an integer in bytes. If no unit is given, or `value` -is a number, it is assumed the value is in bytes. - -Supported units and abbreviations are as follows and are case-insensitive: - - * `b` for bytes - * `kb` for kilobytes - * `mb` for megabytes - * `gb` for gigabytes - * `tb` for terabytes - * `pb` for petabytes - -The units are in powers of two, not ten. This means 1kb = 1024b according to this parser. - -**Arguments** - -| Name | Type | Description | -|---------------|--------|--------------------| -| value | `string`|`number` | String to parse, or number in bytes. | - -**Returns** - -| Name | Type | Description | -|---------|-------------|-------------------------| -| results | `number`|`null` | Return null upon error. Value in bytes otherwise. | - -**Example** - -```js -bytes.parse('1KB'); -// output: 1024 - -bytes.parse('1024'); -// output: 1024 - -bytes.parse(1024); -// output: 1024 -``` - -## License - -[MIT](LICENSE) - -[ci-image]: https://badgen.net/github/checks/visionmedia/bytes.js/master?label=ci -[ci-url]: https://github.com/visionmedia/bytes.js/actions?query=workflow%3Aci -[coveralls-image]: https://badgen.net/coveralls/c/github/visionmedia/bytes.js/master -[coveralls-url]: https://coveralls.io/r/visionmedia/bytes.js?branch=master -[downloads-image]: https://badgen.net/npm/dm/bytes -[downloads-url]: https://npmjs.org/package/bytes -[npm-image]: https://badgen.net/npm/v/bytes -[npm-url]: https://npmjs.org/package/bytes diff --git a/node_modules/bytes/index.js b/node_modules/bytes/index.js deleted file mode 100644 index 6f2d0f8..0000000 --- a/node_modules/bytes/index.js +++ /dev/null @@ -1,170 +0,0 @@ -/*! - * bytes - * Copyright(c) 2012-2014 TJ Holowaychuk - * Copyright(c) 2015 Jed Watson - * MIT Licensed - */ - -'use strict'; - -/** - * Module exports. - * @public - */ - -module.exports = bytes; -module.exports.format = format; -module.exports.parse = parse; - -/** - * Module variables. - * @private - */ - -var formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g; - -var formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/; - -var map = { - b: 1, - kb: 1 << 10, - mb: 1 << 20, - gb: 1 << 30, - tb: Math.pow(1024, 4), - pb: Math.pow(1024, 5), -}; - -var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb|pb)$/i; - -/** - * Convert the given value in bytes into a string or parse to string to an integer in bytes. - * - * @param {string|number} value - * @param {{ - * case: [string], - * decimalPlaces: [number] - * fixedDecimals: [boolean] - * thousandsSeparator: [string] - * unitSeparator: [string] - * }} [options] bytes options. - * - * @returns {string|number|null} - */ - -function bytes(value, options) { - if (typeof value === 'string') { - return parse(value); - } - - if (typeof value === 'number') { - return format(value, options); - } - - return null; -} - -/** - * Format the given value in bytes into a string. - * - * If the value is negative, it is kept as such. If it is a float, - * it is rounded. - * - * @param {number} value - * @param {object} [options] - * @param {number} [options.decimalPlaces=2] - * @param {number} [options.fixedDecimals=false] - * @param {string} [options.thousandsSeparator=] - * @param {string} [options.unit=] - * @param {string} [options.unitSeparator=] - * - * @returns {string|null} - * @public - */ - -function format(value, options) { - if (!Number.isFinite(value)) { - return null; - } - - var mag = Math.abs(value); - var thousandsSeparator = (options && options.thousandsSeparator) || ''; - var unitSeparator = (options && options.unitSeparator) || ''; - var decimalPlaces = (options && options.decimalPlaces !== undefined) ? options.decimalPlaces : 2; - var fixedDecimals = Boolean(options && options.fixedDecimals); - var unit = (options && options.unit) || ''; - - if (!unit || !map[unit.toLowerCase()]) { - if (mag >= map.pb) { - unit = 'PB'; - } else if (mag >= map.tb) { - unit = 'TB'; - } else if (mag >= map.gb) { - unit = 'GB'; - } else if (mag >= map.mb) { - unit = 'MB'; - } else if (mag >= map.kb) { - unit = 'KB'; - } else { - unit = 'B'; - } - } - - var val = value / map[unit.toLowerCase()]; - var str = val.toFixed(decimalPlaces); - - if (!fixedDecimals) { - str = str.replace(formatDecimalsRegExp, '$1'); - } - - if (thousandsSeparator) { - str = str.split('.').map(function (s, i) { - return i === 0 - ? s.replace(formatThousandsRegExp, thousandsSeparator) - : s - }).join('.'); - } - - return str + unitSeparator + unit; -} - -/** - * Parse the string value into an integer in bytes. - * - * If no unit is given, it is assumed the value is in bytes. - * - * @param {number|string} val - * - * @returns {number|null} - * @public - */ - -function parse(val) { - if (typeof val === 'number' && !isNaN(val)) { - return val; - } - - if (typeof val !== 'string') { - return null; - } - - // Test if the string passed is valid - var results = parseRegExp.exec(val); - var floatValue; - var unit = 'b'; - - if (!results) { - // Nothing could be extracted from the given string - floatValue = parseInt(val, 10); - unit = 'b' - } else { - // Retrieve the value and the unit - floatValue = parseFloat(results[1]); - unit = results[4].toLowerCase(); - } - - if (isNaN(floatValue)) { - return null; - } - - return Math.floor(map[unit] * floatValue); -} diff --git a/node_modules/bytes/package.json b/node_modules/bytes/package.json deleted file mode 100644 index f2b6a8b..0000000 --- a/node_modules/bytes/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "bytes", - "description": "Utility to parse a string bytes to bytes and vice-versa", - "version": "3.1.2", - "author": "TJ Holowaychuk (http://tjholowaychuk.com)", - "contributors": [ - "Jed Watson ", - "Théo FIDRY " - ], - "license": "MIT", - "keywords": [ - "byte", - "bytes", - "utility", - "parse", - "parser", - "convert", - "converter" - ], - "repository": "visionmedia/bytes.js", - "devDependencies": { - "eslint": "7.32.0", - "eslint-plugin-markdown": "2.2.1", - "mocha": "9.2.0", - "nyc": "15.1.0" - }, - "files": [ - "History.md", - "LICENSE", - "Readme.md", - "index.js" - ], - "engines": { - "node": ">= 0.8" - }, - "scripts": { - "lint": "eslint .", - "test": "mocha --check-leaks --reporter spec", - "test-ci": "nyc --reporter=lcov --reporter=text npm test", - "test-cov": "nyc --reporter=html --reporter=text npm test" - } -} diff --git a/node_modules/call-bind-apply-helpers/.eslintrc b/node_modules/call-bind-apply-helpers/.eslintrc deleted file mode 100644 index 201e859..0000000 --- a/node_modules/call-bind-apply-helpers/.eslintrc +++ /dev/null @@ -1,17 +0,0 @@ -{ - "root": true, - - "extends": "@ljharb", - - "rules": { - "func-name-matching": 0, - "id-length": 0, - "new-cap": [2, { - "capIsNewExceptions": [ - "GetIntrinsic", - ], - }], - "no-extra-parens": 0, - "no-magic-numbers": 0, - }, -} diff --git a/node_modules/call-bind-apply-helpers/.github/FUNDING.yml b/node_modules/call-bind-apply-helpers/.github/FUNDING.yml deleted file mode 100644 index 0011e9d..0000000 --- a/node_modules/call-bind-apply-helpers/.github/FUNDING.yml +++ /dev/null @@ -1,12 +0,0 @@ -# These are supported funding model platforms - -github: [ljharb] -patreon: # Replace with a single Patreon username -open_collective: # Replace with a single Open Collective username -ko_fi: # Replace with a single Ko-fi username -tidelift: npm/call-bind-apply-helpers -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: # Replace with a single Liberapay username -issuehunt: # Replace with a single IssueHunt username -otechie: # Replace with a single Otechie username -custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/node_modules/call-bind-apply-helpers/.nycrc b/node_modules/call-bind-apply-helpers/.nycrc deleted file mode 100644 index bdd626c..0000000 --- a/node_modules/call-bind-apply-helpers/.nycrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "all": true, - "check-coverage": false, - "reporter": ["text-summary", "text", "html", "json"], - "exclude": [ - "coverage", - "test" - ] -} diff --git a/node_modules/call-bind-apply-helpers/CHANGELOG.md b/node_modules/call-bind-apply-helpers/CHANGELOG.md deleted file mode 100644 index 2484942..0000000 --- a/node_modules/call-bind-apply-helpers/CHANGELOG.md +++ /dev/null @@ -1,30 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [v1.0.2](https://github.com/ljharb/call-bind-apply-helpers/compare/v1.0.1...v1.0.2) - 2025-02-12 - -### Commits - -- [types] improve inferred types [`e6f9586`](https://github.com/ljharb/call-bind-apply-helpers/commit/e6f95860a3c72879cb861a858cdfb8138fbedec1) -- [Dev Deps] update `@arethetypeswrong/cli`, `@ljharb/tsconfig`, `@types/tape`, `es-value-fixtures`, `for-each`, `has-strict-mode`, `object-inspect` [`e43d540`](https://github.com/ljharb/call-bind-apply-helpers/commit/e43d5409f97543bfbb11f345d47d8ce4e066d8c1) - -## [v1.0.1](https://github.com/ljharb/call-bind-apply-helpers/compare/v1.0.0...v1.0.1) - 2024-12-08 - -### Commits - -- [types] `reflectApply`: fix types [`4efc396`](https://github.com/ljharb/call-bind-apply-helpers/commit/4efc3965351a4f02cc55e836fa391d3d11ef2ef8) -- [Fix] `reflectApply`: oops, Reflect is not a function [`83cc739`](https://github.com/ljharb/call-bind-apply-helpers/commit/83cc7395de6b79b7730bdf092f1436f0b1263c75) -- [Dev Deps] update `@arethetypeswrong/cli` [`80bd5d3`](https://github.com/ljharb/call-bind-apply-helpers/commit/80bd5d3ae58b4f6b6995ce439dd5a1bcb178a940) - -## v1.0.0 - 2024-12-05 - -### Commits - -- Initial implementation, tests, readme [`7879629`](https://github.com/ljharb/call-bind-apply-helpers/commit/78796290f9b7430c9934d6f33d94ae9bc89fce04) -- Initial commit [`3f1dc16`](https://github.com/ljharb/call-bind-apply-helpers/commit/3f1dc164afc43285631b114a5f9dd9137b2b952f) -- npm init [`081df04`](https://github.com/ljharb/call-bind-apply-helpers/commit/081df048c312fcee400922026f6e97281200a603) -- Only apps should have lockfiles [`5b9ca0f`](https://github.com/ljharb/call-bind-apply-helpers/commit/5b9ca0fe8101ebfaf309c549caac4e0a017ed930) diff --git a/node_modules/call-bind-apply-helpers/LICENSE b/node_modules/call-bind-apply-helpers/LICENSE deleted file mode 100644 index f82f389..0000000 --- a/node_modules/call-bind-apply-helpers/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 Jordan Harband - -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. diff --git a/node_modules/call-bind-apply-helpers/README.md b/node_modules/call-bind-apply-helpers/README.md deleted file mode 100644 index 8fc0dae..0000000 --- a/node_modules/call-bind-apply-helpers/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# call-bind-apply-helpers [![Version Badge][npm-version-svg]][package-url] - -[![github actions][actions-image]][actions-url] -[![coverage][codecov-image]][codecov-url] -[![dependency status][deps-svg]][deps-url] -[![dev dependency status][dev-deps-svg]][dev-deps-url] -[![License][license-image]][license-url] -[![Downloads][downloads-image]][downloads-url] - -[![npm badge][npm-badge-png]][package-url] - -Helper functions around Function call/apply/bind, for use in `call-bind`. - -The only packages that should likely ever use this package directly are `call-bind` and `get-intrinsic`. -Please use `call-bind` unless you have a very good reason not to. - -## Getting started - -```sh -npm install --save call-bind-apply-helpers -``` - -## Usage/Examples - -```js -const assert = require('assert'); -const callBindBasic = require('call-bind-apply-helpers'); - -function f(a, b) { - assert.equal(this, 1); - assert.equal(a, 2); - assert.equal(b, 3); - assert.equal(arguments.length, 2); -} - -const fBound = callBindBasic([f, 1]); - -delete Function.prototype.call; -delete Function.prototype.bind; - -fBound(2, 3); -``` - -## Tests - -Clone the repo, `npm install`, and run `npm test` - -[package-url]: https://npmjs.org/package/call-bind-apply-helpers -[npm-version-svg]: https://versionbadg.es/ljharb/call-bind-apply-helpers.svg -[deps-svg]: https://david-dm.org/ljharb/call-bind-apply-helpers.svg -[deps-url]: https://david-dm.org/ljharb/call-bind-apply-helpers -[dev-deps-svg]: https://david-dm.org/ljharb/call-bind-apply-helpers/dev-status.svg -[dev-deps-url]: https://david-dm.org/ljharb/call-bind-apply-helpers#info=devDependencies -[npm-badge-png]: https://nodei.co/npm/call-bind-apply-helpers.png?downloads=true&stars=true -[license-image]: https://img.shields.io/npm/l/call-bind-apply-helpers.svg -[license-url]: LICENSE -[downloads-image]: https://img.shields.io/npm/dm/call-bind-apply-helpers.svg -[downloads-url]: https://npm-stat.com/charts.html?package=call-bind-apply-helpers -[codecov-image]: https://codecov.io/gh/ljharb/call-bind-apply-helpers/branch/main/graphs/badge.svg -[codecov-url]: https://app.codecov.io/gh/ljharb/call-bind-apply-helpers/ -[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/call-bind-apply-helpers -[actions-url]: https://github.com/ljharb/call-bind-apply-helpers/actions diff --git a/node_modules/call-bind-apply-helpers/actualApply.d.ts b/node_modules/call-bind-apply-helpers/actualApply.d.ts deleted file mode 100644 index b87286a..0000000 --- a/node_modules/call-bind-apply-helpers/actualApply.d.ts +++ /dev/null @@ -1 +0,0 @@ -export = Reflect.apply; \ No newline at end of file diff --git a/node_modules/call-bind-apply-helpers/actualApply.js b/node_modules/call-bind-apply-helpers/actualApply.js deleted file mode 100644 index ffa5135..0000000 --- a/node_modules/call-bind-apply-helpers/actualApply.js +++ /dev/null @@ -1,10 +0,0 @@ -'use strict'; - -var bind = require('function-bind'); - -var $apply = require('./functionApply'); -var $call = require('./functionCall'); -var $reflectApply = require('./reflectApply'); - -/** @type {import('./actualApply')} */ -module.exports = $reflectApply || bind.call($call, $apply); diff --git a/node_modules/call-bind-apply-helpers/applyBind.d.ts b/node_modules/call-bind-apply-helpers/applyBind.d.ts deleted file mode 100644 index d176c1a..0000000 --- a/node_modules/call-bind-apply-helpers/applyBind.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import actualApply from './actualApply'; - -type TupleSplitHead = T['length'] extends N - ? T - : T extends [...infer R, any] - ? TupleSplitHead - : never - -type TupleSplitTail = O['length'] extends N - ? T - : T extends [infer F, ...infer R] - ? TupleSplitTail<[...R], N, [...O, F]> - : never - -type TupleSplit = [TupleSplitHead, TupleSplitTail] - -declare function applyBind(...args: TupleSplit, 2>[1]): ReturnType; - -export = applyBind; \ No newline at end of file diff --git a/node_modules/call-bind-apply-helpers/applyBind.js b/node_modules/call-bind-apply-helpers/applyBind.js deleted file mode 100644 index d2b7723..0000000 --- a/node_modules/call-bind-apply-helpers/applyBind.js +++ /dev/null @@ -1,10 +0,0 @@ -'use strict'; - -var bind = require('function-bind'); -var $apply = require('./functionApply'); -var actualApply = require('./actualApply'); - -/** @type {import('./applyBind')} */ -module.exports = function applyBind() { - return actualApply(bind, $apply, arguments); -}; diff --git a/node_modules/call-bind-apply-helpers/functionApply.d.ts b/node_modules/call-bind-apply-helpers/functionApply.d.ts deleted file mode 100644 index 1f6e11b..0000000 --- a/node_modules/call-bind-apply-helpers/functionApply.d.ts +++ /dev/null @@ -1 +0,0 @@ -export = Function.prototype.apply; \ No newline at end of file diff --git a/node_modules/call-bind-apply-helpers/functionApply.js b/node_modules/call-bind-apply-helpers/functionApply.js deleted file mode 100644 index c71df9c..0000000 --- a/node_modules/call-bind-apply-helpers/functionApply.js +++ /dev/null @@ -1,4 +0,0 @@ -'use strict'; - -/** @type {import('./functionApply')} */ -module.exports = Function.prototype.apply; diff --git a/node_modules/call-bind-apply-helpers/functionCall.d.ts b/node_modules/call-bind-apply-helpers/functionCall.d.ts deleted file mode 100644 index 15e93df..0000000 --- a/node_modules/call-bind-apply-helpers/functionCall.d.ts +++ /dev/null @@ -1 +0,0 @@ -export = Function.prototype.call; \ No newline at end of file diff --git a/node_modules/call-bind-apply-helpers/functionCall.js b/node_modules/call-bind-apply-helpers/functionCall.js deleted file mode 100644 index 7a8d873..0000000 --- a/node_modules/call-bind-apply-helpers/functionCall.js +++ /dev/null @@ -1,4 +0,0 @@ -'use strict'; - -/** @type {import('./functionCall')} */ -module.exports = Function.prototype.call; diff --git a/node_modules/call-bind-apply-helpers/index.d.ts b/node_modules/call-bind-apply-helpers/index.d.ts deleted file mode 100644 index 541516b..0000000 --- a/node_modules/call-bind-apply-helpers/index.d.ts +++ /dev/null @@ -1,64 +0,0 @@ -type RemoveFromTuple< - Tuple extends readonly unknown[], - RemoveCount extends number, - Index extends 1[] = [] -> = Index["length"] extends RemoveCount - ? Tuple - : Tuple extends [infer First, ...infer Rest] - ? RemoveFromTuple - : Tuple; - -type ConcatTuples< - Prefix extends readonly unknown[], - Suffix extends readonly unknown[] -> = [...Prefix, ...Suffix]; - -type ExtractFunctionParams = T extends (this: infer TThis, ...args: infer P extends readonly unknown[]) => infer R - ? { thisArg: TThis; params: P; returnType: R } - : never; - -type BindFunction< - T extends (this: any, ...args: any[]) => any, - TThis, - TBoundArgs extends readonly unknown[], - ReceiverBound extends boolean -> = ExtractFunctionParams extends { - thisArg: infer OrigThis; - params: infer P extends readonly unknown[]; - returnType: infer R; -} - ? ReceiverBound extends true - ? (...args: RemoveFromTuple>) => R extends [OrigThis, ...infer Rest] - ? [TThis, ...Rest] // Replace `this` with `thisArg` - : R - : >>( - thisArg: U, - ...args: RemainingArgs - ) => R extends [OrigThis, ...infer Rest] - ? [U, ...ConcatTuples] // Preserve bound args in return type - : R - : never; - -declare function callBind< - const T extends (this: any, ...args: any[]) => any, - Extracted extends ExtractFunctionParams, - const TBoundArgs extends Partial & readonly unknown[], - const TThis extends Extracted["thisArg"] ->( - args: [fn: T, thisArg: TThis, ...boundArgs: TBoundArgs] -): BindFunction; - -declare function callBind< - const T extends (this: any, ...args: any[]) => any, - Extracted extends ExtractFunctionParams, - const TBoundArgs extends Partial & readonly unknown[] ->( - args: [fn: T, ...boundArgs: TBoundArgs] -): BindFunction; - -declare function callBind( - args: [fn: Exclude, ...rest: TArgs] -): never; - -// export as namespace callBind; -export = callBind; diff --git a/node_modules/call-bind-apply-helpers/index.js b/node_modules/call-bind-apply-helpers/index.js deleted file mode 100644 index 2f6dab4..0000000 --- a/node_modules/call-bind-apply-helpers/index.js +++ /dev/null @@ -1,15 +0,0 @@ -'use strict'; - -var bind = require('function-bind'); -var $TypeError = require('es-errors/type'); - -var $call = require('./functionCall'); -var $actualApply = require('./actualApply'); - -/** @type {(args: [Function, thisArg?: unknown, ...args: unknown[]]) => Function} TODO FIXME, find a way to use import('.') */ -module.exports = function callBindBasic(args) { - if (args.length < 1 || typeof args[0] !== 'function') { - throw new $TypeError('a function is required'); - } - return $actualApply(bind, $call, args); -}; diff --git a/node_modules/call-bind-apply-helpers/package.json b/node_modules/call-bind-apply-helpers/package.json deleted file mode 100644 index 923b8be..0000000 --- a/node_modules/call-bind-apply-helpers/package.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "name": "call-bind-apply-helpers", - "version": "1.0.2", - "description": "Helper functions around Function call/apply/bind, for use in `call-bind`", - "main": "index.js", - "exports": { - ".": "./index.js", - "./actualApply": "./actualApply.js", - "./applyBind": "./applyBind.js", - "./functionApply": "./functionApply.js", - "./functionCall": "./functionCall.js", - "./reflectApply": "./reflectApply.js", - "./package.json": "./package.json" - }, - "scripts": { - "prepack": "npmignore --auto --commentLines=auto", - "prepublish": "not-in-publish || npm run prepublishOnly", - "prepublishOnly": "safe-publish-latest", - "prelint": "evalmd README.md", - "lint": "eslint --ext=.js,.mjs .", - "postlint": "tsc -p . && attw -P", - "pretest": "npm run lint", - "tests-only": "nyc tape 'test/**/*.js'", - "test": "npm run tests-only", - "posttest": "npx npm@'>=10.2' audit --production", - "version": "auto-changelog && git add CHANGELOG.md", - "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/ljharb/call-bind-apply-helpers.git" - }, - "author": "Jordan Harband ", - "license": "MIT", - "bugs": { - "url": "https://github.com/ljharb/call-bind-apply-helpers/issues" - }, - "homepage": "https://github.com/ljharb/call-bind-apply-helpers#readme", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "devDependencies": { - "@arethetypeswrong/cli": "^0.17.3", - "@ljharb/eslint-config": "^21.1.1", - "@ljharb/tsconfig": "^0.2.3", - "@types/for-each": "^0.3.3", - "@types/function-bind": "^1.1.10", - "@types/object-inspect": "^1.13.0", - "@types/tape": "^5.8.1", - "auto-changelog": "^2.5.0", - "encoding": "^0.1.13", - "es-value-fixtures": "^1.7.1", - "eslint": "=8.8.0", - "evalmd": "^0.0.19", - "for-each": "^0.3.5", - "has-strict-mode": "^1.1.0", - "in-publish": "^2.0.1", - "npmignore": "^0.3.1", - "nyc": "^10.3.2", - "object-inspect": "^1.13.4", - "safe-publish-latest": "^2.0.0", - "tape": "^5.9.0", - "typescript": "next" - }, - "testling": { - "files": "test/index.js" - }, - "auto-changelog": { - "output": "CHANGELOG.md", - "template": "keepachangelog", - "unreleased": false, - "commitLimit": false, - "backfillLimit": false, - "hideCredit": true - }, - "publishConfig": { - "ignore": [ - ".github/workflows" - ] - }, - "engines": { - "node": ">= 0.4" - } -} diff --git a/node_modules/call-bind-apply-helpers/reflectApply.d.ts b/node_modules/call-bind-apply-helpers/reflectApply.d.ts deleted file mode 100644 index 6b2ae76..0000000 --- a/node_modules/call-bind-apply-helpers/reflectApply.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare const reflectApply: false | typeof Reflect.apply; - -export = reflectApply; diff --git a/node_modules/call-bind-apply-helpers/reflectApply.js b/node_modules/call-bind-apply-helpers/reflectApply.js deleted file mode 100644 index 3d03caa..0000000 --- a/node_modules/call-bind-apply-helpers/reflectApply.js +++ /dev/null @@ -1,4 +0,0 @@ -'use strict'; - -/** @type {import('./reflectApply')} */ -module.exports = typeof Reflect !== 'undefined' && Reflect && Reflect.apply; diff --git a/node_modules/call-bind-apply-helpers/test/index.js b/node_modules/call-bind-apply-helpers/test/index.js deleted file mode 100644 index 1cdc89e..0000000 --- a/node_modules/call-bind-apply-helpers/test/index.js +++ /dev/null @@ -1,63 +0,0 @@ -'use strict'; - -var callBind = require('../'); -var hasStrictMode = require('has-strict-mode')(); -var forEach = require('for-each'); -var inspect = require('object-inspect'); -var v = require('es-value-fixtures'); - -var test = require('tape'); - -test('callBindBasic', function (t) { - forEach(v.nonFunctions, function (nonFunction) { - t['throws']( - // @ts-expect-error - function () { callBind([nonFunction]); }, - TypeError, - inspect(nonFunction) + ' is not a function' - ); - }); - - var sentinel = { sentinel: true }; - /** @type {(this: T, a: A, b: B) => [T | undefined, A, B]} */ - var func = function (a, b) { - // eslint-disable-next-line no-invalid-this - return [!hasStrictMode && this === global ? undefined : this, a, b]; - }; - t.equal(func.length, 2, 'original function length is 2'); - - /** type {(thisArg: unknown, a: number, b: number) => [unknown, number, number]} */ - var bound = callBind([func]); - /** type {((a: number, b: number) => [typeof sentinel, typeof a, typeof b])} */ - var boundR = callBind([func, sentinel]); - /** type {((b: number) => [typeof sentinel, number, typeof b])} */ - var boundArg = callBind([func, sentinel, /** @type {const} */ (1)]); - - // @ts-expect-error - t.deepEqual(bound(), [undefined, undefined, undefined], 'bound func with no args'); - - // @ts-expect-error - t.deepEqual(func(), [undefined, undefined, undefined], 'unbound func with too few args'); - // @ts-expect-error - t.deepEqual(bound(1, 2), [hasStrictMode ? 1 : Object(1), 2, undefined], 'bound func too few args'); - // @ts-expect-error - t.deepEqual(boundR(), [sentinel, undefined, undefined], 'bound func with receiver, with too few args'); - // @ts-expect-error - t.deepEqual(boundArg(), [sentinel, 1, undefined], 'bound func with receiver and arg, with too few args'); - - t.deepEqual(func(1, 2), [undefined, 1, 2], 'unbound func with right args'); - t.deepEqual(bound(1, 2, 3), [hasStrictMode ? 1 : Object(1), 2, 3], 'bound func with right args'); - t.deepEqual(boundR(1, 2), [sentinel, 1, 2], 'bound func with receiver, with right args'); - t.deepEqual(boundArg(2), [sentinel, 1, 2], 'bound func with receiver and arg, with right arg'); - - // @ts-expect-error - t.deepEqual(func(1, 2, 3), [undefined, 1, 2], 'unbound func with too many args'); - // @ts-expect-error - t.deepEqual(bound(1, 2, 3, 4), [hasStrictMode ? 1 : Object(1), 2, 3], 'bound func with too many args'); - // @ts-expect-error - t.deepEqual(boundR(1, 2, 3), [sentinel, 1, 2], 'bound func with receiver, with too many args'); - // @ts-expect-error - t.deepEqual(boundArg(2, 3), [sentinel, 1, 2], 'bound func with receiver and arg, with too many args'); - - t.end(); -}); diff --git a/node_modules/call-bind-apply-helpers/tsconfig.json b/node_modules/call-bind-apply-helpers/tsconfig.json deleted file mode 100644 index aef9993..0000000 --- a/node_modules/call-bind-apply-helpers/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "@ljharb/tsconfig", - "compilerOptions": { - "target": "es2021", - }, - "exclude": [ - "coverage", - ], -} \ No newline at end of file diff --git a/node_modules/call-bound/.eslintrc b/node_modules/call-bound/.eslintrc deleted file mode 100644 index 2612ed8..0000000 --- a/node_modules/call-bound/.eslintrc +++ /dev/null @@ -1,13 +0,0 @@ -{ - "root": true, - - "extends": "@ljharb", - - "rules": { - "new-cap": [2, { - "capIsNewExceptions": [ - "GetIntrinsic", - ], - }], - }, -} diff --git a/node_modules/call-bound/.github/FUNDING.yml b/node_modules/call-bound/.github/FUNDING.yml deleted file mode 100644 index 2a2a135..0000000 --- a/node_modules/call-bound/.github/FUNDING.yml +++ /dev/null @@ -1,12 +0,0 @@ -# These are supported funding model platforms - -github: [ljharb] -patreon: # Replace with a single Patreon username -open_collective: # Replace with a single Open Collective username -ko_fi: # Replace with a single Ko-fi username -tidelift: npm/call-bound -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: # Replace with a single Liberapay username -issuehunt: # Replace with a single IssueHunt username -otechie: # Replace with a single Otechie username -custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/node_modules/call-bound/.nycrc b/node_modules/call-bound/.nycrc deleted file mode 100644 index bdd626c..0000000 --- a/node_modules/call-bound/.nycrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "all": true, - "check-coverage": false, - "reporter": ["text-summary", "text", "html", "json"], - "exclude": [ - "coverage", - "test" - ] -} diff --git a/node_modules/call-bound/CHANGELOG.md b/node_modules/call-bound/CHANGELOG.md deleted file mode 100644 index 8bde4e9..0000000 --- a/node_modules/call-bound/CHANGELOG.md +++ /dev/null @@ -1,42 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [v1.0.4](https://github.com/ljharb/call-bound/compare/v1.0.3...v1.0.4) - 2025-03-03 - -### Commits - -- [types] improve types [`e648922`](https://github.com/ljharb/call-bound/commit/e6489222a9e54f350fbf952ceabe51fd8b6027ff) -- [Dev Deps] update `@arethetypeswrong/cli`, `@ljharb/tsconfig`, `@types/tape`, `es-value-fixtures`, `for-each`, `has-strict-mode`, `object-inspect` [`a42a5eb`](https://github.com/ljharb/call-bound/commit/a42a5ebe6c1b54fcdc7997c7dc64fdca9e936719) -- [Deps] update `call-bind-apply-helpers`, `get-intrinsic` [`f529eac`](https://github.com/ljharb/call-bound/commit/f529eac132404c17156bbc23ab2297a25d0f20b8) - -## [v1.0.3](https://github.com/ljharb/call-bound/compare/v1.0.2...v1.0.3) - 2024-12-15 - -### Commits - -- [Refactor] use `call-bind-apply-helpers` instead of `call-bind` [`5e0b134`](https://github.com/ljharb/call-bound/commit/5e0b13496df14fb7d05dae9412f088da8d3f75be) -- [Deps] update `get-intrinsic` [`41fc967`](https://github.com/ljharb/call-bound/commit/41fc96732a22c7b7e8f381f93ccc54bb6293be2e) -- [readme] fix example [`79a0137`](https://github.com/ljharb/call-bound/commit/79a0137723f7c6d09c9c05452bbf8d5efb5d6e49) -- [meta] add `sideEffects` flag [`08b07be`](https://github.com/ljharb/call-bound/commit/08b07be7f1c03f67dc6f3cdaf0906259771859f7) - -## [v1.0.2](https://github.com/ljharb/call-bound/compare/v1.0.1...v1.0.2) - 2024-12-10 - -### Commits - -- [Dev Deps] update `@arethetypeswrong/cli`, `@ljharb/tsconfig`, `gopd` [`e6a5ffe`](https://github.com/ljharb/call-bound/commit/e6a5ffe849368fe4f74dfd6cdeca1b9baa39e8d5) -- [Deps] update `call-bind`, `get-intrinsic` [`2aeb5b5`](https://github.com/ljharb/call-bound/commit/2aeb5b521dc2b2683d1345c753ea1161de2d1c14) -- [types] improve return type [`1a0c9fe`](https://github.com/ljharb/call-bound/commit/1a0c9fe3114471e7ca1f57d104e2efe713bb4871) - -## v1.0.1 - 2024-12-05 - -### Commits - -- Initial implementation, tests, readme, types [`6d94121`](https://github.com/ljharb/call-bound/commit/6d94121a9243602e506334069f7a03189fe3363d) -- Initial commit [`0eae867`](https://github.com/ljharb/call-bound/commit/0eae867334ea025c33e6e91cdecfc9df96680cf9) -- npm init [`71b2479`](https://github.com/ljharb/call-bound/commit/71b2479c6723e0b7d91a6b663613067e98b7b275) -- Only apps should have lockfiles [`c3754a9`](https://github.com/ljharb/call-bound/commit/c3754a949b7f9132b47e2d18c1729889736741eb) -- [actions] skip `npm ls` in node < 10 [`74275a5`](https://github.com/ljharb/call-bound/commit/74275a5186b8caf6309b6b97472bdcb0df4683a8) -- [Dev Deps] add missing peer dep [`1354de8`](https://github.com/ljharb/call-bound/commit/1354de8679413e4ae9c523d85f76fa7a5e032d97) diff --git a/node_modules/call-bound/LICENSE b/node_modules/call-bound/LICENSE deleted file mode 100644 index f82f389..0000000 --- a/node_modules/call-bound/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 Jordan Harband - -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. diff --git a/node_modules/call-bound/README.md b/node_modules/call-bound/README.md deleted file mode 100644 index a44e43e..0000000 --- a/node_modules/call-bound/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# call-bound [![Version Badge][npm-version-svg]][package-url] - -[![github actions][actions-image]][actions-url] -[![coverage][codecov-image]][codecov-url] -[![dependency status][deps-svg]][deps-url] -[![dev dependency status][dev-deps-svg]][dev-deps-url] -[![License][license-image]][license-url] -[![Downloads][downloads-image]][downloads-url] - -[![npm badge][npm-badge-png]][package-url] - -Robust call-bound JavaScript intrinsics, using `call-bind` and `get-intrinsic`. - -## Getting started - -```sh -npm install --save call-bound -``` - -## Usage/Examples - -```js -const assert = require('assert'); -const callBound = require('call-bound'); - -const slice = callBound('Array.prototype.slice'); - -delete Function.prototype.call; -delete Function.prototype.bind; -delete Array.prototype.slice; - -assert.deepEqual(slice([1, 2, 3, 4], 1, -1), [2, 3]); -``` - -## Tests - -Clone the repo, `npm install`, and run `npm test` - -[package-url]: https://npmjs.org/package/call-bound -[npm-version-svg]: https://versionbadg.es/ljharb/call-bound.svg -[deps-svg]: https://david-dm.org/ljharb/call-bound.svg -[deps-url]: https://david-dm.org/ljharb/call-bound -[dev-deps-svg]: https://david-dm.org/ljharb/call-bound/dev-status.svg -[dev-deps-url]: https://david-dm.org/ljharb/call-bound#info=devDependencies -[npm-badge-png]: https://nodei.co/npm/call-bound.png?downloads=true&stars=true -[license-image]: https://img.shields.io/npm/l/call-bound.svg -[license-url]: LICENSE -[downloads-image]: https://img.shields.io/npm/dm/call-bound.svg -[downloads-url]: https://npm-stat.com/charts.html?package=call-bound -[codecov-image]: https://codecov.io/gh/ljharb/call-bound/branch/main/graphs/badge.svg -[codecov-url]: https://app.codecov.io/gh/ljharb/call-bound/ -[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/call-bound -[actions-url]: https://github.com/ljharb/call-bound/actions diff --git a/node_modules/call-bound/index.d.ts b/node_modules/call-bound/index.d.ts deleted file mode 100644 index 5562f00..0000000 --- a/node_modules/call-bound/index.d.ts +++ /dev/null @@ -1,94 +0,0 @@ -type Intrinsic = typeof globalThis; - -type IntrinsicName = keyof Intrinsic | `%${keyof Intrinsic}%`; - -type IntrinsicPath = IntrinsicName | `${StripPercents}.${string}` | `%${StripPercents}.${string}%`; - -type AllowMissing = boolean; - -type StripPercents = T extends `%${infer U}%` ? U : T; - -type BindMethodPrecise = - F extends (this: infer This, ...args: infer Args) => infer R - ? (obj: This, ...args: Args) => R - : F extends { - (this: infer This1, ...args: infer Args1): infer R1; - (this: infer This2, ...args: infer Args2): infer R2 - } - ? { - (obj: This1, ...args: Args1): R1; - (obj: This2, ...args: Args2): R2 - } - : never - -// Extract method type from a prototype -type GetPrototypeMethod = - (typeof globalThis)[T] extends { prototype: any } - ? M extends keyof (typeof globalThis)[T]['prototype'] - ? (typeof globalThis)[T]['prototype'][M] - : never - : never - -// Get static property/method -type GetStaticMember = - P extends keyof (typeof globalThis)[T] ? (typeof globalThis)[T][P] : never - -// Type that maps string path to actual bound function or value with better precision -type BoundIntrinsic = - S extends `${infer Obj}.prototype.${infer Method}` - ? Obj extends keyof typeof globalThis - ? BindMethodPrecise> - : unknown - : S extends `${infer Obj}.${infer Prop}` - ? Obj extends keyof typeof globalThis - ? GetStaticMember - : unknown - : unknown - -declare function arraySlice(array: readonly T[], start?: number, end?: number): T[]; -declare function arraySlice(array: ArrayLike, start?: number, end?: number): T[]; -declare function arraySlice(array: IArguments, start?: number, end?: number): T[]; - -// Special cases for methods that need explicit typing -interface SpecialCases { - '%Object.prototype.isPrototypeOf%': (thisArg: {}, obj: unknown) => boolean; - '%String.prototype.replace%': { - (str: string, searchValue: string | RegExp, replaceValue: string): string; - (str: string, searchValue: string | RegExp, replacer: (substring: string, ...args: any[]) => string): string - }; - '%Object.prototype.toString%': (obj: {}) => string; - '%Object.prototype.hasOwnProperty%': (obj: {}, v: PropertyKey) => boolean; - '%Array.prototype.slice%': typeof arraySlice; - '%Array.prototype.map%': (array: readonly T[], callbackfn: (value: T, index: number, array: readonly T[]) => U, thisArg?: any) => U[]; - '%Array.prototype.filter%': (array: readonly T[], predicate: (value: T, index: number, array: readonly T[]) => unknown, thisArg?: any) => T[]; - '%Array.prototype.indexOf%': (array: readonly T[], searchElement: T, fromIndex?: number) => number; - '%Function.prototype.apply%': (fn: (...args: A) => R, thisArg: any, args: A) => R; - '%Function.prototype.call%': (fn: (...args: A) => R, thisArg: any, ...args: A) => R; - '%Function.prototype.bind%': (fn: (...args: A) => R, thisArg: any, ...args: A) => (...remainingArgs: A) => R; - '%Promise.prototype.then%': { - (promise: Promise, onfulfilled: (value: T) => R | PromiseLike): Promise; - (promise: Promise, onfulfilled: ((value: T) => R | PromiseLike) | undefined | null, onrejected: (reason: any) => R | PromiseLike): Promise; - }; - '%RegExp.prototype.test%': (regexp: RegExp, str: string) => boolean; - '%RegExp.prototype.exec%': (regexp: RegExp, str: string) => RegExpExecArray | null; - '%Error.prototype.toString%': (error: Error) => string; - '%TypeError.prototype.toString%': (error: TypeError) => string; - '%String.prototype.split%': ( - obj: unknown, - splitter: string | RegExp | { - [Symbol.split](string: string, limit?: number): string[]; - }, - limit?: number | undefined - ) => string[]; -} - -/** - * Returns a bound function for a prototype method, or a value for a static property. - * - * @param name - The name of the intrinsic (e.g. 'Array.prototype.slice') - * @param {AllowMissing} [allowMissing] - Whether to allow missing intrinsics (default: false) - */ -declare function callBound, S extends IntrinsicPath>(name: K, allowMissing?: AllowMissing): SpecialCases[`%${StripPercents}%`]; -declare function callBound, S extends IntrinsicPath>(name: S, allowMissing?: AllowMissing): BoundIntrinsic; - -export = callBound; diff --git a/node_modules/call-bound/index.js b/node_modules/call-bound/index.js deleted file mode 100644 index e9ade74..0000000 --- a/node_modules/call-bound/index.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict'; - -var GetIntrinsic = require('get-intrinsic'); - -var callBindBasic = require('call-bind-apply-helpers'); - -/** @type {(thisArg: string, searchString: string, position?: number) => number} */ -var $indexOf = callBindBasic([GetIntrinsic('%String.prototype.indexOf%')]); - -/** @type {import('.')} */ -module.exports = function callBoundIntrinsic(name, allowMissing) { - /* eslint no-extra-parens: 0 */ - - var intrinsic = /** @type {(this: unknown, ...args: unknown[]) => unknown} */ (GetIntrinsic(name, !!allowMissing)); - if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) { - return callBindBasic(/** @type {const} */ ([intrinsic])); - } - return intrinsic; -}; diff --git a/node_modules/call-bound/package.json b/node_modules/call-bound/package.json deleted file mode 100644 index d542db4..0000000 --- a/node_modules/call-bound/package.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "name": "call-bound", - "version": "1.0.4", - "description": "Robust call-bound JavaScript intrinsics, using `call-bind` and `get-intrinsic`.", - "main": "index.js", - "exports": { - ".": "./index.js", - "./package.json": "./package.json" - }, - "sideEffects": false, - "scripts": { - "prepack": "npmignore --auto --commentLines=auto", - "prepublish": "not-in-publish || npm run prepublishOnly", - "prepublishOnly": "safe-publish-latest", - "prelint": "evalmd README.md", - "lint": "eslint --ext=.js,.mjs .", - "postlint": "tsc -p . && attw -P", - "pretest": "npm run lint", - "tests-only": "nyc tape 'test/**/*.js'", - "test": "npm run tests-only", - "posttest": "npx npm@'>=10.2' audit --production", - "version": "auto-changelog && git add CHANGELOG.md", - "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/ljharb/call-bound.git" - }, - "keywords": [ - "javascript", - "ecmascript", - "es", - "js", - "callbind", - "callbound", - "call", - "bind", - "bound", - "call-bind", - "call-bound", - "function", - "es-abstract" - ], - "author": "Jordan Harband ", - "funding": { - "url": "https://github.com/sponsors/ljharb" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/ljharb/call-bound/issues" - }, - "homepage": "https://github.com/ljharb/call-bound#readme", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "devDependencies": { - "@arethetypeswrong/cli": "^0.17.4", - "@ljharb/eslint-config": "^21.1.1", - "@ljharb/tsconfig": "^0.3.0", - "@types/call-bind": "^1.0.5", - "@types/get-intrinsic": "^1.2.3", - "@types/tape": "^5.8.1", - "auto-changelog": "^2.5.0", - "encoding": "^0.1.13", - "es-value-fixtures": "^1.7.1", - "eslint": "=8.8.0", - "evalmd": "^0.0.19", - "for-each": "^0.3.5", - "gopd": "^1.2.0", - "has-strict-mode": "^1.1.0", - "in-publish": "^2.0.1", - "npmignore": "^0.3.1", - "nyc": "^10.3.2", - "object-inspect": "^1.13.4", - "safe-publish-latest": "^2.0.0", - "tape": "^5.9.0", - "typescript": "next" - }, - "testling": { - "files": "test/index.js" - }, - "auto-changelog": { - "output": "CHANGELOG.md", - "template": "keepachangelog", - "unreleased": false, - "commitLimit": false, - "backfillLimit": false, - "hideCredit": true - }, - "publishConfig": { - "ignore": [ - ".github/workflows" - ] - }, - "engines": { - "node": ">= 0.4" - } -} diff --git a/node_modules/call-bound/test/index.js b/node_modules/call-bound/test/index.js deleted file mode 100644 index a2fc9f0..0000000 --- a/node_modules/call-bound/test/index.js +++ /dev/null @@ -1,61 +0,0 @@ -'use strict'; - -var test = require('tape'); - -var callBound = require('../'); - -/** @template {true} T @template U @typedef {T extends U ? T : never} AssertType */ - -test('callBound', function (t) { - // static primitive - t.equal(callBound('Array.length'), Array.length, 'Array.length yields itself'); - t.equal(callBound('%Array.length%'), Array.length, '%Array.length% yields itself'); - - // static non-function object - t.equal(callBound('Array.prototype'), Array.prototype, 'Array.prototype yields itself'); - t.equal(callBound('%Array.prototype%'), Array.prototype, '%Array.prototype% yields itself'); - t.equal(callBound('Array.constructor'), Array.constructor, 'Array.constructor yields itself'); - t.equal(callBound('%Array.constructor%'), Array.constructor, '%Array.constructor% yields itself'); - - // static function - t.equal(callBound('Date.parse'), Date.parse, 'Date.parse yields itself'); - t.equal(callBound('%Date.parse%'), Date.parse, '%Date.parse% yields itself'); - - // prototype primitive - t.equal(callBound('Error.prototype.message'), Error.prototype.message, 'Error.prototype.message yields itself'); - t.equal(callBound('%Error.prototype.message%'), Error.prototype.message, '%Error.prototype.message% yields itself'); - - var x = callBound('Object.prototype.toString'); - var y = callBound('%Object.prototype.toString%'); - - // prototype function - t.notEqual(x, Object.prototype.toString, 'Object.prototype.toString does not yield itself'); - t.notEqual(y, Object.prototype.toString, '%Object.prototype.toString% does not yield itself'); - t.equal(x(true), Object.prototype.toString.call(true), 'call-bound Object.prototype.toString calls into the original'); - t.equal(y(true), Object.prototype.toString.call(true), 'call-bound %Object.prototype.toString% calls into the original'); - - t['throws']( - // @ts-expect-error - function () { callBound('does not exist'); }, - SyntaxError, - 'nonexistent intrinsic throws' - ); - t['throws']( - // @ts-expect-error - function () { callBound('does not exist', true); }, - SyntaxError, - 'allowMissing arg still throws for unknown intrinsic' - ); - - t.test('real but absent intrinsic', { skip: typeof WeakRef !== 'undefined' }, function (st) { - st['throws']( - function () { callBound('WeakRef'); }, - TypeError, - 'real but absent intrinsic throws' - ); - st.equal(callBound('WeakRef', true), undefined, 'allowMissing arg avoids exception'); - st.end(); - }); - - t.end(); -}); diff --git a/node_modules/call-bound/tsconfig.json b/node_modules/call-bound/tsconfig.json deleted file mode 100644 index 8976d98..0000000 --- a/node_modules/call-bound/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "@ljharb/tsconfig", - "compilerOptions": { - "target": "ESNext", - "lib": ["es2024"], - }, - "exclude": [ - "coverage", - ], -} diff --git a/node_modules/chokidar/LICENSE b/node_modules/chokidar/LICENSE deleted file mode 100644 index 8c27184..0000000 --- a/node_modules/chokidar/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2012 Paul Miller (https://paulmillr.com), Elan Shanker - -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. diff --git a/node_modules/chokidar/README.md b/node_modules/chokidar/README.md deleted file mode 100644 index ca3bcbb..0000000 --- a/node_modules/chokidar/README.md +++ /dev/null @@ -1,305 +0,0 @@ -# Chokidar [![Weekly downloads](https://img.shields.io/npm/dw/chokidar.svg)](https://github.com/paulmillr/chokidar) - -> Minimal and efficient cross-platform file watching library - -## Why? - -There are many reasons to prefer Chokidar to raw fs.watch / fs.watchFile in 2024: - -- Events are properly reported - - macOS events report filenames - - events are not reported twice - - changes are reported as add / change / unlink instead of useless `rename` -- Atomic writes are supported, using `atomic` option - - Some file editors use them -- Chunked writes are supported, using `awaitWriteFinish` option - - Large files are commonly written in chunks -- File / dir filtering is supported -- Symbolic links are supported -- Recursive watching is always supported, instead of partial when using raw events - - Includes a way to limit recursion depth - -Chokidar relies on the Node.js core `fs` module, but when using -`fs.watch` and `fs.watchFile` for watching, it normalizes the events it -receives, often checking for truth by getting file stats and/or dir contents. -The `fs.watch`-based implementation is the default, which -avoids polling and keeps CPU usage down. Be advised that chokidar will initiate -watchers recursively for everything within scope of the paths that have been -specified, so be judicious about not wasting system resources by watching much -more than needed. For some cases, `fs.watchFile`, which utilizes polling and uses more resources, is used. - -Made for [Brunch](https://brunch.io/) in 2012, -it is now used in [~30 million repositories](https://www.npmjs.com/browse/depended/chokidar) and -has proven itself in production environments. - -**Sep 2024 update:** v4 is out! It decreases dependency count from 13 to 1, removes -support for globs, adds support for ESM / Common.js modules, and bumps minimum node.js version from v8 to v14. -Check out [upgrading](#upgrading). - -## Getting started - -Install with npm: - -```sh -npm install chokidar -``` - -Use it in your code: - -```javascript -import chokidar from 'chokidar'; - -// One-liner for current directory -chokidar.watch('.').on('all', (event, path) => { - console.log(event, path); -}); - - -// Extended options -// ---------------- - -// Initialize watcher. -const watcher = chokidar.watch('file, dir, or array', { - ignored: (path, stats) => stats?.isFile() && !path.endsWith('.js'), // only watch js files - persistent: true -}); - -// Something to use when events are received. -const log = console.log.bind(console); -// Add event listeners. -watcher - .on('add', path => log(`File ${path} has been added`)) - .on('change', path => log(`File ${path} has been changed`)) - .on('unlink', path => log(`File ${path} has been removed`)); - -// More possible events. -watcher - .on('addDir', path => log(`Directory ${path} has been added`)) - .on('unlinkDir', path => log(`Directory ${path} has been removed`)) - .on('error', error => log(`Watcher error: ${error}`)) - .on('ready', () => log('Initial scan complete. Ready for changes')) - .on('raw', (event, path, details) => { // internal - log('Raw event info:', event, path, details); - }); - -// 'add', 'addDir' and 'change' events also receive stat() results as second -// argument when available: https://nodejs.org/api/fs.html#fs_class_fs_stats -watcher.on('change', (path, stats) => { - if (stats) console.log(`File ${path} changed size to ${stats.size}`); -}); - -// Watch new files. -watcher.add('new-file'); -watcher.add(['new-file-2', 'new-file-3']); - -// Get list of actual paths being watched on the filesystem -let watchedPaths = watcher.getWatched(); - -// Un-watch some files. -await watcher.unwatch('new-file'); - -// Stop watching. The method is async! -await watcher.close().then(() => console.log('closed')); - -// Full list of options. See below for descriptions. -// Do not use this example! -chokidar.watch('file', { - persistent: true, - - // ignore .txt files - ignored: (file) => file.endsWith('.txt'), - // watch only .txt files - // ignored: (file, _stats) => _stats?.isFile() && !file.endsWith('.txt'), - - awaitWriteFinish: true, // emit single event when chunked writes are completed - atomic: true, // emit proper events when "atomic writes" (mv _tmp file) are used - - // The options also allow specifying custom intervals in ms - // awaitWriteFinish: { - // stabilityThreshold: 2000, - // pollInterval: 100 - // }, - // atomic: 100, - - interval: 100, - binaryInterval: 300, - - cwd: '.', - depth: 99, - - followSymlinks: true, - ignoreInitial: false, - ignorePermissionErrors: false, - usePolling: false, - alwaysStat: false, -}); - -``` - -`chokidar.watch(paths, [options])` - -* `paths` (string or array of strings). Paths to files, dirs to be watched -recursively. -* `options` (object) Options object as defined below: - -#### Persistence - -* `persistent` (default: `true`). Indicates whether the process -should continue to run as long as files are being watched. - -#### Path filtering - -* `ignored` function, regex, or path. Defines files/paths to be ignored. -The whole relative or absolute path is tested, not just filename. If a function with two arguments -is provided, it gets called twice per path - once with a single argument (the path), second -time with two arguments (the path and the -[`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) -object of that path). -* `ignoreInitial` (default: `false`). If set to `false` then `add`/`addDir` events are also emitted for matching paths while -instantiating the watching as chokidar discovers these file paths (before the `ready` event). -* `followSymlinks` (default: `true`). When `false`, only the -symlinks themselves will be watched for changes instead of following -the link references and bubbling events through the link's path. -* `cwd` (no default). The base directory from which watch `paths` are to be -derived. Paths emitted with events will be relative to this. - -#### Performance - -* `usePolling` (default: `false`). -Whether to use fs.watchFile (backed by polling), or fs.watch. If polling -leads to high CPU utilization, consider setting this to `false`. It is -typically necessary to **set this to `true` to successfully watch files over -a network**, and it may be necessary to successfully watch files in other -non-standard situations. Setting to `true` explicitly on MacOS overrides the -`useFsEvents` default. You may also set the CHOKIDAR_USEPOLLING env variable -to true (1) or false (0) in order to override this option. -* _Polling-specific settings_ (effective when `usePolling: true`) - * `interval` (default: `100`). Interval of file system polling, in milliseconds. You may also - set the CHOKIDAR_INTERVAL env variable to override this option. - * `binaryInterval` (default: `300`). Interval of file system - polling for binary files. - ([see list of binary extensions](https://github.com/sindresorhus/binary-extensions/blob/master/binary-extensions.json)) -* `alwaysStat` (default: `false`). If relying upon the -[`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) -object that may get passed with `add`, `addDir`, and `change` events, set -this to `true` to ensure it is provided even in cases where it wasn't -already available from the underlying watch events. -* `depth` (default: `undefined`). If set, limits how many levels of -subdirectories will be traversed. -* `awaitWriteFinish` (default: `false`). -By default, the `add` event will fire when a file first appears on disk, before -the entire file has been written. Furthermore, in some cases some `change` -events will be emitted while the file is being written. In some cases, -especially when watching for large files there will be a need to wait for the -write operation to finish before responding to a file creation or modification. -Setting `awaitWriteFinish` to `true` (or a truthy value) will poll file size, -holding its `add` and `change` events until the size does not change for a -configurable amount of time. The appropriate duration setting is heavily -dependent on the OS and hardware. For accurate detection this parameter should -be relatively high, making file watching much less responsive. -Use with caution. - * *`options.awaitWriteFinish` can be set to an object in order to adjust - timing params:* - * `awaitWriteFinish.stabilityThreshold` (default: 2000). Amount of time in - milliseconds for a file size to remain constant before emitting its event. - * `awaitWriteFinish.pollInterval` (default: 100). File size polling interval, in milliseconds. - -#### Errors - -* `ignorePermissionErrors` (default: `false`). Indicates whether to watch files -that don't have read permissions if possible. If watching fails due to `EPERM` -or `EACCES` with this set to `true`, the errors will be suppressed silently. -* `atomic` (default: `true` if `useFsEvents` and `usePolling` are `false`). -Automatically filters out artifacts that occur when using editors that use -"atomic writes" instead of writing directly to the source file. If a file is -re-added within 100 ms of being deleted, Chokidar emits a `change` event -rather than `unlink` then `add`. If the default of 100 ms does not work well -for you, you can override it by setting `atomic` to a custom value, in -milliseconds. - -### Methods & Events - -`chokidar.watch()` produces an instance of `FSWatcher`. Methods of `FSWatcher`: - -* `.add(path / paths)`: Add files, directories for tracking. -Takes an array of strings or just one string. -* `.on(event, callback)`: Listen for an FS event. -Available events: `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `ready`, -`raw`, `error`. -Additionally `all` is available which gets emitted with the underlying event -name and path for every event other than `ready`, `raw`, and `error`. `raw` is internal, use it carefully. -* `.unwatch(path / paths)`: Stop watching files or directories. -Takes an array of strings or just one string. -* `.close()`: **async** Removes all listeners from watched files. Asynchronous, returns Promise. Use with `await` to ensure bugs don't happen. -* `.getWatched()`: Returns an object representing all the paths on the file -system being watched by this `FSWatcher` instance. The object's keys are all the -directories (using absolute paths unless the `cwd` option was used), and the -values are arrays of the names of the items contained in each directory. - -### CLI - -Check out third party [chokidar-cli](https://github.com/open-cli-tools/chokidar-cli), -which allows to execute a command on each change, or get a stdio stream of change events. - -## Troubleshooting - -Sometimes, Chokidar runs out of file handles, causing `EMFILE` and `ENOSP` errors: - -* `bash: cannot set terminal process group (-1): Inappropriate ioctl for device bash: no job control in this shell` -* `Error: watch /home/ ENOSPC` - -There are two things that can cause it. - -1. Exhausted file handles for generic fs operations - - Can be solved by using [graceful-fs](https://www.npmjs.com/package/graceful-fs), - which can monkey-patch native `fs` module used by chokidar: `let fs = require('fs'); let grfs = require('graceful-fs'); grfs.gracefulify(fs);` - - Can also be solved by tuning OS: `echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p`. -2. Exhausted file handles for `fs.watch` - - Can't seem to be solved by graceful-fs or OS tuning - - It's possible to start using `usePolling: true`, which will switch backend to resource-intensive `fs.watchFile` - -All fsevents-related issues (`WARN optional dep failed`, `fsevents is not a constructor`) are solved by upgrading to v4+. - -## Changelog - -- **v4 (Sep 2024):** remove glob support and bundled fsevents. Decrease dependency count from 13 to 1. Rewrite in typescript. Bumps minimum node.js requirement to v14+ -- **v3 (Apr 2019):** massive CPU & RAM consumption improvements; reduces deps / package size by a factor of 17x and bumps Node.js requirement to v8.16+. -- **v2 (Dec 2017):** globs are now posix-style-only. Tons of bugfixes. -- **v1 (Apr 2015):** glob support, symlink support, tons of bugfixes. Node 0.8+ is supported -- **v0.1 (Apr 2012):** Initial release, extracted from [Brunch](https://github.com/brunch/brunch/blob/9847a065aea300da99bd0753f90354cde9de1261/src/helpers.coffee#L66) - -### Upgrading - -If you've used globs before and want do replicate the functionality with v4: - -```js -// v3 -chok.watch('**/*.js'); -chok.watch("./directory/**/*"); - -// v4 -chok.watch('.', { - ignored: (path, stats) => stats?.isFile() && !path.endsWith('.js'), // only watch js files -}); -chok.watch('./directory'); - -// other way -import { glob } from 'node:fs/promises'; -const watcher = watch(await Array.fromAsync(glob('**/*.js'))); - -// unwatching -// v3 -chok.unwatch('**/*.js'); -// v4 -chok.unwatch(await glob('**/*.js')); -``` - -## Also - -Why was chokidar named this way? What's the meaning behind it? - ->Chowkidar is a transliteration of a Hindi word meaning 'watchman, gatekeeper', चौकीदार. This ultimately comes from Sanskrit _ चतुष्क_ (crossway, quadrangle, consisting-of-four). This word is also used in other languages like Urdu as (چوکیدار) which is widely used in Pakistan and India. - -## License - -MIT (c) Paul Miller (), see [LICENSE](LICENSE) file. diff --git a/node_modules/chokidar/esm/handler.d.ts b/node_modules/chokidar/esm/handler.d.ts deleted file mode 100644 index ea777d0..0000000 --- a/node_modules/chokidar/esm/handler.d.ts +++ /dev/null @@ -1,90 +0,0 @@ -import type { WatchEventType, Stats, FSWatcher as NativeFsWatcher } from 'fs'; -import type { FSWatcher, WatchHelper, Throttler } from './index.js'; -import type { EntryInfo } from 'readdirp'; -export type Path = string; -export declare const STR_DATA = "data"; -export declare const STR_END = "end"; -export declare const STR_CLOSE = "close"; -export declare const EMPTY_FN: () => void; -export declare const IDENTITY_FN: (val: unknown) => unknown; -export declare const isWindows: boolean; -export declare const isMacos: boolean; -export declare const isLinux: boolean; -export declare const isFreeBSD: boolean; -export declare const isIBMi: boolean; -export declare const EVENTS: { - readonly ALL: "all"; - readonly READY: "ready"; - readonly ADD: "add"; - readonly CHANGE: "change"; - readonly ADD_DIR: "addDir"; - readonly UNLINK: "unlink"; - readonly UNLINK_DIR: "unlinkDir"; - readonly RAW: "raw"; - readonly ERROR: "error"; -}; -export type EventName = (typeof EVENTS)[keyof typeof EVENTS]; -export type FsWatchContainer = { - listeners: (path: string) => void | Set; - errHandlers: (err: unknown) => void | Set; - rawEmitters: (ev: WatchEventType, path: string, opts: unknown) => void | Set; - watcher: NativeFsWatcher; - watcherUnusable?: boolean; -}; -export interface WatchHandlers { - listener: (path: string) => void; - errHandler: (err: unknown) => void; - rawEmitter: (ev: WatchEventType, path: string, opts: unknown) => void; -} -/** - * @mixin - */ -export declare class NodeFsHandler { - fsw: FSWatcher; - _boundHandleError: (error: unknown) => void; - constructor(fsW: FSWatcher); - /** - * Watch file for changes with fs_watchFile or fs_watch. - * @param path to file or dir - * @param listener on fs change - * @returns closer for the watcher instance - */ - _watchWithNodeFs(path: string, listener: (path: string, newStats?: any) => void | Promise): (() => void) | undefined; - /** - * Watch a file and emit add event if warranted. - * @returns closer for the watcher instance - */ - _handleFile(file: Path, stats: Stats, initialAdd: boolean): (() => void) | undefined; - /** - * Handle symlinks encountered while reading a dir. - * @param entry returned by readdirp - * @param directory path of dir being read - * @param path of this item - * @param item basename of this item - * @returns true if no more processing is needed for this entry. - */ - _handleSymlink(entry: EntryInfo, directory: string, path: Path, item: string): Promise; - _handleRead(directory: string, initialAdd: boolean, wh: WatchHelper, target: Path, dir: Path, depth: number, throttler: Throttler): Promise | undefined; - /** - * Read directory to add / remove files from `@watched` list and re-read it on change. - * @param dir fs path - * @param stats - * @param initialAdd - * @param depth relative to user-supplied path - * @param target child path targeted for watch - * @param wh Common watch helpers for this path - * @param realpath - * @returns closer for the watcher instance. - */ - _handleDir(dir: string, stats: Stats, initialAdd: boolean, depth: number, target: string, wh: WatchHelper, realpath: string): Promise<(() => void) | undefined>; - /** - * Handle added file, directory, or glob pattern. - * Delegates call to _handleFile / _handleDir after checks. - * @param path to file or ir - * @param initialAdd was the file added at watch instantiation? - * @param priorWh depth relative to user-supplied path - * @param depth Child path actually targeted for watch - * @param target Child path actually targeted for watch - */ - _addToNodeFs(path: string, initialAdd: boolean, priorWh: WatchHelper | undefined, depth: number, target?: string): Promise; -} diff --git a/node_modules/chokidar/esm/handler.js b/node_modules/chokidar/esm/handler.js deleted file mode 100644 index bbda010..0000000 --- a/node_modules/chokidar/esm/handler.js +++ /dev/null @@ -1,629 +0,0 @@ -import { watchFile, unwatchFile, watch as fs_watch } from 'fs'; -import { open, stat, lstat, realpath as fsrealpath } from 'fs/promises'; -import * as sysPath from 'path'; -import { type as osType } from 'os'; -export const STR_DATA = 'data'; -export const STR_END = 'end'; -export const STR_CLOSE = 'close'; -export const EMPTY_FN = () => { }; -export const IDENTITY_FN = (val) => val; -const pl = process.platform; -export const isWindows = pl === 'win32'; -export const isMacos = pl === 'darwin'; -export const isLinux = pl === 'linux'; -export const isFreeBSD = pl === 'freebsd'; -export const isIBMi = osType() === 'OS400'; -export const EVENTS = { - ALL: 'all', - READY: 'ready', - ADD: 'add', - CHANGE: 'change', - ADD_DIR: 'addDir', - UNLINK: 'unlink', - UNLINK_DIR: 'unlinkDir', - RAW: 'raw', - ERROR: 'error', -}; -const EV = EVENTS; -const THROTTLE_MODE_WATCH = 'watch'; -const statMethods = { lstat, stat }; -const KEY_LISTENERS = 'listeners'; -const KEY_ERR = 'errHandlers'; -const KEY_RAW = 'rawEmitters'; -const HANDLER_KEYS = [KEY_LISTENERS, KEY_ERR, KEY_RAW]; -// prettier-ignore -const binaryExtensions = new Set([ - '3dm', '3ds', '3g2', '3gp', '7z', 'a', 'aac', 'adp', 'afdesign', 'afphoto', 'afpub', 'ai', - 'aif', 'aiff', 'alz', 'ape', 'apk', 'appimage', 'ar', 'arj', 'asf', 'au', 'avi', - 'bak', 'baml', 'bh', 'bin', 'bk', 'bmp', 'btif', 'bz2', 'bzip2', - 'cab', 'caf', 'cgm', 'class', 'cmx', 'cpio', 'cr2', 'cur', 'dat', 'dcm', 'deb', 'dex', 'djvu', - 'dll', 'dmg', 'dng', 'doc', 'docm', 'docx', 'dot', 'dotm', 'dra', 'DS_Store', 'dsk', 'dts', - 'dtshd', 'dvb', 'dwg', 'dxf', - 'ecelp4800', 'ecelp7470', 'ecelp9600', 'egg', 'eol', 'eot', 'epub', 'exe', - 'f4v', 'fbs', 'fh', 'fla', 'flac', 'flatpak', 'fli', 'flv', 'fpx', 'fst', 'fvt', - 'g3', 'gh', 'gif', 'graffle', 'gz', 'gzip', - 'h261', 'h263', 'h264', 'icns', 'ico', 'ief', 'img', 'ipa', 'iso', - 'jar', 'jpeg', 'jpg', 'jpgv', 'jpm', 'jxr', 'key', 'ktx', - 'lha', 'lib', 'lvp', 'lz', 'lzh', 'lzma', 'lzo', - 'm3u', 'm4a', 'm4v', 'mar', 'mdi', 'mht', 'mid', 'midi', 'mj2', 'mka', 'mkv', 'mmr', 'mng', - 'mobi', 'mov', 'movie', 'mp3', - 'mp4', 'mp4a', 'mpeg', 'mpg', 'mpga', 'mxu', - 'nef', 'npx', 'numbers', 'nupkg', - 'o', 'odp', 'ods', 'odt', 'oga', 'ogg', 'ogv', 'otf', 'ott', - 'pages', 'pbm', 'pcx', 'pdb', 'pdf', 'pea', 'pgm', 'pic', 'png', 'pnm', 'pot', 'potm', - 'potx', 'ppa', 'ppam', - 'ppm', 'pps', 'ppsm', 'ppsx', 'ppt', 'pptm', 'pptx', 'psd', 'pya', 'pyc', 'pyo', 'pyv', - 'qt', - 'rar', 'ras', 'raw', 'resources', 'rgb', 'rip', 'rlc', 'rmf', 'rmvb', 'rpm', 'rtf', 'rz', - 's3m', 's7z', 'scpt', 'sgi', 'shar', 'snap', 'sil', 'sketch', 'slk', 'smv', 'snk', 'so', - 'stl', 'suo', 'sub', 'swf', - 'tar', 'tbz', 'tbz2', 'tga', 'tgz', 'thmx', 'tif', 'tiff', 'tlz', 'ttc', 'ttf', 'txz', - 'udf', 'uvh', 'uvi', 'uvm', 'uvp', 'uvs', 'uvu', - 'viv', 'vob', - 'war', 'wav', 'wax', 'wbmp', 'wdp', 'weba', 'webm', 'webp', 'whl', 'wim', 'wm', 'wma', - 'wmv', 'wmx', 'woff', 'woff2', 'wrm', 'wvx', - 'xbm', 'xif', 'xla', 'xlam', 'xls', 'xlsb', 'xlsm', 'xlsx', 'xlt', 'xltm', 'xltx', 'xm', - 'xmind', 'xpi', 'xpm', 'xwd', 'xz', - 'z', 'zip', 'zipx', -]); -const isBinaryPath = (filePath) => binaryExtensions.has(sysPath.extname(filePath).slice(1).toLowerCase()); -// TODO: emit errors properly. Example: EMFILE on Macos. -const foreach = (val, fn) => { - if (val instanceof Set) { - val.forEach(fn); - } - else { - fn(val); - } -}; -const addAndConvert = (main, prop, item) => { - let container = main[prop]; - if (!(container instanceof Set)) { - main[prop] = container = new Set([container]); - } - container.add(item); -}; -const clearItem = (cont) => (key) => { - const set = cont[key]; - if (set instanceof Set) { - set.clear(); - } - else { - delete cont[key]; - } -}; -const delFromSet = (main, prop, item) => { - const container = main[prop]; - if (container instanceof Set) { - container.delete(item); - } - else if (container === item) { - delete main[prop]; - } -}; -const isEmptySet = (val) => (val instanceof Set ? val.size === 0 : !val); -const FsWatchInstances = new Map(); -/** - * Instantiates the fs_watch interface - * @param path to be watched - * @param options to be passed to fs_watch - * @param listener main event handler - * @param errHandler emits info about errors - * @param emitRaw emits raw event data - * @returns {NativeFsWatcher} - */ -function createFsWatchInstance(path, options, listener, errHandler, emitRaw) { - const handleEvent = (rawEvent, evPath) => { - listener(path); - emitRaw(rawEvent, evPath, { watchedPath: path }); - // emit based on events occurring for files from a directory's watcher in - // case the file's watcher misses it (and rely on throttling to de-dupe) - if (evPath && path !== evPath) { - fsWatchBroadcast(sysPath.resolve(path, evPath), KEY_LISTENERS, sysPath.join(path, evPath)); - } - }; - try { - return fs_watch(path, { - persistent: options.persistent, - }, handleEvent); - } - catch (error) { - errHandler(error); - return undefined; - } -} -/** - * Helper for passing fs_watch event data to a collection of listeners - * @param fullPath absolute path bound to fs_watch instance - */ -const fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => { - const cont = FsWatchInstances.get(fullPath); - if (!cont) - return; - foreach(cont[listenerType], (listener) => { - listener(val1, val2, val3); - }); -}; -/** - * Instantiates the fs_watch interface or binds listeners - * to an existing one covering the same file system entry - * @param path - * @param fullPath absolute path - * @param options to be passed to fs_watch - * @param handlers container for event listener functions - */ -const setFsWatchListener = (path, fullPath, options, handlers) => { - const { listener, errHandler, rawEmitter } = handlers; - let cont = FsWatchInstances.get(fullPath); - let watcher; - if (!options.persistent) { - watcher = createFsWatchInstance(path, options, listener, errHandler, rawEmitter); - if (!watcher) - return; - return watcher.close.bind(watcher); - } - if (cont) { - addAndConvert(cont, KEY_LISTENERS, listener); - addAndConvert(cont, KEY_ERR, errHandler); - addAndConvert(cont, KEY_RAW, rawEmitter); - } - else { - watcher = createFsWatchInstance(path, options, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, // no need to use broadcast here - fsWatchBroadcast.bind(null, fullPath, KEY_RAW)); - if (!watcher) - return; - watcher.on(EV.ERROR, async (error) => { - const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR); - if (cont) - cont.watcherUnusable = true; // documented since Node 10.4.1 - // Workaround for https://github.com/joyent/node/issues/4337 - if (isWindows && error.code === 'EPERM') { - try { - const fd = await open(path, 'r'); - await fd.close(); - broadcastErr(error); - } - catch (err) { - // do nothing - } - } - else { - broadcastErr(error); - } - }); - cont = { - listeners: listener, - errHandlers: errHandler, - rawEmitters: rawEmitter, - watcher, - }; - FsWatchInstances.set(fullPath, cont); - } - // const index = cont.listeners.indexOf(listener); - // removes this instance's listeners and closes the underlying fs_watch - // instance if there are no more listeners left - return () => { - delFromSet(cont, KEY_LISTENERS, listener); - delFromSet(cont, KEY_ERR, errHandler); - delFromSet(cont, KEY_RAW, rawEmitter); - if (isEmptySet(cont.listeners)) { - // Check to protect against issue gh-730. - // if (cont.watcherUnusable) { - cont.watcher.close(); - // } - FsWatchInstances.delete(fullPath); - HANDLER_KEYS.forEach(clearItem(cont)); - // @ts-ignore - cont.watcher = undefined; - Object.freeze(cont); - } - }; -}; -// fs_watchFile helpers -// object to hold per-process fs_watchFile instances -// (may be shared across chokidar FSWatcher instances) -const FsWatchFileInstances = new Map(); -/** - * Instantiates the fs_watchFile interface or binds listeners - * to an existing one covering the same file system entry - * @param path to be watched - * @param fullPath absolute path - * @param options options to be passed to fs_watchFile - * @param handlers container for event listener functions - * @returns closer - */ -const setFsWatchFileListener = (path, fullPath, options, handlers) => { - const { listener, rawEmitter } = handlers; - let cont = FsWatchFileInstances.get(fullPath); - // let listeners = new Set(); - // let rawEmitters = new Set(); - const copts = cont && cont.options; - if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) { - // "Upgrade" the watcher to persistence or a quicker interval. - // This creates some unlikely edge case issues if the user mixes - // settings in a very weird way, but solving for those cases - // doesn't seem worthwhile for the added complexity. - // listeners = cont.listeners; - // rawEmitters = cont.rawEmitters; - unwatchFile(fullPath); - cont = undefined; - } - if (cont) { - addAndConvert(cont, KEY_LISTENERS, listener); - addAndConvert(cont, KEY_RAW, rawEmitter); - } - else { - // TODO - // listeners.add(listener); - // rawEmitters.add(rawEmitter); - cont = { - listeners: listener, - rawEmitters: rawEmitter, - options, - watcher: watchFile(fullPath, options, (curr, prev) => { - foreach(cont.rawEmitters, (rawEmitter) => { - rawEmitter(EV.CHANGE, fullPath, { curr, prev }); - }); - const currmtime = curr.mtimeMs; - if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) { - foreach(cont.listeners, (listener) => listener(path, curr)); - } - }), - }; - FsWatchFileInstances.set(fullPath, cont); - } - // const index = cont.listeners.indexOf(listener); - // Removes this instance's listeners and closes the underlying fs_watchFile - // instance if there are no more listeners left. - return () => { - delFromSet(cont, KEY_LISTENERS, listener); - delFromSet(cont, KEY_RAW, rawEmitter); - if (isEmptySet(cont.listeners)) { - FsWatchFileInstances.delete(fullPath); - unwatchFile(fullPath); - cont.options = cont.watcher = undefined; - Object.freeze(cont); - } - }; -}; -/** - * @mixin - */ -export class NodeFsHandler { - constructor(fsW) { - this.fsw = fsW; - this._boundHandleError = (error) => fsW._handleError(error); - } - /** - * Watch file for changes with fs_watchFile or fs_watch. - * @param path to file or dir - * @param listener on fs change - * @returns closer for the watcher instance - */ - _watchWithNodeFs(path, listener) { - const opts = this.fsw.options; - const directory = sysPath.dirname(path); - const basename = sysPath.basename(path); - const parent = this.fsw._getWatchedDir(directory); - parent.add(basename); - const absolutePath = sysPath.resolve(path); - const options = { - persistent: opts.persistent, - }; - if (!listener) - listener = EMPTY_FN; - let closer; - if (opts.usePolling) { - const enableBin = opts.interval !== opts.binaryInterval; - options.interval = enableBin && isBinaryPath(basename) ? opts.binaryInterval : opts.interval; - closer = setFsWatchFileListener(path, absolutePath, options, { - listener, - rawEmitter: this.fsw._emitRaw, - }); - } - else { - closer = setFsWatchListener(path, absolutePath, options, { - listener, - errHandler: this._boundHandleError, - rawEmitter: this.fsw._emitRaw, - }); - } - return closer; - } - /** - * Watch a file and emit add event if warranted. - * @returns closer for the watcher instance - */ - _handleFile(file, stats, initialAdd) { - if (this.fsw.closed) { - return; - } - const dirname = sysPath.dirname(file); - const basename = sysPath.basename(file); - const parent = this.fsw._getWatchedDir(dirname); - // stats is always present - let prevStats = stats; - // if the file is already being watched, do nothing - if (parent.has(basename)) - return; - const listener = async (path, newStats) => { - if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5)) - return; - if (!newStats || newStats.mtimeMs === 0) { - try { - const newStats = await stat(file); - if (this.fsw.closed) - return; - // Check that change event was not fired because of changed only accessTime. - const at = newStats.atimeMs; - const mt = newStats.mtimeMs; - if (!at || at <= mt || mt !== prevStats.mtimeMs) { - this.fsw._emit(EV.CHANGE, file, newStats); - } - if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats.ino) { - this.fsw._closeFile(path); - prevStats = newStats; - const closer = this._watchWithNodeFs(file, listener); - if (closer) - this.fsw._addPathCloser(path, closer); - } - else { - prevStats = newStats; - } - } - catch (error) { - // Fix issues where mtime is null but file is still present - this.fsw._remove(dirname, basename); - } - // add is about to be emitted if file not already tracked in parent - } - else if (parent.has(basename)) { - // Check that change event was not fired because of changed only accessTime. - const at = newStats.atimeMs; - const mt = newStats.mtimeMs; - if (!at || at <= mt || mt !== prevStats.mtimeMs) { - this.fsw._emit(EV.CHANGE, file, newStats); - } - prevStats = newStats; - } - }; - // kick off the watcher - const closer = this._watchWithNodeFs(file, listener); - // emit an add event if we're supposed to - if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) { - if (!this.fsw._throttle(EV.ADD, file, 0)) - return; - this.fsw._emit(EV.ADD, file, stats); - } - return closer; - } - /** - * Handle symlinks encountered while reading a dir. - * @param entry returned by readdirp - * @param directory path of dir being read - * @param path of this item - * @param item basename of this item - * @returns true if no more processing is needed for this entry. - */ - async _handleSymlink(entry, directory, path, item) { - if (this.fsw.closed) { - return; - } - const full = entry.fullPath; - const dir = this.fsw._getWatchedDir(directory); - if (!this.fsw.options.followSymlinks) { - // watch symlink directly (don't follow) and detect changes - this.fsw._incrReadyCount(); - let linkPath; - try { - linkPath = await fsrealpath(path); - } - catch (e) { - this.fsw._emitReady(); - return true; - } - if (this.fsw.closed) - return; - if (dir.has(item)) { - if (this.fsw._symlinkPaths.get(full) !== linkPath) { - this.fsw._symlinkPaths.set(full, linkPath); - this.fsw._emit(EV.CHANGE, path, entry.stats); - } - } - else { - dir.add(item); - this.fsw._symlinkPaths.set(full, linkPath); - this.fsw._emit(EV.ADD, path, entry.stats); - } - this.fsw._emitReady(); - return true; - } - // don't follow the same symlink more than once - if (this.fsw._symlinkPaths.has(full)) { - return true; - } - this.fsw._symlinkPaths.set(full, true); - } - _handleRead(directory, initialAdd, wh, target, dir, depth, throttler) { - // Normalize the directory name on Windows - directory = sysPath.join(directory, ''); - throttler = this.fsw._throttle('readdir', directory, 1000); - if (!throttler) - return; - const previous = this.fsw._getWatchedDir(wh.path); - const current = new Set(); - let stream = this.fsw._readdirp(directory, { - fileFilter: (entry) => wh.filterPath(entry), - directoryFilter: (entry) => wh.filterDir(entry), - }); - if (!stream) - return; - stream - .on(STR_DATA, async (entry) => { - if (this.fsw.closed) { - stream = undefined; - return; - } - const item = entry.path; - let path = sysPath.join(directory, item); - current.add(item); - if (entry.stats.isSymbolicLink() && - (await this._handleSymlink(entry, directory, path, item))) { - return; - } - if (this.fsw.closed) { - stream = undefined; - return; - } - // Files that present in current directory snapshot - // but absent in previous are added to watch list and - // emit `add` event. - if (item === target || (!target && !previous.has(item))) { - this.fsw._incrReadyCount(); - // ensure relativeness of path is preserved in case of watcher reuse - path = sysPath.join(dir, sysPath.relative(dir, path)); - this._addToNodeFs(path, initialAdd, wh, depth + 1); - } - }) - .on(EV.ERROR, this._boundHandleError); - return new Promise((resolve, reject) => { - if (!stream) - return reject(); - stream.once(STR_END, () => { - if (this.fsw.closed) { - stream = undefined; - return; - } - const wasThrottled = throttler ? throttler.clear() : false; - resolve(undefined); - // Files that absent in current directory snapshot - // but present in previous emit `remove` event - // and are removed from @watched[directory]. - previous - .getChildren() - .filter((item) => { - return item !== directory && !current.has(item); - }) - .forEach((item) => { - this.fsw._remove(directory, item); - }); - stream = undefined; - // one more time for any missed in case changes came in extremely quickly - if (wasThrottled) - this._handleRead(directory, false, wh, target, dir, depth, throttler); - }); - }); - } - /** - * Read directory to add / remove files from `@watched` list and re-read it on change. - * @param dir fs path - * @param stats - * @param initialAdd - * @param depth relative to user-supplied path - * @param target child path targeted for watch - * @param wh Common watch helpers for this path - * @param realpath - * @returns closer for the watcher instance. - */ - async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath) { - const parentDir = this.fsw._getWatchedDir(sysPath.dirname(dir)); - const tracked = parentDir.has(sysPath.basename(dir)); - if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) { - this.fsw._emit(EV.ADD_DIR, dir, stats); - } - // ensure dir is tracked (harmless if redundant) - parentDir.add(sysPath.basename(dir)); - this.fsw._getWatchedDir(dir); - let throttler; - let closer; - const oDepth = this.fsw.options.depth; - if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath)) { - if (!target) { - await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler); - if (this.fsw.closed) - return; - } - closer = this._watchWithNodeFs(dir, (dirPath, stats) => { - // if current directory is removed, do nothing - if (stats && stats.mtimeMs === 0) - return; - this._handleRead(dirPath, false, wh, target, dir, depth, throttler); - }); - } - return closer; - } - /** - * Handle added file, directory, or glob pattern. - * Delegates call to _handleFile / _handleDir after checks. - * @param path to file or ir - * @param initialAdd was the file added at watch instantiation? - * @param priorWh depth relative to user-supplied path - * @param depth Child path actually targeted for watch - * @param target Child path actually targeted for watch - */ - async _addToNodeFs(path, initialAdd, priorWh, depth, target) { - const ready = this.fsw._emitReady; - if (this.fsw._isIgnored(path) || this.fsw.closed) { - ready(); - return false; - } - const wh = this.fsw._getWatchHelpers(path); - if (priorWh) { - wh.filterPath = (entry) => priorWh.filterPath(entry); - wh.filterDir = (entry) => priorWh.filterDir(entry); - } - // evaluate what is at the path we're being asked to watch - try { - const stats = await statMethods[wh.statMethod](wh.watchPath); - if (this.fsw.closed) - return; - if (this.fsw._isIgnored(wh.watchPath, stats)) { - ready(); - return false; - } - const follow = this.fsw.options.followSymlinks; - let closer; - if (stats.isDirectory()) { - const absPath = sysPath.resolve(path); - const targetPath = follow ? await fsrealpath(path) : path; - if (this.fsw.closed) - return; - closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath); - if (this.fsw.closed) - return; - // preserve this symlink's target path - if (absPath !== targetPath && targetPath !== undefined) { - this.fsw._symlinkPaths.set(absPath, targetPath); - } - } - else if (stats.isSymbolicLink()) { - const targetPath = follow ? await fsrealpath(path) : path; - if (this.fsw.closed) - return; - const parent = sysPath.dirname(wh.watchPath); - this.fsw._getWatchedDir(parent).add(wh.watchPath); - this.fsw._emit(EV.ADD, wh.watchPath, stats); - closer = await this._handleDir(parent, stats, initialAdd, depth, path, wh, targetPath); - if (this.fsw.closed) - return; - // preserve this symlink's target path - if (targetPath !== undefined) { - this.fsw._symlinkPaths.set(sysPath.resolve(path), targetPath); - } - } - else { - closer = this._handleFile(wh.watchPath, stats, initialAdd); - } - ready(); - if (closer) - this.fsw._addPathCloser(path, closer); - return false; - } - catch (error) { - if (this.fsw._handleError(error)) { - ready(); - return path; - } - } - } -} diff --git a/node_modules/chokidar/esm/index.d.ts b/node_modules/chokidar/esm/index.d.ts deleted file mode 100644 index ffeb1e7..0000000 --- a/node_modules/chokidar/esm/index.d.ts +++ /dev/null @@ -1,215 +0,0 @@ -/*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) */ -import { Stats } from 'fs'; -import { EventEmitter } from 'events'; -import { ReaddirpStream, ReaddirpOptions, EntryInfo } from 'readdirp'; -import { NodeFsHandler, EventName, Path, EVENTS as EV, WatchHandlers } from './handler.js'; -type AWF = { - stabilityThreshold: number; - pollInterval: number; -}; -type BasicOpts = { - persistent: boolean; - ignoreInitial: boolean; - followSymlinks: boolean; - cwd?: string; - usePolling: boolean; - interval: number; - binaryInterval: number; - alwaysStat?: boolean; - depth?: number; - ignorePermissionErrors: boolean; - atomic: boolean | number; -}; -export type Throttler = { - timeoutObject: NodeJS.Timeout; - clear: () => void; - count: number; -}; -export type ChokidarOptions = Partial; -}>; -export type FSWInstanceOptions = BasicOpts & { - ignored: Matcher[]; - awaitWriteFinish: false | AWF; -}; -export type ThrottleType = 'readdir' | 'watch' | 'add' | 'remove' | 'change'; -export type EmitArgs = [path: Path, stats?: Stats]; -export type EmitErrorArgs = [error: Error, stats?: Stats]; -export type EmitArgsWithName = [event: EventName, ...EmitArgs]; -export type MatchFunction = (val: string, stats?: Stats) => boolean; -export interface MatcherObject { - path: string; - recursive?: boolean; -} -export type Matcher = string | RegExp | MatchFunction | MatcherObject; -/** - * Directory entry. - */ -declare class DirEntry { - path: Path; - _removeWatcher: (dir: string, base: string) => void; - items: Set; - constructor(dir: Path, removeWatcher: (dir: string, base: string) => void); - add(item: string): void; - remove(item: string): Promise; - has(item: string): boolean | undefined; - getChildren(): string[]; - dispose(): void; -} -export declare class WatchHelper { - fsw: FSWatcher; - path: string; - watchPath: string; - fullWatchPath: string; - dirParts: string[][]; - followSymlinks: boolean; - statMethod: 'stat' | 'lstat'; - constructor(path: string, follow: boolean, fsw: FSWatcher); - entryPath(entry: EntryInfo): Path; - filterPath(entry: EntryInfo): boolean; - filterDir(entry: EntryInfo): boolean; -} -export interface FSWatcherKnownEventMap { - [EV.READY]: []; - [EV.RAW]: Parameters; - [EV.ERROR]: Parameters; - [EV.ALL]: [event: EventName, ...EmitArgs]; -} -export type FSWatcherEventMap = FSWatcherKnownEventMap & { - [k in Exclude]: EmitArgs; -}; -/** - * Watches files & directories for changes. Emitted events: - * `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error` - * - * new FSWatcher() - * .add(directories) - * .on('add', path => log('File', path, 'was added')) - */ -export declare class FSWatcher extends EventEmitter { - closed: boolean; - options: FSWInstanceOptions; - _closers: Map>; - _ignoredPaths: Set; - _throttled: Map>; - _streams: Set; - _symlinkPaths: Map; - _watched: Map; - _pendingWrites: Map; - _pendingUnlinks: Map; - _readyCount: number; - _emitReady: () => void; - _closePromise?: Promise; - _userIgnored?: MatchFunction; - _readyEmitted: boolean; - _emitRaw: WatchHandlers['rawEmitter']; - _boundRemove: (dir: string, item: string) => void; - _nodeFsHandler: NodeFsHandler; - constructor(_opts?: ChokidarOptions); - _addIgnoredPath(matcher: Matcher): void; - _removeIgnoredPath(matcher: Matcher): void; - /** - * Adds paths to be watched on an existing FSWatcher instance. - * @param paths_ file or file list. Other arguments are unused - */ - add(paths_: Path | Path[], _origAdd?: string, _internal?: boolean): FSWatcher; - /** - * Close watchers or start ignoring events from specified paths. - */ - unwatch(paths_: Path | Path[]): FSWatcher; - /** - * Close watchers and remove all listeners from watched paths. - */ - close(): Promise; - /** - * Expose list of watched paths - * @returns for chaining - */ - getWatched(): Record; - emitWithAll(event: EventName, args: EmitArgs): void; - /** - * Normalize and emit events. - * Calling _emit DOES NOT MEAN emit() would be called! - * @param event Type of event - * @param path File or directory path - * @param stats arguments to be passed with event - * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag - */ - _emit(event: EventName, path: Path, stats?: Stats): Promise; - /** - * Common handler for errors - * @returns The error if defined, otherwise the value of the FSWatcher instance's `closed` flag - */ - _handleError(error: Error): Error | boolean; - /** - * Helper utility for throttling - * @param actionType type being throttled - * @param path being acted upon - * @param timeout duration of time to suppress duplicate actions - * @returns tracking object or false if action should be suppressed - */ - _throttle(actionType: ThrottleType, path: Path, timeout: number): Throttler | false; - _incrReadyCount(): number; - /** - * Awaits write operation to finish. - * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback. - * @param path being acted upon - * @param threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished - * @param event - * @param awfEmit Callback to be called when ready for event to be emitted. - */ - _awaitWriteFinish(path: Path, threshold: number, event: EventName, awfEmit: (err?: Error, stat?: Stats) => void): void; - /** - * Determines whether user has asked to ignore this path. - */ - _isIgnored(path: Path, stats?: Stats): boolean; - _isntIgnored(path: Path, stat?: Stats): boolean; - /** - * Provides a set of common helpers and properties relating to symlink handling. - * @param path file or directory pattern being watched - */ - _getWatchHelpers(path: Path): WatchHelper; - /** - * Provides directory tracking objects - * @param directory path of the directory - */ - _getWatchedDir(directory: string): DirEntry; - /** - * Check for read permissions: https://stackoverflow.com/a/11781404/1358405 - */ - _hasReadPermissions(stats: Stats): boolean; - /** - * Handles emitting unlink events for - * files and directories, and via recursion, for - * files and directories within directories that are unlinked - * @param directory within which the following item is located - * @param item base path of item/directory - */ - _remove(directory: string, item: string, isDirectory?: boolean): void; - /** - * Closes all watchers for a path - */ - _closePath(path: Path): void; - /** - * Closes only file-specific watchers - */ - _closeFile(path: Path): void; - _addPathCloser(path: Path, closer: () => void): void; - _readdirp(root: Path, opts?: Partial): ReaddirpStream | undefined; -} -/** - * Instantiates watcher with paths to be tracked. - * @param paths file / directory paths - * @param options opts, such as `atomic`, `awaitWriteFinish`, `ignored`, and others - * @returns an instance of FSWatcher for chaining. - * @example - * const watcher = watch('.').on('all', (event, path) => { console.log(event, path); }); - * watch('.', { atomic: true, awaitWriteFinish: true, ignored: (f, stats) => stats?.isFile() && !f.endsWith('.js') }) - */ -export declare function watch(paths: string | string[], options?: ChokidarOptions): FSWatcher; -declare const _default: { - watch: typeof watch; - FSWatcher: typeof FSWatcher; -}; -export default _default; diff --git a/node_modules/chokidar/esm/index.js b/node_modules/chokidar/esm/index.js deleted file mode 100644 index 1c80a40..0000000 --- a/node_modules/chokidar/esm/index.js +++ /dev/null @@ -1,798 +0,0 @@ -/*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) */ -import { stat as statcb } from 'fs'; -import { stat, readdir } from 'fs/promises'; -import { EventEmitter } from 'events'; -import * as sysPath from 'path'; -import { readdirp } from 'readdirp'; -import { NodeFsHandler, EVENTS as EV, isWindows, isIBMi, EMPTY_FN, STR_CLOSE, STR_END, } from './handler.js'; -const SLASH = '/'; -const SLASH_SLASH = '//'; -const ONE_DOT = '.'; -const TWO_DOTS = '..'; -const STRING_TYPE = 'string'; -const BACK_SLASH_RE = /\\/g; -const DOUBLE_SLASH_RE = /\/\//; -const DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/; -const REPLACER_RE = /^\.[/\\]/; -function arrify(item) { - return Array.isArray(item) ? item : [item]; -} -const isMatcherObject = (matcher) => typeof matcher === 'object' && matcher !== null && !(matcher instanceof RegExp); -function createPattern(matcher) { - if (typeof matcher === 'function') - return matcher; - if (typeof matcher === 'string') - return (string) => matcher === string; - if (matcher instanceof RegExp) - return (string) => matcher.test(string); - if (typeof matcher === 'object' && matcher !== null) { - return (string) => { - if (matcher.path === string) - return true; - if (matcher.recursive) { - const relative = sysPath.relative(matcher.path, string); - if (!relative) { - return false; - } - return !relative.startsWith('..') && !sysPath.isAbsolute(relative); - } - return false; - }; - } - return () => false; -} -function normalizePath(path) { - if (typeof path !== 'string') - throw new Error('string expected'); - path = sysPath.normalize(path); - path = path.replace(/\\/g, '/'); - let prepend = false; - if (path.startsWith('//')) - prepend = true; - const DOUBLE_SLASH_RE = /\/\//; - while (path.match(DOUBLE_SLASH_RE)) - path = path.replace(DOUBLE_SLASH_RE, '/'); - if (prepend) - path = '/' + path; - return path; -} -function matchPatterns(patterns, testString, stats) { - const path = normalizePath(testString); - for (let index = 0; index < patterns.length; index++) { - const pattern = patterns[index]; - if (pattern(path, stats)) { - return true; - } - } - return false; -} -function anymatch(matchers, testString) { - if (matchers == null) { - throw new TypeError('anymatch: specify first argument'); - } - // Early cache for matchers. - const matchersArray = arrify(matchers); - const patterns = matchersArray.map((matcher) => createPattern(matcher)); - if (testString == null) { - return (testString, stats) => { - return matchPatterns(patterns, testString, stats); - }; - } - return matchPatterns(patterns, testString); -} -const unifyPaths = (paths_) => { - const paths = arrify(paths_).flat(); - if (!paths.every((p) => typeof p === STRING_TYPE)) { - throw new TypeError(`Non-string provided as watch path: ${paths}`); - } - return paths.map(normalizePathToUnix); -}; -// If SLASH_SLASH occurs at the beginning of path, it is not replaced -// because "//StoragePC/DrivePool/Movies" is a valid network path -const toUnix = (string) => { - let str = string.replace(BACK_SLASH_RE, SLASH); - let prepend = false; - if (str.startsWith(SLASH_SLASH)) { - prepend = true; - } - while (str.match(DOUBLE_SLASH_RE)) { - str = str.replace(DOUBLE_SLASH_RE, SLASH); - } - if (prepend) { - str = SLASH + str; - } - return str; -}; -// Our version of upath.normalize -// TODO: this is not equal to path-normalize module - investigate why -const normalizePathToUnix = (path) => toUnix(sysPath.normalize(toUnix(path))); -// TODO: refactor -const normalizeIgnored = (cwd = '') => (path) => { - if (typeof path === 'string') { - return normalizePathToUnix(sysPath.isAbsolute(path) ? path : sysPath.join(cwd, path)); - } - else { - return path; - } -}; -const getAbsolutePath = (path, cwd) => { - if (sysPath.isAbsolute(path)) { - return path; - } - return sysPath.join(cwd, path); -}; -const EMPTY_SET = Object.freeze(new Set()); -/** - * Directory entry. - */ -class DirEntry { - constructor(dir, removeWatcher) { - this.path = dir; - this._removeWatcher = removeWatcher; - this.items = new Set(); - } - add(item) { - const { items } = this; - if (!items) - return; - if (item !== ONE_DOT && item !== TWO_DOTS) - items.add(item); - } - async remove(item) { - const { items } = this; - if (!items) - return; - items.delete(item); - if (items.size > 0) - return; - const dir = this.path; - try { - await readdir(dir); - } - catch (err) { - if (this._removeWatcher) { - this._removeWatcher(sysPath.dirname(dir), sysPath.basename(dir)); - } - } - } - has(item) { - const { items } = this; - if (!items) - return; - return items.has(item); - } - getChildren() { - const { items } = this; - if (!items) - return []; - return [...items.values()]; - } - dispose() { - this.items.clear(); - this.path = ''; - this._removeWatcher = EMPTY_FN; - this.items = EMPTY_SET; - Object.freeze(this); - } -} -const STAT_METHOD_F = 'stat'; -const STAT_METHOD_L = 'lstat'; -export class WatchHelper { - constructor(path, follow, fsw) { - this.fsw = fsw; - const watchPath = path; - this.path = path = path.replace(REPLACER_RE, ''); - this.watchPath = watchPath; - this.fullWatchPath = sysPath.resolve(watchPath); - this.dirParts = []; - this.dirParts.forEach((parts) => { - if (parts.length > 1) - parts.pop(); - }); - this.followSymlinks = follow; - this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L; - } - entryPath(entry) { - return sysPath.join(this.watchPath, sysPath.relative(this.watchPath, entry.fullPath)); - } - filterPath(entry) { - const { stats } = entry; - if (stats && stats.isSymbolicLink()) - return this.filterDir(entry); - const resolvedPath = this.entryPath(entry); - // TODO: what if stats is undefined? remove ! - return this.fsw._isntIgnored(resolvedPath, stats) && this.fsw._hasReadPermissions(stats); - } - filterDir(entry) { - return this.fsw._isntIgnored(this.entryPath(entry), entry.stats); - } -} -/** - * Watches files & directories for changes. Emitted events: - * `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error` - * - * new FSWatcher() - * .add(directories) - * .on('add', path => log('File', path, 'was added')) - */ -export class FSWatcher extends EventEmitter { - // Not indenting methods for history sake; for now. - constructor(_opts = {}) { - super(); - this.closed = false; - this._closers = new Map(); - this._ignoredPaths = new Set(); - this._throttled = new Map(); - this._streams = new Set(); - this._symlinkPaths = new Map(); - this._watched = new Map(); - this._pendingWrites = new Map(); - this._pendingUnlinks = new Map(); - this._readyCount = 0; - this._readyEmitted = false; - const awf = _opts.awaitWriteFinish; - const DEF_AWF = { stabilityThreshold: 2000, pollInterval: 100 }; - const opts = { - // Defaults - persistent: true, - ignoreInitial: false, - ignorePermissionErrors: false, - interval: 100, - binaryInterval: 300, - followSymlinks: true, - usePolling: false, - // useAsync: false, - atomic: true, // NOTE: overwritten later (depends on usePolling) - ..._opts, - // Change format - ignored: _opts.ignored ? arrify(_opts.ignored) : arrify([]), - awaitWriteFinish: awf === true ? DEF_AWF : typeof awf === 'object' ? { ...DEF_AWF, ...awf } : false, - }; - // Always default to polling on IBM i because fs.watch() is not available on IBM i. - if (isIBMi) - opts.usePolling = true; - // Editor atomic write normalization enabled by default with fs.watch - if (opts.atomic === undefined) - opts.atomic = !opts.usePolling; - // opts.atomic = typeof _opts.atomic === 'number' ? _opts.atomic : 100; - // Global override. Useful for developers, who need to force polling for all - // instances of chokidar, regardless of usage / dependency depth - const envPoll = process.env.CHOKIDAR_USEPOLLING; - if (envPoll !== undefined) { - const envLower = envPoll.toLowerCase(); - if (envLower === 'false' || envLower === '0') - opts.usePolling = false; - else if (envLower === 'true' || envLower === '1') - opts.usePolling = true; - else - opts.usePolling = !!envLower; - } - const envInterval = process.env.CHOKIDAR_INTERVAL; - if (envInterval) - opts.interval = Number.parseInt(envInterval, 10); - // This is done to emit ready only once, but each 'add' will increase that? - let readyCalls = 0; - this._emitReady = () => { - readyCalls++; - if (readyCalls >= this._readyCount) { - this._emitReady = EMPTY_FN; - this._readyEmitted = true; - // use process.nextTick to allow time for listener to be bound - process.nextTick(() => this.emit(EV.READY)); - } - }; - this._emitRaw = (...args) => this.emit(EV.RAW, ...args); - this._boundRemove = this._remove.bind(this); - this.options = opts; - this._nodeFsHandler = new NodeFsHandler(this); - // You’re frozen when your heart’s not open. - Object.freeze(opts); - } - _addIgnoredPath(matcher) { - if (isMatcherObject(matcher)) { - // return early if we already have a deeply equal matcher object - for (const ignored of this._ignoredPaths) { - if (isMatcherObject(ignored) && - ignored.path === matcher.path && - ignored.recursive === matcher.recursive) { - return; - } - } - } - this._ignoredPaths.add(matcher); - } - _removeIgnoredPath(matcher) { - this._ignoredPaths.delete(matcher); - // now find any matcher objects with the matcher as path - if (typeof matcher === 'string') { - for (const ignored of this._ignoredPaths) { - // TODO (43081j): make this more efficient. - // probably just make a `this._ignoredDirectories` or some - // such thing. - if (isMatcherObject(ignored) && ignored.path === matcher) { - this._ignoredPaths.delete(ignored); - } - } - } - } - // Public methods - /** - * Adds paths to be watched on an existing FSWatcher instance. - * @param paths_ file or file list. Other arguments are unused - */ - add(paths_, _origAdd, _internal) { - const { cwd } = this.options; - this.closed = false; - this._closePromise = undefined; - let paths = unifyPaths(paths_); - if (cwd) { - paths = paths.map((path) => { - const absPath = getAbsolutePath(path, cwd); - // Check `path` instead of `absPath` because the cwd portion can't be a glob - return absPath; - }); - } - paths.forEach((path) => { - this._removeIgnoredPath(path); - }); - this._userIgnored = undefined; - if (!this._readyCount) - this._readyCount = 0; - this._readyCount += paths.length; - Promise.all(paths.map(async (path) => { - const res = await this._nodeFsHandler._addToNodeFs(path, !_internal, undefined, 0, _origAdd); - if (res) - this._emitReady(); - return res; - })).then((results) => { - if (this.closed) - return; - results.forEach((item) => { - if (item) - this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item)); - }); - }); - return this; - } - /** - * Close watchers or start ignoring events from specified paths. - */ - unwatch(paths_) { - if (this.closed) - return this; - const paths = unifyPaths(paths_); - const { cwd } = this.options; - paths.forEach((path) => { - // convert to absolute path unless relative path already matches - if (!sysPath.isAbsolute(path) && !this._closers.has(path)) { - if (cwd) - path = sysPath.join(cwd, path); - path = sysPath.resolve(path); - } - this._closePath(path); - this._addIgnoredPath(path); - if (this._watched.has(path)) { - this._addIgnoredPath({ - path, - recursive: true, - }); - } - // reset the cached userIgnored anymatch fn - // to make ignoredPaths changes effective - this._userIgnored = undefined; - }); - return this; - } - /** - * Close watchers and remove all listeners from watched paths. - */ - close() { - if (this._closePromise) { - return this._closePromise; - } - this.closed = true; - // Memory management. - this.removeAllListeners(); - const closers = []; - this._closers.forEach((closerList) => closerList.forEach((closer) => { - const promise = closer(); - if (promise instanceof Promise) - closers.push(promise); - })); - this._streams.forEach((stream) => stream.destroy()); - this._userIgnored = undefined; - this._readyCount = 0; - this._readyEmitted = false; - this._watched.forEach((dirent) => dirent.dispose()); - this._closers.clear(); - this._watched.clear(); - this._streams.clear(); - this._symlinkPaths.clear(); - this._throttled.clear(); - this._closePromise = closers.length - ? Promise.all(closers).then(() => undefined) - : Promise.resolve(); - return this._closePromise; - } - /** - * Expose list of watched paths - * @returns for chaining - */ - getWatched() { - const watchList = {}; - this._watched.forEach((entry, dir) => { - const key = this.options.cwd ? sysPath.relative(this.options.cwd, dir) : dir; - const index = key || ONE_DOT; - watchList[index] = entry.getChildren().sort(); - }); - return watchList; - } - emitWithAll(event, args) { - this.emit(event, ...args); - if (event !== EV.ERROR) - this.emit(EV.ALL, event, ...args); - } - // Common helpers - // -------------- - /** - * Normalize and emit events. - * Calling _emit DOES NOT MEAN emit() would be called! - * @param event Type of event - * @param path File or directory path - * @param stats arguments to be passed with event - * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag - */ - async _emit(event, path, stats) { - if (this.closed) - return; - const opts = this.options; - if (isWindows) - path = sysPath.normalize(path); - if (opts.cwd) - path = sysPath.relative(opts.cwd, path); - const args = [path]; - if (stats != null) - args.push(stats); - const awf = opts.awaitWriteFinish; - let pw; - if (awf && (pw = this._pendingWrites.get(path))) { - pw.lastChange = new Date(); - return this; - } - if (opts.atomic) { - if (event === EV.UNLINK) { - this._pendingUnlinks.set(path, [event, ...args]); - setTimeout(() => { - this._pendingUnlinks.forEach((entry, path) => { - this.emit(...entry); - this.emit(EV.ALL, ...entry); - this._pendingUnlinks.delete(path); - }); - }, typeof opts.atomic === 'number' ? opts.atomic : 100); - return this; - } - if (event === EV.ADD && this._pendingUnlinks.has(path)) { - event = EV.CHANGE; - this._pendingUnlinks.delete(path); - } - } - if (awf && (event === EV.ADD || event === EV.CHANGE) && this._readyEmitted) { - const awfEmit = (err, stats) => { - if (err) { - event = EV.ERROR; - args[0] = err; - this.emitWithAll(event, args); - } - else if (stats) { - // if stats doesn't exist the file must have been deleted - if (args.length > 1) { - args[1] = stats; - } - else { - args.push(stats); - } - this.emitWithAll(event, args); - } - }; - this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit); - return this; - } - if (event === EV.CHANGE) { - const isThrottled = !this._throttle(EV.CHANGE, path, 50); - if (isThrottled) - return this; - } - if (opts.alwaysStat && - stats === undefined && - (event === EV.ADD || event === EV.ADD_DIR || event === EV.CHANGE)) { - const fullPath = opts.cwd ? sysPath.join(opts.cwd, path) : path; - let stats; - try { - stats = await stat(fullPath); - } - catch (err) { - // do nothing - } - // Suppress event when fs_stat fails, to avoid sending undefined 'stat' - if (!stats || this.closed) - return; - args.push(stats); - } - this.emitWithAll(event, args); - return this; - } - /** - * Common handler for errors - * @returns The error if defined, otherwise the value of the FSWatcher instance's `closed` flag - */ - _handleError(error) { - const code = error && error.code; - if (error && - code !== 'ENOENT' && - code !== 'ENOTDIR' && - (!this.options.ignorePermissionErrors || (code !== 'EPERM' && code !== 'EACCES'))) { - this.emit(EV.ERROR, error); - } - return error || this.closed; - } - /** - * Helper utility for throttling - * @param actionType type being throttled - * @param path being acted upon - * @param timeout duration of time to suppress duplicate actions - * @returns tracking object or false if action should be suppressed - */ - _throttle(actionType, path, timeout) { - if (!this._throttled.has(actionType)) { - this._throttled.set(actionType, new Map()); - } - const action = this._throttled.get(actionType); - if (!action) - throw new Error('invalid throttle'); - const actionPath = action.get(path); - if (actionPath) { - actionPath.count++; - return false; - } - // eslint-disable-next-line prefer-const - let timeoutObject; - const clear = () => { - const item = action.get(path); - const count = item ? item.count : 0; - action.delete(path); - clearTimeout(timeoutObject); - if (item) - clearTimeout(item.timeoutObject); - return count; - }; - timeoutObject = setTimeout(clear, timeout); - const thr = { timeoutObject, clear, count: 0 }; - action.set(path, thr); - return thr; - } - _incrReadyCount() { - return this._readyCount++; - } - /** - * Awaits write operation to finish. - * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback. - * @param path being acted upon - * @param threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished - * @param event - * @param awfEmit Callback to be called when ready for event to be emitted. - */ - _awaitWriteFinish(path, threshold, event, awfEmit) { - const awf = this.options.awaitWriteFinish; - if (typeof awf !== 'object') - return; - const pollInterval = awf.pollInterval; - let timeoutHandler; - let fullPath = path; - if (this.options.cwd && !sysPath.isAbsolute(path)) { - fullPath = sysPath.join(this.options.cwd, path); - } - const now = new Date(); - const writes = this._pendingWrites; - function awaitWriteFinishFn(prevStat) { - statcb(fullPath, (err, curStat) => { - if (err || !writes.has(path)) { - if (err && err.code !== 'ENOENT') - awfEmit(err); - return; - } - const now = Number(new Date()); - if (prevStat && curStat.size !== prevStat.size) { - writes.get(path).lastChange = now; - } - const pw = writes.get(path); - const df = now - pw.lastChange; - if (df >= threshold) { - writes.delete(path); - awfEmit(undefined, curStat); - } - else { - timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat); - } - }); - } - if (!writes.has(path)) { - writes.set(path, { - lastChange: now, - cancelWait: () => { - writes.delete(path); - clearTimeout(timeoutHandler); - return event; - }, - }); - timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval); - } - } - /** - * Determines whether user has asked to ignore this path. - */ - _isIgnored(path, stats) { - if (this.options.atomic && DOT_RE.test(path)) - return true; - if (!this._userIgnored) { - const { cwd } = this.options; - const ign = this.options.ignored; - const ignored = (ign || []).map(normalizeIgnored(cwd)); - const ignoredPaths = [...this._ignoredPaths]; - const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored]; - this._userIgnored = anymatch(list, undefined); - } - return this._userIgnored(path, stats); - } - _isntIgnored(path, stat) { - return !this._isIgnored(path, stat); - } - /** - * Provides a set of common helpers and properties relating to symlink handling. - * @param path file or directory pattern being watched - */ - _getWatchHelpers(path) { - return new WatchHelper(path, this.options.followSymlinks, this); - } - // Directory helpers - // ----------------- - /** - * Provides directory tracking objects - * @param directory path of the directory - */ - _getWatchedDir(directory) { - const dir = sysPath.resolve(directory); - if (!this._watched.has(dir)) - this._watched.set(dir, new DirEntry(dir, this._boundRemove)); - return this._watched.get(dir); - } - // File helpers - // ------------ - /** - * Check for read permissions: https://stackoverflow.com/a/11781404/1358405 - */ - _hasReadPermissions(stats) { - if (this.options.ignorePermissionErrors) - return true; - return Boolean(Number(stats.mode) & 0o400); - } - /** - * Handles emitting unlink events for - * files and directories, and via recursion, for - * files and directories within directories that are unlinked - * @param directory within which the following item is located - * @param item base path of item/directory - */ - _remove(directory, item, isDirectory) { - // if what is being deleted is a directory, get that directory's paths - // for recursive deleting and cleaning of watched object - // if it is not a directory, nestedDirectoryChildren will be empty array - const path = sysPath.join(directory, item); - const fullPath = sysPath.resolve(path); - isDirectory = - isDirectory != null ? isDirectory : this._watched.has(path) || this._watched.has(fullPath); - // prevent duplicate handling in case of arriving here nearly simultaneously - // via multiple paths (such as _handleFile and _handleDir) - if (!this._throttle('remove', path, 100)) - return; - // if the only watched file is removed, watch for its return - if (!isDirectory && this._watched.size === 1) { - this.add(directory, item, true); - } - // This will create a new entry in the watched object in either case - // so we got to do the directory check beforehand - const wp = this._getWatchedDir(path); - const nestedDirectoryChildren = wp.getChildren(); - // Recursively remove children directories / files. - nestedDirectoryChildren.forEach((nested) => this._remove(path, nested)); - // Check if item was on the watched list and remove it - const parent = this._getWatchedDir(directory); - const wasTracked = parent.has(item); - parent.remove(item); - // Fixes issue #1042 -> Relative paths were detected and added as symlinks - // (https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L612), - // but never removed from the map in case the path was deleted. - // This leads to an incorrect state if the path was recreated: - // https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L553 - if (this._symlinkPaths.has(fullPath)) { - this._symlinkPaths.delete(fullPath); - } - // If we wait for this file to be fully written, cancel the wait. - let relPath = path; - if (this.options.cwd) - relPath = sysPath.relative(this.options.cwd, path); - if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) { - const event = this._pendingWrites.get(relPath).cancelWait(); - if (event === EV.ADD) - return; - } - // The Entry will either be a directory that just got removed - // or a bogus entry to a file, in either case we have to remove it - this._watched.delete(path); - this._watched.delete(fullPath); - const eventName = isDirectory ? EV.UNLINK_DIR : EV.UNLINK; - if (wasTracked && !this._isIgnored(path)) - this._emit(eventName, path); - // Avoid conflicts if we later create another file with the same name - this._closePath(path); - } - /** - * Closes all watchers for a path - */ - _closePath(path) { - this._closeFile(path); - const dir = sysPath.dirname(path); - this._getWatchedDir(dir).remove(sysPath.basename(path)); - } - /** - * Closes only file-specific watchers - */ - _closeFile(path) { - const closers = this._closers.get(path); - if (!closers) - return; - closers.forEach((closer) => closer()); - this._closers.delete(path); - } - _addPathCloser(path, closer) { - if (!closer) - return; - let list = this._closers.get(path); - if (!list) { - list = []; - this._closers.set(path, list); - } - list.push(closer); - } - _readdirp(root, opts) { - if (this.closed) - return; - const options = { type: EV.ALL, alwaysStat: true, lstat: true, ...opts, depth: 0 }; - let stream = readdirp(root, options); - this._streams.add(stream); - stream.once(STR_CLOSE, () => { - stream = undefined; - }); - stream.once(STR_END, () => { - if (stream) { - this._streams.delete(stream); - stream = undefined; - } - }); - return stream; - } -} -/** - * Instantiates watcher with paths to be tracked. - * @param paths file / directory paths - * @param options opts, such as `atomic`, `awaitWriteFinish`, `ignored`, and others - * @returns an instance of FSWatcher for chaining. - * @example - * const watcher = watch('.').on('all', (event, path) => { console.log(event, path); }); - * watch('.', { atomic: true, awaitWriteFinish: true, ignored: (f, stats) => stats?.isFile() && !f.endsWith('.js') }) - */ -export function watch(paths, options = {}) { - const watcher = new FSWatcher(options); - watcher.add(paths); - return watcher; -} -export default { watch, FSWatcher }; diff --git a/node_modules/chokidar/esm/package.json b/node_modules/chokidar/esm/package.json deleted file mode 100644 index 8769641..0000000 --- a/node_modules/chokidar/esm/package.json +++ /dev/null @@ -1 +0,0 @@ -{ "type": "module", "sideEffects": false } diff --git a/node_modules/chokidar/handler.d.ts b/node_modules/chokidar/handler.d.ts deleted file mode 100644 index ea777d0..0000000 --- a/node_modules/chokidar/handler.d.ts +++ /dev/null @@ -1,90 +0,0 @@ -import type { WatchEventType, Stats, FSWatcher as NativeFsWatcher } from 'fs'; -import type { FSWatcher, WatchHelper, Throttler } from './index.js'; -import type { EntryInfo } from 'readdirp'; -export type Path = string; -export declare const STR_DATA = "data"; -export declare const STR_END = "end"; -export declare const STR_CLOSE = "close"; -export declare const EMPTY_FN: () => void; -export declare const IDENTITY_FN: (val: unknown) => unknown; -export declare const isWindows: boolean; -export declare const isMacos: boolean; -export declare const isLinux: boolean; -export declare const isFreeBSD: boolean; -export declare const isIBMi: boolean; -export declare const EVENTS: { - readonly ALL: "all"; - readonly READY: "ready"; - readonly ADD: "add"; - readonly CHANGE: "change"; - readonly ADD_DIR: "addDir"; - readonly UNLINK: "unlink"; - readonly UNLINK_DIR: "unlinkDir"; - readonly RAW: "raw"; - readonly ERROR: "error"; -}; -export type EventName = (typeof EVENTS)[keyof typeof EVENTS]; -export type FsWatchContainer = { - listeners: (path: string) => void | Set; - errHandlers: (err: unknown) => void | Set; - rawEmitters: (ev: WatchEventType, path: string, opts: unknown) => void | Set; - watcher: NativeFsWatcher; - watcherUnusable?: boolean; -}; -export interface WatchHandlers { - listener: (path: string) => void; - errHandler: (err: unknown) => void; - rawEmitter: (ev: WatchEventType, path: string, opts: unknown) => void; -} -/** - * @mixin - */ -export declare class NodeFsHandler { - fsw: FSWatcher; - _boundHandleError: (error: unknown) => void; - constructor(fsW: FSWatcher); - /** - * Watch file for changes with fs_watchFile or fs_watch. - * @param path to file or dir - * @param listener on fs change - * @returns closer for the watcher instance - */ - _watchWithNodeFs(path: string, listener: (path: string, newStats?: any) => void | Promise): (() => void) | undefined; - /** - * Watch a file and emit add event if warranted. - * @returns closer for the watcher instance - */ - _handleFile(file: Path, stats: Stats, initialAdd: boolean): (() => void) | undefined; - /** - * Handle symlinks encountered while reading a dir. - * @param entry returned by readdirp - * @param directory path of dir being read - * @param path of this item - * @param item basename of this item - * @returns true if no more processing is needed for this entry. - */ - _handleSymlink(entry: EntryInfo, directory: string, path: Path, item: string): Promise; - _handleRead(directory: string, initialAdd: boolean, wh: WatchHelper, target: Path, dir: Path, depth: number, throttler: Throttler): Promise | undefined; - /** - * Read directory to add / remove files from `@watched` list and re-read it on change. - * @param dir fs path - * @param stats - * @param initialAdd - * @param depth relative to user-supplied path - * @param target child path targeted for watch - * @param wh Common watch helpers for this path - * @param realpath - * @returns closer for the watcher instance. - */ - _handleDir(dir: string, stats: Stats, initialAdd: boolean, depth: number, target: string, wh: WatchHelper, realpath: string): Promise<(() => void) | undefined>; - /** - * Handle added file, directory, or glob pattern. - * Delegates call to _handleFile / _handleDir after checks. - * @param path to file or ir - * @param initialAdd was the file added at watch instantiation? - * @param priorWh depth relative to user-supplied path - * @param depth Child path actually targeted for watch - * @param target Child path actually targeted for watch - */ - _addToNodeFs(path: string, initialAdd: boolean, priorWh: WatchHelper | undefined, depth: number, target?: string): Promise; -} diff --git a/node_modules/chokidar/handler.js b/node_modules/chokidar/handler.js deleted file mode 100644 index 9c2ef28..0000000 --- a/node_modules/chokidar/handler.js +++ /dev/null @@ -1,635 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.NodeFsHandler = exports.EVENTS = exports.isIBMi = exports.isFreeBSD = exports.isLinux = exports.isMacos = exports.isWindows = exports.IDENTITY_FN = exports.EMPTY_FN = exports.STR_CLOSE = exports.STR_END = exports.STR_DATA = void 0; -const fs_1 = require("fs"); -const promises_1 = require("fs/promises"); -const sysPath = require("path"); -const os_1 = require("os"); -exports.STR_DATA = 'data'; -exports.STR_END = 'end'; -exports.STR_CLOSE = 'close'; -const EMPTY_FN = () => { }; -exports.EMPTY_FN = EMPTY_FN; -const IDENTITY_FN = (val) => val; -exports.IDENTITY_FN = IDENTITY_FN; -const pl = process.platform; -exports.isWindows = pl === 'win32'; -exports.isMacos = pl === 'darwin'; -exports.isLinux = pl === 'linux'; -exports.isFreeBSD = pl === 'freebsd'; -exports.isIBMi = (0, os_1.type)() === 'OS400'; -exports.EVENTS = { - ALL: 'all', - READY: 'ready', - ADD: 'add', - CHANGE: 'change', - ADD_DIR: 'addDir', - UNLINK: 'unlink', - UNLINK_DIR: 'unlinkDir', - RAW: 'raw', - ERROR: 'error', -}; -const EV = exports.EVENTS; -const THROTTLE_MODE_WATCH = 'watch'; -const statMethods = { lstat: promises_1.lstat, stat: promises_1.stat }; -const KEY_LISTENERS = 'listeners'; -const KEY_ERR = 'errHandlers'; -const KEY_RAW = 'rawEmitters'; -const HANDLER_KEYS = [KEY_LISTENERS, KEY_ERR, KEY_RAW]; -// prettier-ignore -const binaryExtensions = new Set([ - '3dm', '3ds', '3g2', '3gp', '7z', 'a', 'aac', 'adp', 'afdesign', 'afphoto', 'afpub', 'ai', - 'aif', 'aiff', 'alz', 'ape', 'apk', 'appimage', 'ar', 'arj', 'asf', 'au', 'avi', - 'bak', 'baml', 'bh', 'bin', 'bk', 'bmp', 'btif', 'bz2', 'bzip2', - 'cab', 'caf', 'cgm', 'class', 'cmx', 'cpio', 'cr2', 'cur', 'dat', 'dcm', 'deb', 'dex', 'djvu', - 'dll', 'dmg', 'dng', 'doc', 'docm', 'docx', 'dot', 'dotm', 'dra', 'DS_Store', 'dsk', 'dts', - 'dtshd', 'dvb', 'dwg', 'dxf', - 'ecelp4800', 'ecelp7470', 'ecelp9600', 'egg', 'eol', 'eot', 'epub', 'exe', - 'f4v', 'fbs', 'fh', 'fla', 'flac', 'flatpak', 'fli', 'flv', 'fpx', 'fst', 'fvt', - 'g3', 'gh', 'gif', 'graffle', 'gz', 'gzip', - 'h261', 'h263', 'h264', 'icns', 'ico', 'ief', 'img', 'ipa', 'iso', - 'jar', 'jpeg', 'jpg', 'jpgv', 'jpm', 'jxr', 'key', 'ktx', - 'lha', 'lib', 'lvp', 'lz', 'lzh', 'lzma', 'lzo', - 'm3u', 'm4a', 'm4v', 'mar', 'mdi', 'mht', 'mid', 'midi', 'mj2', 'mka', 'mkv', 'mmr', 'mng', - 'mobi', 'mov', 'movie', 'mp3', - 'mp4', 'mp4a', 'mpeg', 'mpg', 'mpga', 'mxu', - 'nef', 'npx', 'numbers', 'nupkg', - 'o', 'odp', 'ods', 'odt', 'oga', 'ogg', 'ogv', 'otf', 'ott', - 'pages', 'pbm', 'pcx', 'pdb', 'pdf', 'pea', 'pgm', 'pic', 'png', 'pnm', 'pot', 'potm', - 'potx', 'ppa', 'ppam', - 'ppm', 'pps', 'ppsm', 'ppsx', 'ppt', 'pptm', 'pptx', 'psd', 'pya', 'pyc', 'pyo', 'pyv', - 'qt', - 'rar', 'ras', 'raw', 'resources', 'rgb', 'rip', 'rlc', 'rmf', 'rmvb', 'rpm', 'rtf', 'rz', - 's3m', 's7z', 'scpt', 'sgi', 'shar', 'snap', 'sil', 'sketch', 'slk', 'smv', 'snk', 'so', - 'stl', 'suo', 'sub', 'swf', - 'tar', 'tbz', 'tbz2', 'tga', 'tgz', 'thmx', 'tif', 'tiff', 'tlz', 'ttc', 'ttf', 'txz', - 'udf', 'uvh', 'uvi', 'uvm', 'uvp', 'uvs', 'uvu', - 'viv', 'vob', - 'war', 'wav', 'wax', 'wbmp', 'wdp', 'weba', 'webm', 'webp', 'whl', 'wim', 'wm', 'wma', - 'wmv', 'wmx', 'woff', 'woff2', 'wrm', 'wvx', - 'xbm', 'xif', 'xla', 'xlam', 'xls', 'xlsb', 'xlsm', 'xlsx', 'xlt', 'xltm', 'xltx', 'xm', - 'xmind', 'xpi', 'xpm', 'xwd', 'xz', - 'z', 'zip', 'zipx', -]); -const isBinaryPath = (filePath) => binaryExtensions.has(sysPath.extname(filePath).slice(1).toLowerCase()); -// TODO: emit errors properly. Example: EMFILE on Macos. -const foreach = (val, fn) => { - if (val instanceof Set) { - val.forEach(fn); - } - else { - fn(val); - } -}; -const addAndConvert = (main, prop, item) => { - let container = main[prop]; - if (!(container instanceof Set)) { - main[prop] = container = new Set([container]); - } - container.add(item); -}; -const clearItem = (cont) => (key) => { - const set = cont[key]; - if (set instanceof Set) { - set.clear(); - } - else { - delete cont[key]; - } -}; -const delFromSet = (main, prop, item) => { - const container = main[prop]; - if (container instanceof Set) { - container.delete(item); - } - else if (container === item) { - delete main[prop]; - } -}; -const isEmptySet = (val) => (val instanceof Set ? val.size === 0 : !val); -const FsWatchInstances = new Map(); -/** - * Instantiates the fs_watch interface - * @param path to be watched - * @param options to be passed to fs_watch - * @param listener main event handler - * @param errHandler emits info about errors - * @param emitRaw emits raw event data - * @returns {NativeFsWatcher} - */ -function createFsWatchInstance(path, options, listener, errHandler, emitRaw) { - const handleEvent = (rawEvent, evPath) => { - listener(path); - emitRaw(rawEvent, evPath, { watchedPath: path }); - // emit based on events occurring for files from a directory's watcher in - // case the file's watcher misses it (and rely on throttling to de-dupe) - if (evPath && path !== evPath) { - fsWatchBroadcast(sysPath.resolve(path, evPath), KEY_LISTENERS, sysPath.join(path, evPath)); - } - }; - try { - return (0, fs_1.watch)(path, { - persistent: options.persistent, - }, handleEvent); - } - catch (error) { - errHandler(error); - return undefined; - } -} -/** - * Helper for passing fs_watch event data to a collection of listeners - * @param fullPath absolute path bound to fs_watch instance - */ -const fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => { - const cont = FsWatchInstances.get(fullPath); - if (!cont) - return; - foreach(cont[listenerType], (listener) => { - listener(val1, val2, val3); - }); -}; -/** - * Instantiates the fs_watch interface or binds listeners - * to an existing one covering the same file system entry - * @param path - * @param fullPath absolute path - * @param options to be passed to fs_watch - * @param handlers container for event listener functions - */ -const setFsWatchListener = (path, fullPath, options, handlers) => { - const { listener, errHandler, rawEmitter } = handlers; - let cont = FsWatchInstances.get(fullPath); - let watcher; - if (!options.persistent) { - watcher = createFsWatchInstance(path, options, listener, errHandler, rawEmitter); - if (!watcher) - return; - return watcher.close.bind(watcher); - } - if (cont) { - addAndConvert(cont, KEY_LISTENERS, listener); - addAndConvert(cont, KEY_ERR, errHandler); - addAndConvert(cont, KEY_RAW, rawEmitter); - } - else { - watcher = createFsWatchInstance(path, options, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, // no need to use broadcast here - fsWatchBroadcast.bind(null, fullPath, KEY_RAW)); - if (!watcher) - return; - watcher.on(EV.ERROR, async (error) => { - const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR); - if (cont) - cont.watcherUnusable = true; // documented since Node 10.4.1 - // Workaround for https://github.com/joyent/node/issues/4337 - if (exports.isWindows && error.code === 'EPERM') { - try { - const fd = await (0, promises_1.open)(path, 'r'); - await fd.close(); - broadcastErr(error); - } - catch (err) { - // do nothing - } - } - else { - broadcastErr(error); - } - }); - cont = { - listeners: listener, - errHandlers: errHandler, - rawEmitters: rawEmitter, - watcher, - }; - FsWatchInstances.set(fullPath, cont); - } - // const index = cont.listeners.indexOf(listener); - // removes this instance's listeners and closes the underlying fs_watch - // instance if there are no more listeners left - return () => { - delFromSet(cont, KEY_LISTENERS, listener); - delFromSet(cont, KEY_ERR, errHandler); - delFromSet(cont, KEY_RAW, rawEmitter); - if (isEmptySet(cont.listeners)) { - // Check to protect against issue gh-730. - // if (cont.watcherUnusable) { - cont.watcher.close(); - // } - FsWatchInstances.delete(fullPath); - HANDLER_KEYS.forEach(clearItem(cont)); - // @ts-ignore - cont.watcher = undefined; - Object.freeze(cont); - } - }; -}; -// fs_watchFile helpers -// object to hold per-process fs_watchFile instances -// (may be shared across chokidar FSWatcher instances) -const FsWatchFileInstances = new Map(); -/** - * Instantiates the fs_watchFile interface or binds listeners - * to an existing one covering the same file system entry - * @param path to be watched - * @param fullPath absolute path - * @param options options to be passed to fs_watchFile - * @param handlers container for event listener functions - * @returns closer - */ -const setFsWatchFileListener = (path, fullPath, options, handlers) => { - const { listener, rawEmitter } = handlers; - let cont = FsWatchFileInstances.get(fullPath); - // let listeners = new Set(); - // let rawEmitters = new Set(); - const copts = cont && cont.options; - if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) { - // "Upgrade" the watcher to persistence or a quicker interval. - // This creates some unlikely edge case issues if the user mixes - // settings in a very weird way, but solving for those cases - // doesn't seem worthwhile for the added complexity. - // listeners = cont.listeners; - // rawEmitters = cont.rawEmitters; - (0, fs_1.unwatchFile)(fullPath); - cont = undefined; - } - if (cont) { - addAndConvert(cont, KEY_LISTENERS, listener); - addAndConvert(cont, KEY_RAW, rawEmitter); - } - else { - // TODO - // listeners.add(listener); - // rawEmitters.add(rawEmitter); - cont = { - listeners: listener, - rawEmitters: rawEmitter, - options, - watcher: (0, fs_1.watchFile)(fullPath, options, (curr, prev) => { - foreach(cont.rawEmitters, (rawEmitter) => { - rawEmitter(EV.CHANGE, fullPath, { curr, prev }); - }); - const currmtime = curr.mtimeMs; - if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) { - foreach(cont.listeners, (listener) => listener(path, curr)); - } - }), - }; - FsWatchFileInstances.set(fullPath, cont); - } - // const index = cont.listeners.indexOf(listener); - // Removes this instance's listeners and closes the underlying fs_watchFile - // instance if there are no more listeners left. - return () => { - delFromSet(cont, KEY_LISTENERS, listener); - delFromSet(cont, KEY_RAW, rawEmitter); - if (isEmptySet(cont.listeners)) { - FsWatchFileInstances.delete(fullPath); - (0, fs_1.unwatchFile)(fullPath); - cont.options = cont.watcher = undefined; - Object.freeze(cont); - } - }; -}; -/** - * @mixin - */ -class NodeFsHandler { - constructor(fsW) { - this.fsw = fsW; - this._boundHandleError = (error) => fsW._handleError(error); - } - /** - * Watch file for changes with fs_watchFile or fs_watch. - * @param path to file or dir - * @param listener on fs change - * @returns closer for the watcher instance - */ - _watchWithNodeFs(path, listener) { - const opts = this.fsw.options; - const directory = sysPath.dirname(path); - const basename = sysPath.basename(path); - const parent = this.fsw._getWatchedDir(directory); - parent.add(basename); - const absolutePath = sysPath.resolve(path); - const options = { - persistent: opts.persistent, - }; - if (!listener) - listener = exports.EMPTY_FN; - let closer; - if (opts.usePolling) { - const enableBin = opts.interval !== opts.binaryInterval; - options.interval = enableBin && isBinaryPath(basename) ? opts.binaryInterval : opts.interval; - closer = setFsWatchFileListener(path, absolutePath, options, { - listener, - rawEmitter: this.fsw._emitRaw, - }); - } - else { - closer = setFsWatchListener(path, absolutePath, options, { - listener, - errHandler: this._boundHandleError, - rawEmitter: this.fsw._emitRaw, - }); - } - return closer; - } - /** - * Watch a file and emit add event if warranted. - * @returns closer for the watcher instance - */ - _handleFile(file, stats, initialAdd) { - if (this.fsw.closed) { - return; - } - const dirname = sysPath.dirname(file); - const basename = sysPath.basename(file); - const parent = this.fsw._getWatchedDir(dirname); - // stats is always present - let prevStats = stats; - // if the file is already being watched, do nothing - if (parent.has(basename)) - return; - const listener = async (path, newStats) => { - if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5)) - return; - if (!newStats || newStats.mtimeMs === 0) { - try { - const newStats = await (0, promises_1.stat)(file); - if (this.fsw.closed) - return; - // Check that change event was not fired because of changed only accessTime. - const at = newStats.atimeMs; - const mt = newStats.mtimeMs; - if (!at || at <= mt || mt !== prevStats.mtimeMs) { - this.fsw._emit(EV.CHANGE, file, newStats); - } - if ((exports.isMacos || exports.isLinux || exports.isFreeBSD) && prevStats.ino !== newStats.ino) { - this.fsw._closeFile(path); - prevStats = newStats; - const closer = this._watchWithNodeFs(file, listener); - if (closer) - this.fsw._addPathCloser(path, closer); - } - else { - prevStats = newStats; - } - } - catch (error) { - // Fix issues where mtime is null but file is still present - this.fsw._remove(dirname, basename); - } - // add is about to be emitted if file not already tracked in parent - } - else if (parent.has(basename)) { - // Check that change event was not fired because of changed only accessTime. - const at = newStats.atimeMs; - const mt = newStats.mtimeMs; - if (!at || at <= mt || mt !== prevStats.mtimeMs) { - this.fsw._emit(EV.CHANGE, file, newStats); - } - prevStats = newStats; - } - }; - // kick off the watcher - const closer = this._watchWithNodeFs(file, listener); - // emit an add event if we're supposed to - if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) { - if (!this.fsw._throttle(EV.ADD, file, 0)) - return; - this.fsw._emit(EV.ADD, file, stats); - } - return closer; - } - /** - * Handle symlinks encountered while reading a dir. - * @param entry returned by readdirp - * @param directory path of dir being read - * @param path of this item - * @param item basename of this item - * @returns true if no more processing is needed for this entry. - */ - async _handleSymlink(entry, directory, path, item) { - if (this.fsw.closed) { - return; - } - const full = entry.fullPath; - const dir = this.fsw._getWatchedDir(directory); - if (!this.fsw.options.followSymlinks) { - // watch symlink directly (don't follow) and detect changes - this.fsw._incrReadyCount(); - let linkPath; - try { - linkPath = await (0, promises_1.realpath)(path); - } - catch (e) { - this.fsw._emitReady(); - return true; - } - if (this.fsw.closed) - return; - if (dir.has(item)) { - if (this.fsw._symlinkPaths.get(full) !== linkPath) { - this.fsw._symlinkPaths.set(full, linkPath); - this.fsw._emit(EV.CHANGE, path, entry.stats); - } - } - else { - dir.add(item); - this.fsw._symlinkPaths.set(full, linkPath); - this.fsw._emit(EV.ADD, path, entry.stats); - } - this.fsw._emitReady(); - return true; - } - // don't follow the same symlink more than once - if (this.fsw._symlinkPaths.has(full)) { - return true; - } - this.fsw._symlinkPaths.set(full, true); - } - _handleRead(directory, initialAdd, wh, target, dir, depth, throttler) { - // Normalize the directory name on Windows - directory = sysPath.join(directory, ''); - throttler = this.fsw._throttle('readdir', directory, 1000); - if (!throttler) - return; - const previous = this.fsw._getWatchedDir(wh.path); - const current = new Set(); - let stream = this.fsw._readdirp(directory, { - fileFilter: (entry) => wh.filterPath(entry), - directoryFilter: (entry) => wh.filterDir(entry), - }); - if (!stream) - return; - stream - .on(exports.STR_DATA, async (entry) => { - if (this.fsw.closed) { - stream = undefined; - return; - } - const item = entry.path; - let path = sysPath.join(directory, item); - current.add(item); - if (entry.stats.isSymbolicLink() && - (await this._handleSymlink(entry, directory, path, item))) { - return; - } - if (this.fsw.closed) { - stream = undefined; - return; - } - // Files that present in current directory snapshot - // but absent in previous are added to watch list and - // emit `add` event. - if (item === target || (!target && !previous.has(item))) { - this.fsw._incrReadyCount(); - // ensure relativeness of path is preserved in case of watcher reuse - path = sysPath.join(dir, sysPath.relative(dir, path)); - this._addToNodeFs(path, initialAdd, wh, depth + 1); - } - }) - .on(EV.ERROR, this._boundHandleError); - return new Promise((resolve, reject) => { - if (!stream) - return reject(); - stream.once(exports.STR_END, () => { - if (this.fsw.closed) { - stream = undefined; - return; - } - const wasThrottled = throttler ? throttler.clear() : false; - resolve(undefined); - // Files that absent in current directory snapshot - // but present in previous emit `remove` event - // and are removed from @watched[directory]. - previous - .getChildren() - .filter((item) => { - return item !== directory && !current.has(item); - }) - .forEach((item) => { - this.fsw._remove(directory, item); - }); - stream = undefined; - // one more time for any missed in case changes came in extremely quickly - if (wasThrottled) - this._handleRead(directory, false, wh, target, dir, depth, throttler); - }); - }); - } - /** - * Read directory to add / remove files from `@watched` list and re-read it on change. - * @param dir fs path - * @param stats - * @param initialAdd - * @param depth relative to user-supplied path - * @param target child path targeted for watch - * @param wh Common watch helpers for this path - * @param realpath - * @returns closer for the watcher instance. - */ - async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath) { - const parentDir = this.fsw._getWatchedDir(sysPath.dirname(dir)); - const tracked = parentDir.has(sysPath.basename(dir)); - if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) { - this.fsw._emit(EV.ADD_DIR, dir, stats); - } - // ensure dir is tracked (harmless if redundant) - parentDir.add(sysPath.basename(dir)); - this.fsw._getWatchedDir(dir); - let throttler; - let closer; - const oDepth = this.fsw.options.depth; - if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath)) { - if (!target) { - await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler); - if (this.fsw.closed) - return; - } - closer = this._watchWithNodeFs(dir, (dirPath, stats) => { - // if current directory is removed, do nothing - if (stats && stats.mtimeMs === 0) - return; - this._handleRead(dirPath, false, wh, target, dir, depth, throttler); - }); - } - return closer; - } - /** - * Handle added file, directory, or glob pattern. - * Delegates call to _handleFile / _handleDir after checks. - * @param path to file or ir - * @param initialAdd was the file added at watch instantiation? - * @param priorWh depth relative to user-supplied path - * @param depth Child path actually targeted for watch - * @param target Child path actually targeted for watch - */ - async _addToNodeFs(path, initialAdd, priorWh, depth, target) { - const ready = this.fsw._emitReady; - if (this.fsw._isIgnored(path) || this.fsw.closed) { - ready(); - return false; - } - const wh = this.fsw._getWatchHelpers(path); - if (priorWh) { - wh.filterPath = (entry) => priorWh.filterPath(entry); - wh.filterDir = (entry) => priorWh.filterDir(entry); - } - // evaluate what is at the path we're being asked to watch - try { - const stats = await statMethods[wh.statMethod](wh.watchPath); - if (this.fsw.closed) - return; - if (this.fsw._isIgnored(wh.watchPath, stats)) { - ready(); - return false; - } - const follow = this.fsw.options.followSymlinks; - let closer; - if (stats.isDirectory()) { - const absPath = sysPath.resolve(path); - const targetPath = follow ? await (0, promises_1.realpath)(path) : path; - if (this.fsw.closed) - return; - closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath); - if (this.fsw.closed) - return; - // preserve this symlink's target path - if (absPath !== targetPath && targetPath !== undefined) { - this.fsw._symlinkPaths.set(absPath, targetPath); - } - } - else if (stats.isSymbolicLink()) { - const targetPath = follow ? await (0, promises_1.realpath)(path) : path; - if (this.fsw.closed) - return; - const parent = sysPath.dirname(wh.watchPath); - this.fsw._getWatchedDir(parent).add(wh.watchPath); - this.fsw._emit(EV.ADD, wh.watchPath, stats); - closer = await this._handleDir(parent, stats, initialAdd, depth, path, wh, targetPath); - if (this.fsw.closed) - return; - // preserve this symlink's target path - if (targetPath !== undefined) { - this.fsw._symlinkPaths.set(sysPath.resolve(path), targetPath); - } - } - else { - closer = this._handleFile(wh.watchPath, stats, initialAdd); - } - ready(); - if (closer) - this.fsw._addPathCloser(path, closer); - return false; - } - catch (error) { - if (this.fsw._handleError(error)) { - ready(); - return path; - } - } - } -} -exports.NodeFsHandler = NodeFsHandler; diff --git a/node_modules/chokidar/index.d.ts b/node_modules/chokidar/index.d.ts deleted file mode 100644 index ffeb1e7..0000000 --- a/node_modules/chokidar/index.d.ts +++ /dev/null @@ -1,215 +0,0 @@ -/*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) */ -import { Stats } from 'fs'; -import { EventEmitter } from 'events'; -import { ReaddirpStream, ReaddirpOptions, EntryInfo } from 'readdirp'; -import { NodeFsHandler, EventName, Path, EVENTS as EV, WatchHandlers } from './handler.js'; -type AWF = { - stabilityThreshold: number; - pollInterval: number; -}; -type BasicOpts = { - persistent: boolean; - ignoreInitial: boolean; - followSymlinks: boolean; - cwd?: string; - usePolling: boolean; - interval: number; - binaryInterval: number; - alwaysStat?: boolean; - depth?: number; - ignorePermissionErrors: boolean; - atomic: boolean | number; -}; -export type Throttler = { - timeoutObject: NodeJS.Timeout; - clear: () => void; - count: number; -}; -export type ChokidarOptions = Partial; -}>; -export type FSWInstanceOptions = BasicOpts & { - ignored: Matcher[]; - awaitWriteFinish: false | AWF; -}; -export type ThrottleType = 'readdir' | 'watch' | 'add' | 'remove' | 'change'; -export type EmitArgs = [path: Path, stats?: Stats]; -export type EmitErrorArgs = [error: Error, stats?: Stats]; -export type EmitArgsWithName = [event: EventName, ...EmitArgs]; -export type MatchFunction = (val: string, stats?: Stats) => boolean; -export interface MatcherObject { - path: string; - recursive?: boolean; -} -export type Matcher = string | RegExp | MatchFunction | MatcherObject; -/** - * Directory entry. - */ -declare class DirEntry { - path: Path; - _removeWatcher: (dir: string, base: string) => void; - items: Set; - constructor(dir: Path, removeWatcher: (dir: string, base: string) => void); - add(item: string): void; - remove(item: string): Promise; - has(item: string): boolean | undefined; - getChildren(): string[]; - dispose(): void; -} -export declare class WatchHelper { - fsw: FSWatcher; - path: string; - watchPath: string; - fullWatchPath: string; - dirParts: string[][]; - followSymlinks: boolean; - statMethod: 'stat' | 'lstat'; - constructor(path: string, follow: boolean, fsw: FSWatcher); - entryPath(entry: EntryInfo): Path; - filterPath(entry: EntryInfo): boolean; - filterDir(entry: EntryInfo): boolean; -} -export interface FSWatcherKnownEventMap { - [EV.READY]: []; - [EV.RAW]: Parameters; - [EV.ERROR]: Parameters; - [EV.ALL]: [event: EventName, ...EmitArgs]; -} -export type FSWatcherEventMap = FSWatcherKnownEventMap & { - [k in Exclude]: EmitArgs; -}; -/** - * Watches files & directories for changes. Emitted events: - * `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error` - * - * new FSWatcher() - * .add(directories) - * .on('add', path => log('File', path, 'was added')) - */ -export declare class FSWatcher extends EventEmitter { - closed: boolean; - options: FSWInstanceOptions; - _closers: Map>; - _ignoredPaths: Set; - _throttled: Map>; - _streams: Set; - _symlinkPaths: Map; - _watched: Map; - _pendingWrites: Map; - _pendingUnlinks: Map; - _readyCount: number; - _emitReady: () => void; - _closePromise?: Promise; - _userIgnored?: MatchFunction; - _readyEmitted: boolean; - _emitRaw: WatchHandlers['rawEmitter']; - _boundRemove: (dir: string, item: string) => void; - _nodeFsHandler: NodeFsHandler; - constructor(_opts?: ChokidarOptions); - _addIgnoredPath(matcher: Matcher): void; - _removeIgnoredPath(matcher: Matcher): void; - /** - * Adds paths to be watched on an existing FSWatcher instance. - * @param paths_ file or file list. Other arguments are unused - */ - add(paths_: Path | Path[], _origAdd?: string, _internal?: boolean): FSWatcher; - /** - * Close watchers or start ignoring events from specified paths. - */ - unwatch(paths_: Path | Path[]): FSWatcher; - /** - * Close watchers and remove all listeners from watched paths. - */ - close(): Promise; - /** - * Expose list of watched paths - * @returns for chaining - */ - getWatched(): Record; - emitWithAll(event: EventName, args: EmitArgs): void; - /** - * Normalize and emit events. - * Calling _emit DOES NOT MEAN emit() would be called! - * @param event Type of event - * @param path File or directory path - * @param stats arguments to be passed with event - * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag - */ - _emit(event: EventName, path: Path, stats?: Stats): Promise; - /** - * Common handler for errors - * @returns The error if defined, otherwise the value of the FSWatcher instance's `closed` flag - */ - _handleError(error: Error): Error | boolean; - /** - * Helper utility for throttling - * @param actionType type being throttled - * @param path being acted upon - * @param timeout duration of time to suppress duplicate actions - * @returns tracking object or false if action should be suppressed - */ - _throttle(actionType: ThrottleType, path: Path, timeout: number): Throttler | false; - _incrReadyCount(): number; - /** - * Awaits write operation to finish. - * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback. - * @param path being acted upon - * @param threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished - * @param event - * @param awfEmit Callback to be called when ready for event to be emitted. - */ - _awaitWriteFinish(path: Path, threshold: number, event: EventName, awfEmit: (err?: Error, stat?: Stats) => void): void; - /** - * Determines whether user has asked to ignore this path. - */ - _isIgnored(path: Path, stats?: Stats): boolean; - _isntIgnored(path: Path, stat?: Stats): boolean; - /** - * Provides a set of common helpers and properties relating to symlink handling. - * @param path file or directory pattern being watched - */ - _getWatchHelpers(path: Path): WatchHelper; - /** - * Provides directory tracking objects - * @param directory path of the directory - */ - _getWatchedDir(directory: string): DirEntry; - /** - * Check for read permissions: https://stackoverflow.com/a/11781404/1358405 - */ - _hasReadPermissions(stats: Stats): boolean; - /** - * Handles emitting unlink events for - * files and directories, and via recursion, for - * files and directories within directories that are unlinked - * @param directory within which the following item is located - * @param item base path of item/directory - */ - _remove(directory: string, item: string, isDirectory?: boolean): void; - /** - * Closes all watchers for a path - */ - _closePath(path: Path): void; - /** - * Closes only file-specific watchers - */ - _closeFile(path: Path): void; - _addPathCloser(path: Path, closer: () => void): void; - _readdirp(root: Path, opts?: Partial): ReaddirpStream | undefined; -} -/** - * Instantiates watcher with paths to be tracked. - * @param paths file / directory paths - * @param options opts, such as `atomic`, `awaitWriteFinish`, `ignored`, and others - * @returns an instance of FSWatcher for chaining. - * @example - * const watcher = watch('.').on('all', (event, path) => { console.log(event, path); }); - * watch('.', { atomic: true, awaitWriteFinish: true, ignored: (f, stats) => stats?.isFile() && !f.endsWith('.js') }) - */ -export declare function watch(paths: string | string[], options?: ChokidarOptions): FSWatcher; -declare const _default: { - watch: typeof watch; - FSWatcher: typeof FSWatcher; -}; -export default _default; diff --git a/node_modules/chokidar/index.js b/node_modules/chokidar/index.js deleted file mode 100644 index 79370ee..0000000 --- a/node_modules/chokidar/index.js +++ /dev/null @@ -1,804 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.FSWatcher = exports.WatchHelper = void 0; -exports.watch = watch; -/*! chokidar - MIT License (c) 2012 Paul Miller (paulmillr.com) */ -const fs_1 = require("fs"); -const promises_1 = require("fs/promises"); -const events_1 = require("events"); -const sysPath = require("path"); -const readdirp_1 = require("readdirp"); -const handler_js_1 = require("./handler.js"); -const SLASH = '/'; -const SLASH_SLASH = '//'; -const ONE_DOT = '.'; -const TWO_DOTS = '..'; -const STRING_TYPE = 'string'; -const BACK_SLASH_RE = /\\/g; -const DOUBLE_SLASH_RE = /\/\//; -const DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/; -const REPLACER_RE = /^\.[/\\]/; -function arrify(item) { - return Array.isArray(item) ? item : [item]; -} -const isMatcherObject = (matcher) => typeof matcher === 'object' && matcher !== null && !(matcher instanceof RegExp); -function createPattern(matcher) { - if (typeof matcher === 'function') - return matcher; - if (typeof matcher === 'string') - return (string) => matcher === string; - if (matcher instanceof RegExp) - return (string) => matcher.test(string); - if (typeof matcher === 'object' && matcher !== null) { - return (string) => { - if (matcher.path === string) - return true; - if (matcher.recursive) { - const relative = sysPath.relative(matcher.path, string); - if (!relative) { - return false; - } - return !relative.startsWith('..') && !sysPath.isAbsolute(relative); - } - return false; - }; - } - return () => false; -} -function normalizePath(path) { - if (typeof path !== 'string') - throw new Error('string expected'); - path = sysPath.normalize(path); - path = path.replace(/\\/g, '/'); - let prepend = false; - if (path.startsWith('//')) - prepend = true; - const DOUBLE_SLASH_RE = /\/\//; - while (path.match(DOUBLE_SLASH_RE)) - path = path.replace(DOUBLE_SLASH_RE, '/'); - if (prepend) - path = '/' + path; - return path; -} -function matchPatterns(patterns, testString, stats) { - const path = normalizePath(testString); - for (let index = 0; index < patterns.length; index++) { - const pattern = patterns[index]; - if (pattern(path, stats)) { - return true; - } - } - return false; -} -function anymatch(matchers, testString) { - if (matchers == null) { - throw new TypeError('anymatch: specify first argument'); - } - // Early cache for matchers. - const matchersArray = arrify(matchers); - const patterns = matchersArray.map((matcher) => createPattern(matcher)); - if (testString == null) { - return (testString, stats) => { - return matchPatterns(patterns, testString, stats); - }; - } - return matchPatterns(patterns, testString); -} -const unifyPaths = (paths_) => { - const paths = arrify(paths_).flat(); - if (!paths.every((p) => typeof p === STRING_TYPE)) { - throw new TypeError(`Non-string provided as watch path: ${paths}`); - } - return paths.map(normalizePathToUnix); -}; -// If SLASH_SLASH occurs at the beginning of path, it is not replaced -// because "//StoragePC/DrivePool/Movies" is a valid network path -const toUnix = (string) => { - let str = string.replace(BACK_SLASH_RE, SLASH); - let prepend = false; - if (str.startsWith(SLASH_SLASH)) { - prepend = true; - } - while (str.match(DOUBLE_SLASH_RE)) { - str = str.replace(DOUBLE_SLASH_RE, SLASH); - } - if (prepend) { - str = SLASH + str; - } - return str; -}; -// Our version of upath.normalize -// TODO: this is not equal to path-normalize module - investigate why -const normalizePathToUnix = (path) => toUnix(sysPath.normalize(toUnix(path))); -// TODO: refactor -const normalizeIgnored = (cwd = '') => (path) => { - if (typeof path === 'string') { - return normalizePathToUnix(sysPath.isAbsolute(path) ? path : sysPath.join(cwd, path)); - } - else { - return path; - } -}; -const getAbsolutePath = (path, cwd) => { - if (sysPath.isAbsolute(path)) { - return path; - } - return sysPath.join(cwd, path); -}; -const EMPTY_SET = Object.freeze(new Set()); -/** - * Directory entry. - */ -class DirEntry { - constructor(dir, removeWatcher) { - this.path = dir; - this._removeWatcher = removeWatcher; - this.items = new Set(); - } - add(item) { - const { items } = this; - if (!items) - return; - if (item !== ONE_DOT && item !== TWO_DOTS) - items.add(item); - } - async remove(item) { - const { items } = this; - if (!items) - return; - items.delete(item); - if (items.size > 0) - return; - const dir = this.path; - try { - await (0, promises_1.readdir)(dir); - } - catch (err) { - if (this._removeWatcher) { - this._removeWatcher(sysPath.dirname(dir), sysPath.basename(dir)); - } - } - } - has(item) { - const { items } = this; - if (!items) - return; - return items.has(item); - } - getChildren() { - const { items } = this; - if (!items) - return []; - return [...items.values()]; - } - dispose() { - this.items.clear(); - this.path = ''; - this._removeWatcher = handler_js_1.EMPTY_FN; - this.items = EMPTY_SET; - Object.freeze(this); - } -} -const STAT_METHOD_F = 'stat'; -const STAT_METHOD_L = 'lstat'; -class WatchHelper { - constructor(path, follow, fsw) { - this.fsw = fsw; - const watchPath = path; - this.path = path = path.replace(REPLACER_RE, ''); - this.watchPath = watchPath; - this.fullWatchPath = sysPath.resolve(watchPath); - this.dirParts = []; - this.dirParts.forEach((parts) => { - if (parts.length > 1) - parts.pop(); - }); - this.followSymlinks = follow; - this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L; - } - entryPath(entry) { - return sysPath.join(this.watchPath, sysPath.relative(this.watchPath, entry.fullPath)); - } - filterPath(entry) { - const { stats } = entry; - if (stats && stats.isSymbolicLink()) - return this.filterDir(entry); - const resolvedPath = this.entryPath(entry); - // TODO: what if stats is undefined? remove ! - return this.fsw._isntIgnored(resolvedPath, stats) && this.fsw._hasReadPermissions(stats); - } - filterDir(entry) { - return this.fsw._isntIgnored(this.entryPath(entry), entry.stats); - } -} -exports.WatchHelper = WatchHelper; -/** - * Watches files & directories for changes. Emitted events: - * `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error` - * - * new FSWatcher() - * .add(directories) - * .on('add', path => log('File', path, 'was added')) - */ -class FSWatcher extends events_1.EventEmitter { - // Not indenting methods for history sake; for now. - constructor(_opts = {}) { - super(); - this.closed = false; - this._closers = new Map(); - this._ignoredPaths = new Set(); - this._throttled = new Map(); - this._streams = new Set(); - this._symlinkPaths = new Map(); - this._watched = new Map(); - this._pendingWrites = new Map(); - this._pendingUnlinks = new Map(); - this._readyCount = 0; - this._readyEmitted = false; - const awf = _opts.awaitWriteFinish; - const DEF_AWF = { stabilityThreshold: 2000, pollInterval: 100 }; - const opts = { - // Defaults - persistent: true, - ignoreInitial: false, - ignorePermissionErrors: false, - interval: 100, - binaryInterval: 300, - followSymlinks: true, - usePolling: false, - // useAsync: false, - atomic: true, // NOTE: overwritten later (depends on usePolling) - ..._opts, - // Change format - ignored: _opts.ignored ? arrify(_opts.ignored) : arrify([]), - awaitWriteFinish: awf === true ? DEF_AWF : typeof awf === 'object' ? { ...DEF_AWF, ...awf } : false, - }; - // Always default to polling on IBM i because fs.watch() is not available on IBM i. - if (handler_js_1.isIBMi) - opts.usePolling = true; - // Editor atomic write normalization enabled by default with fs.watch - if (opts.atomic === undefined) - opts.atomic = !opts.usePolling; - // opts.atomic = typeof _opts.atomic === 'number' ? _opts.atomic : 100; - // Global override. Useful for developers, who need to force polling for all - // instances of chokidar, regardless of usage / dependency depth - const envPoll = process.env.CHOKIDAR_USEPOLLING; - if (envPoll !== undefined) { - const envLower = envPoll.toLowerCase(); - if (envLower === 'false' || envLower === '0') - opts.usePolling = false; - else if (envLower === 'true' || envLower === '1') - opts.usePolling = true; - else - opts.usePolling = !!envLower; - } - const envInterval = process.env.CHOKIDAR_INTERVAL; - if (envInterval) - opts.interval = Number.parseInt(envInterval, 10); - // This is done to emit ready only once, but each 'add' will increase that? - let readyCalls = 0; - this._emitReady = () => { - readyCalls++; - if (readyCalls >= this._readyCount) { - this._emitReady = handler_js_1.EMPTY_FN; - this._readyEmitted = true; - // use process.nextTick to allow time for listener to be bound - process.nextTick(() => this.emit(handler_js_1.EVENTS.READY)); - } - }; - this._emitRaw = (...args) => this.emit(handler_js_1.EVENTS.RAW, ...args); - this._boundRemove = this._remove.bind(this); - this.options = opts; - this._nodeFsHandler = new handler_js_1.NodeFsHandler(this); - // You’re frozen when your heart’s not open. - Object.freeze(opts); - } - _addIgnoredPath(matcher) { - if (isMatcherObject(matcher)) { - // return early if we already have a deeply equal matcher object - for (const ignored of this._ignoredPaths) { - if (isMatcherObject(ignored) && - ignored.path === matcher.path && - ignored.recursive === matcher.recursive) { - return; - } - } - } - this._ignoredPaths.add(matcher); - } - _removeIgnoredPath(matcher) { - this._ignoredPaths.delete(matcher); - // now find any matcher objects with the matcher as path - if (typeof matcher === 'string') { - for (const ignored of this._ignoredPaths) { - // TODO (43081j): make this more efficient. - // probably just make a `this._ignoredDirectories` or some - // such thing. - if (isMatcherObject(ignored) && ignored.path === matcher) { - this._ignoredPaths.delete(ignored); - } - } - } - } - // Public methods - /** - * Adds paths to be watched on an existing FSWatcher instance. - * @param paths_ file or file list. Other arguments are unused - */ - add(paths_, _origAdd, _internal) { - const { cwd } = this.options; - this.closed = false; - this._closePromise = undefined; - let paths = unifyPaths(paths_); - if (cwd) { - paths = paths.map((path) => { - const absPath = getAbsolutePath(path, cwd); - // Check `path` instead of `absPath` because the cwd portion can't be a glob - return absPath; - }); - } - paths.forEach((path) => { - this._removeIgnoredPath(path); - }); - this._userIgnored = undefined; - if (!this._readyCount) - this._readyCount = 0; - this._readyCount += paths.length; - Promise.all(paths.map(async (path) => { - const res = await this._nodeFsHandler._addToNodeFs(path, !_internal, undefined, 0, _origAdd); - if (res) - this._emitReady(); - return res; - })).then((results) => { - if (this.closed) - return; - results.forEach((item) => { - if (item) - this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item)); - }); - }); - return this; - } - /** - * Close watchers or start ignoring events from specified paths. - */ - unwatch(paths_) { - if (this.closed) - return this; - const paths = unifyPaths(paths_); - const { cwd } = this.options; - paths.forEach((path) => { - // convert to absolute path unless relative path already matches - if (!sysPath.isAbsolute(path) && !this._closers.has(path)) { - if (cwd) - path = sysPath.join(cwd, path); - path = sysPath.resolve(path); - } - this._closePath(path); - this._addIgnoredPath(path); - if (this._watched.has(path)) { - this._addIgnoredPath({ - path, - recursive: true, - }); - } - // reset the cached userIgnored anymatch fn - // to make ignoredPaths changes effective - this._userIgnored = undefined; - }); - return this; - } - /** - * Close watchers and remove all listeners from watched paths. - */ - close() { - if (this._closePromise) { - return this._closePromise; - } - this.closed = true; - // Memory management. - this.removeAllListeners(); - const closers = []; - this._closers.forEach((closerList) => closerList.forEach((closer) => { - const promise = closer(); - if (promise instanceof Promise) - closers.push(promise); - })); - this._streams.forEach((stream) => stream.destroy()); - this._userIgnored = undefined; - this._readyCount = 0; - this._readyEmitted = false; - this._watched.forEach((dirent) => dirent.dispose()); - this._closers.clear(); - this._watched.clear(); - this._streams.clear(); - this._symlinkPaths.clear(); - this._throttled.clear(); - this._closePromise = closers.length - ? Promise.all(closers).then(() => undefined) - : Promise.resolve(); - return this._closePromise; - } - /** - * Expose list of watched paths - * @returns for chaining - */ - getWatched() { - const watchList = {}; - this._watched.forEach((entry, dir) => { - const key = this.options.cwd ? sysPath.relative(this.options.cwd, dir) : dir; - const index = key || ONE_DOT; - watchList[index] = entry.getChildren().sort(); - }); - return watchList; - } - emitWithAll(event, args) { - this.emit(event, ...args); - if (event !== handler_js_1.EVENTS.ERROR) - this.emit(handler_js_1.EVENTS.ALL, event, ...args); - } - // Common helpers - // -------------- - /** - * Normalize and emit events. - * Calling _emit DOES NOT MEAN emit() would be called! - * @param event Type of event - * @param path File or directory path - * @param stats arguments to be passed with event - * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag - */ - async _emit(event, path, stats) { - if (this.closed) - return; - const opts = this.options; - if (handler_js_1.isWindows) - path = sysPath.normalize(path); - if (opts.cwd) - path = sysPath.relative(opts.cwd, path); - const args = [path]; - if (stats != null) - args.push(stats); - const awf = opts.awaitWriteFinish; - let pw; - if (awf && (pw = this._pendingWrites.get(path))) { - pw.lastChange = new Date(); - return this; - } - if (opts.atomic) { - if (event === handler_js_1.EVENTS.UNLINK) { - this._pendingUnlinks.set(path, [event, ...args]); - setTimeout(() => { - this._pendingUnlinks.forEach((entry, path) => { - this.emit(...entry); - this.emit(handler_js_1.EVENTS.ALL, ...entry); - this._pendingUnlinks.delete(path); - }); - }, typeof opts.atomic === 'number' ? opts.atomic : 100); - return this; - } - if (event === handler_js_1.EVENTS.ADD && this._pendingUnlinks.has(path)) { - event = handler_js_1.EVENTS.CHANGE; - this._pendingUnlinks.delete(path); - } - } - if (awf && (event === handler_js_1.EVENTS.ADD || event === handler_js_1.EVENTS.CHANGE) && this._readyEmitted) { - const awfEmit = (err, stats) => { - if (err) { - event = handler_js_1.EVENTS.ERROR; - args[0] = err; - this.emitWithAll(event, args); - } - else if (stats) { - // if stats doesn't exist the file must have been deleted - if (args.length > 1) { - args[1] = stats; - } - else { - args.push(stats); - } - this.emitWithAll(event, args); - } - }; - this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit); - return this; - } - if (event === handler_js_1.EVENTS.CHANGE) { - const isThrottled = !this._throttle(handler_js_1.EVENTS.CHANGE, path, 50); - if (isThrottled) - return this; - } - if (opts.alwaysStat && - stats === undefined && - (event === handler_js_1.EVENTS.ADD || event === handler_js_1.EVENTS.ADD_DIR || event === handler_js_1.EVENTS.CHANGE)) { - const fullPath = opts.cwd ? sysPath.join(opts.cwd, path) : path; - let stats; - try { - stats = await (0, promises_1.stat)(fullPath); - } - catch (err) { - // do nothing - } - // Suppress event when fs_stat fails, to avoid sending undefined 'stat' - if (!stats || this.closed) - return; - args.push(stats); - } - this.emitWithAll(event, args); - return this; - } - /** - * Common handler for errors - * @returns The error if defined, otherwise the value of the FSWatcher instance's `closed` flag - */ - _handleError(error) { - const code = error && error.code; - if (error && - code !== 'ENOENT' && - code !== 'ENOTDIR' && - (!this.options.ignorePermissionErrors || (code !== 'EPERM' && code !== 'EACCES'))) { - this.emit(handler_js_1.EVENTS.ERROR, error); - } - return error || this.closed; - } - /** - * Helper utility for throttling - * @param actionType type being throttled - * @param path being acted upon - * @param timeout duration of time to suppress duplicate actions - * @returns tracking object or false if action should be suppressed - */ - _throttle(actionType, path, timeout) { - if (!this._throttled.has(actionType)) { - this._throttled.set(actionType, new Map()); - } - const action = this._throttled.get(actionType); - if (!action) - throw new Error('invalid throttle'); - const actionPath = action.get(path); - if (actionPath) { - actionPath.count++; - return false; - } - // eslint-disable-next-line prefer-const - let timeoutObject; - const clear = () => { - const item = action.get(path); - const count = item ? item.count : 0; - action.delete(path); - clearTimeout(timeoutObject); - if (item) - clearTimeout(item.timeoutObject); - return count; - }; - timeoutObject = setTimeout(clear, timeout); - const thr = { timeoutObject, clear, count: 0 }; - action.set(path, thr); - return thr; - } - _incrReadyCount() { - return this._readyCount++; - } - /** - * Awaits write operation to finish. - * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback. - * @param path being acted upon - * @param threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished - * @param event - * @param awfEmit Callback to be called when ready for event to be emitted. - */ - _awaitWriteFinish(path, threshold, event, awfEmit) { - const awf = this.options.awaitWriteFinish; - if (typeof awf !== 'object') - return; - const pollInterval = awf.pollInterval; - let timeoutHandler; - let fullPath = path; - if (this.options.cwd && !sysPath.isAbsolute(path)) { - fullPath = sysPath.join(this.options.cwd, path); - } - const now = new Date(); - const writes = this._pendingWrites; - function awaitWriteFinishFn(prevStat) { - (0, fs_1.stat)(fullPath, (err, curStat) => { - if (err || !writes.has(path)) { - if (err && err.code !== 'ENOENT') - awfEmit(err); - return; - } - const now = Number(new Date()); - if (prevStat && curStat.size !== prevStat.size) { - writes.get(path).lastChange = now; - } - const pw = writes.get(path); - const df = now - pw.lastChange; - if (df >= threshold) { - writes.delete(path); - awfEmit(undefined, curStat); - } - else { - timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat); - } - }); - } - if (!writes.has(path)) { - writes.set(path, { - lastChange: now, - cancelWait: () => { - writes.delete(path); - clearTimeout(timeoutHandler); - return event; - }, - }); - timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval); - } - } - /** - * Determines whether user has asked to ignore this path. - */ - _isIgnored(path, stats) { - if (this.options.atomic && DOT_RE.test(path)) - return true; - if (!this._userIgnored) { - const { cwd } = this.options; - const ign = this.options.ignored; - const ignored = (ign || []).map(normalizeIgnored(cwd)); - const ignoredPaths = [...this._ignoredPaths]; - const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored]; - this._userIgnored = anymatch(list, undefined); - } - return this._userIgnored(path, stats); - } - _isntIgnored(path, stat) { - return !this._isIgnored(path, stat); - } - /** - * Provides a set of common helpers and properties relating to symlink handling. - * @param path file or directory pattern being watched - */ - _getWatchHelpers(path) { - return new WatchHelper(path, this.options.followSymlinks, this); - } - // Directory helpers - // ----------------- - /** - * Provides directory tracking objects - * @param directory path of the directory - */ - _getWatchedDir(directory) { - const dir = sysPath.resolve(directory); - if (!this._watched.has(dir)) - this._watched.set(dir, new DirEntry(dir, this._boundRemove)); - return this._watched.get(dir); - } - // File helpers - // ------------ - /** - * Check for read permissions: https://stackoverflow.com/a/11781404/1358405 - */ - _hasReadPermissions(stats) { - if (this.options.ignorePermissionErrors) - return true; - return Boolean(Number(stats.mode) & 0o400); - } - /** - * Handles emitting unlink events for - * files and directories, and via recursion, for - * files and directories within directories that are unlinked - * @param directory within which the following item is located - * @param item base path of item/directory - */ - _remove(directory, item, isDirectory) { - // if what is being deleted is a directory, get that directory's paths - // for recursive deleting and cleaning of watched object - // if it is not a directory, nestedDirectoryChildren will be empty array - const path = sysPath.join(directory, item); - const fullPath = sysPath.resolve(path); - isDirectory = - isDirectory != null ? isDirectory : this._watched.has(path) || this._watched.has(fullPath); - // prevent duplicate handling in case of arriving here nearly simultaneously - // via multiple paths (such as _handleFile and _handleDir) - if (!this._throttle('remove', path, 100)) - return; - // if the only watched file is removed, watch for its return - if (!isDirectory && this._watched.size === 1) { - this.add(directory, item, true); - } - // This will create a new entry in the watched object in either case - // so we got to do the directory check beforehand - const wp = this._getWatchedDir(path); - const nestedDirectoryChildren = wp.getChildren(); - // Recursively remove children directories / files. - nestedDirectoryChildren.forEach((nested) => this._remove(path, nested)); - // Check if item was on the watched list and remove it - const parent = this._getWatchedDir(directory); - const wasTracked = parent.has(item); - parent.remove(item); - // Fixes issue #1042 -> Relative paths were detected and added as symlinks - // (https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L612), - // but never removed from the map in case the path was deleted. - // This leads to an incorrect state if the path was recreated: - // https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L553 - if (this._symlinkPaths.has(fullPath)) { - this._symlinkPaths.delete(fullPath); - } - // If we wait for this file to be fully written, cancel the wait. - let relPath = path; - if (this.options.cwd) - relPath = sysPath.relative(this.options.cwd, path); - if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) { - const event = this._pendingWrites.get(relPath).cancelWait(); - if (event === handler_js_1.EVENTS.ADD) - return; - } - // The Entry will either be a directory that just got removed - // or a bogus entry to a file, in either case we have to remove it - this._watched.delete(path); - this._watched.delete(fullPath); - const eventName = isDirectory ? handler_js_1.EVENTS.UNLINK_DIR : handler_js_1.EVENTS.UNLINK; - if (wasTracked && !this._isIgnored(path)) - this._emit(eventName, path); - // Avoid conflicts if we later create another file with the same name - this._closePath(path); - } - /** - * Closes all watchers for a path - */ - _closePath(path) { - this._closeFile(path); - const dir = sysPath.dirname(path); - this._getWatchedDir(dir).remove(sysPath.basename(path)); - } - /** - * Closes only file-specific watchers - */ - _closeFile(path) { - const closers = this._closers.get(path); - if (!closers) - return; - closers.forEach((closer) => closer()); - this._closers.delete(path); - } - _addPathCloser(path, closer) { - if (!closer) - return; - let list = this._closers.get(path); - if (!list) { - list = []; - this._closers.set(path, list); - } - list.push(closer); - } - _readdirp(root, opts) { - if (this.closed) - return; - const options = { type: handler_js_1.EVENTS.ALL, alwaysStat: true, lstat: true, ...opts, depth: 0 }; - let stream = (0, readdirp_1.readdirp)(root, options); - this._streams.add(stream); - stream.once(handler_js_1.STR_CLOSE, () => { - stream = undefined; - }); - stream.once(handler_js_1.STR_END, () => { - if (stream) { - this._streams.delete(stream); - stream = undefined; - } - }); - return stream; - } -} -exports.FSWatcher = FSWatcher; -/** - * Instantiates watcher with paths to be tracked. - * @param paths file / directory paths - * @param options opts, such as `atomic`, `awaitWriteFinish`, `ignored`, and others - * @returns an instance of FSWatcher for chaining. - * @example - * const watcher = watch('.').on('all', (event, path) => { console.log(event, path); }); - * watch('.', { atomic: true, awaitWriteFinish: true, ignored: (f, stats) => stats?.isFile() && !f.endsWith('.js') }) - */ -function watch(paths, options = {}) { - const watcher = new FSWatcher(options); - watcher.add(paths); - return watcher; -} -exports.default = { watch, FSWatcher }; diff --git a/node_modules/chokidar/package.json b/node_modules/chokidar/package.json deleted file mode 100644 index db79241..0000000 --- a/node_modules/chokidar/package.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "chokidar", - "description": "Minimal and efficient cross-platform file watching library", - "version": "4.0.3", - "homepage": "https://github.com/paulmillr/chokidar", - "author": "Paul Miller (https://paulmillr.com)", - "files": [ - "index.js", - "index.d.ts", - "handler.js", - "handler.d.ts", - "esm" - ], - "main": "./index.js", - "module": "./esm/index.js", - "types": "./index.d.ts", - "exports": { - ".": { - "import": "./esm/index.js", - "require": "./index.js" - }, - "./handler.js": { - "import": "./esm/handler.js", - "require": "./handler.js" - } - }, - "dependencies": { - "readdirp": "^4.0.1" - }, - "devDependencies": { - "@paulmillr/jsbt": "0.2.1", - "@types/node": "20.14.8", - "chai": "4.3.4", - "prettier": "3.1.1", - "rimraf": "5.0.5", - "sinon": "12.0.1", - "sinon-chai": "3.7.0", - "typescript": "5.5.2", - "upath": "2.0.1" - }, - "sideEffects": false, - "engines": { - "node": ">= 14.16.0" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/paulmillr/chokidar.git" - }, - "bugs": { - "url": "https://github.com/paulmillr/chokidar/issues" - }, - "license": "MIT", - "scripts": { - "build": "tsc && tsc -p tsconfig.esm.json", - "lint": "prettier --check src", - "format": "prettier --write src", - "test": "node --test" - }, - "keywords": [ - "fs", - "watch", - "watchFile", - "watcher", - "watching", - "file", - "fsevents" - ], - "funding": "https://paulmillr.com/funding/" -} diff --git a/node_modules/content-disposition/HISTORY.md b/node_modules/content-disposition/HISTORY.md deleted file mode 100644 index 488effa..0000000 --- a/node_modules/content-disposition/HISTORY.md +++ /dev/null @@ -1,60 +0,0 @@ -0.5.4 / 2021-12-10 -================== - - * deps: safe-buffer@5.2.1 - -0.5.3 / 2018-12-17 -================== - - * Use `safe-buffer` for improved Buffer API - -0.5.2 / 2016-12-08 -================== - - * Fix `parse` to accept any linear whitespace character - -0.5.1 / 2016-01-17 -================== - - * perf: enable strict mode - -0.5.0 / 2014-10-11 -================== - - * Add `parse` function - -0.4.0 / 2014-09-21 -================== - - * Expand non-Unicode `filename` to the full ISO-8859-1 charset - -0.3.0 / 2014-09-20 -================== - - * Add `fallback` option - * Add `type` option - -0.2.0 / 2014-09-19 -================== - - * Reduce ambiguity of file names with hex escape in buggy browsers - -0.1.2 / 2014-09-19 -================== - - * Fix periodic invalid Unicode filename header - -0.1.1 / 2014-09-19 -================== - - * Fix invalid characters appearing in `filename*` parameter - -0.1.0 / 2014-09-18 -================== - - * Make the `filename` argument optional - -0.0.0 / 2014-09-18 -================== - - * Initial release diff --git a/node_modules/content-disposition/LICENSE b/node_modules/content-disposition/LICENSE deleted file mode 100644 index 84441fb..0000000 --- a/node_modules/content-disposition/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2014-2017 Douglas Christopher Wilson - -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. diff --git a/node_modules/content-disposition/README.md b/node_modules/content-disposition/README.md deleted file mode 100644 index 3a0bb05..0000000 --- a/node_modules/content-disposition/README.md +++ /dev/null @@ -1,142 +0,0 @@ -# content-disposition - -[![NPM Version][npm-image]][npm-url] -[![NPM Downloads][downloads-image]][downloads-url] -[![Node.js Version][node-version-image]][node-version-url] -[![Build Status][github-actions-ci-image]][github-actions-ci-url] -[![Test Coverage][coveralls-image]][coveralls-url] - -Create and parse HTTP `Content-Disposition` header - -## Installation - -```sh -$ npm install content-disposition -``` - -## API - -```js -var contentDisposition = require('content-disposition') -``` - -### contentDisposition(filename, options) - -Create an attachment `Content-Disposition` header value using the given file name, -if supplied. The `filename` is optional and if no file name is desired, but you -want to specify `options`, set `filename` to `undefined`. - -```js -res.setHeader('Content-Disposition', contentDisposition('∫ maths.pdf')) -``` - -**note** HTTP headers are of the ISO-8859-1 character set. If you are writing this -header through a means different from `setHeader` in Node.js, you'll want to specify -the `'binary'` encoding in Node.js. - -#### Options - -`contentDisposition` accepts these properties in the options object. - -##### fallback - -If the `filename` option is outside ISO-8859-1, then the file name is actually -stored in a supplemental field for clients that support Unicode file names and -a ISO-8859-1 version of the file name is automatically generated. - -This specifies the ISO-8859-1 file name to override the automatic generation or -disables the generation all together, defaults to `true`. - - - A string will specify the ISO-8859-1 file name to use in place of automatic - generation. - - `false` will disable including a ISO-8859-1 file name and only include the - Unicode version (unless the file name is already ISO-8859-1). - - `true` will enable automatic generation if the file name is outside ISO-8859-1. - -If the `filename` option is ISO-8859-1 and this option is specified and has a -different value, then the `filename` option is encoded in the extended field -and this set as the fallback field, even though they are both ISO-8859-1. - -##### type - -Specifies the disposition type, defaults to `"attachment"`. This can also be -`"inline"`, or any other value (all values except inline are treated like -`attachment`, but can convey additional information if both parties agree to -it). The type is normalized to lower-case. - -### contentDisposition.parse(string) - -```js -var disposition = contentDisposition.parse('attachment; filename="EURO rates.txt"; filename*=UTF-8\'\'%e2%82%ac%20rates.txt') -``` - -Parse a `Content-Disposition` header string. This automatically handles extended -("Unicode") parameters by decoding them and providing them under the standard -parameter name. This will return an object with the following properties (examples -are shown for the string `'attachment; filename="EURO rates.txt"; filename*=UTF-8\'\'%e2%82%ac%20rates.txt'`): - - - `type`: The disposition type (always lower case). Example: `'attachment'` - - - `parameters`: An object of the parameters in the disposition (name of parameter - always lower case and extended versions replace non-extended versions). Example: - `{filename: "€ rates.txt"}` - -## Examples - -### Send a file for download - -```js -var contentDisposition = require('content-disposition') -var destroy = require('destroy') -var fs = require('fs') -var http = require('http') -var onFinished = require('on-finished') - -var filePath = '/path/to/public/plans.pdf' - -http.createServer(function onRequest (req, res) { - // set headers - res.setHeader('Content-Type', 'application/pdf') - res.setHeader('Content-Disposition', contentDisposition(filePath)) - - // send file - var stream = fs.createReadStream(filePath) - stream.pipe(res) - onFinished(res, function () { - destroy(stream) - }) -}) -``` - -## Testing - -```sh -$ npm test -``` - -## References - -- [RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1][rfc-2616] -- [RFC 5987: Character Set and Language Encoding for Hypertext Transfer Protocol (HTTP) Header Field Parameters][rfc-5987] -- [RFC 6266: Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)][rfc-6266] -- [Test Cases for HTTP Content-Disposition header field (RFC 6266) and the Encodings defined in RFCs 2047, 2231 and 5987][tc-2231] - -[rfc-2616]: https://tools.ietf.org/html/rfc2616 -[rfc-5987]: https://tools.ietf.org/html/rfc5987 -[rfc-6266]: https://tools.ietf.org/html/rfc6266 -[tc-2231]: http://greenbytes.de/tech/tc2231/ - -## License - -[MIT](LICENSE) - -[npm-image]: https://img.shields.io/npm/v/content-disposition.svg -[npm-url]: https://npmjs.org/package/content-disposition -[node-version-image]: https://img.shields.io/node/v/content-disposition.svg -[node-version-url]: https://nodejs.org/en/download -[coveralls-image]: https://img.shields.io/coveralls/jshttp/content-disposition.svg -[coveralls-url]: https://coveralls.io/r/jshttp/content-disposition?branch=master -[downloads-image]: https://img.shields.io/npm/dm/content-disposition.svg -[downloads-url]: https://npmjs.org/package/content-disposition -[github-actions-ci-image]: https://img.shields.io/github/workflow/status/jshttp/content-disposition/ci/master?label=ci -[github-actions-ci-url]: https://github.com/jshttp/content-disposition?query=workflow%3Aci diff --git a/node_modules/content-disposition/index.js b/node_modules/content-disposition/index.js deleted file mode 100644 index ecec899..0000000 --- a/node_modules/content-disposition/index.js +++ /dev/null @@ -1,458 +0,0 @@ -/*! - * content-disposition - * Copyright(c) 2014-2017 Douglas Christopher Wilson - * MIT Licensed - */ - -'use strict' - -/** - * Module exports. - * @public - */ - -module.exports = contentDisposition -module.exports.parse = parse - -/** - * Module dependencies. - * @private - */ - -var basename = require('path').basename -var Buffer = require('safe-buffer').Buffer - -/** - * RegExp to match non attr-char, *after* encodeURIComponent (i.e. not including "%") - * @private - */ - -var ENCODE_URL_ATTR_CHAR_REGEXP = /[\x00-\x20"'()*,/:;<=>?@[\\\]{}\x7f]/g // eslint-disable-line no-control-regex - -/** - * RegExp to match percent encoding escape. - * @private - */ - -var HEX_ESCAPE_REGEXP = /%[0-9A-Fa-f]{2}/ -var HEX_ESCAPE_REPLACE_REGEXP = /%([0-9A-Fa-f]{2})/g - -/** - * RegExp to match non-latin1 characters. - * @private - */ - -var NON_LATIN1_REGEXP = /[^\x20-\x7e\xa0-\xff]/g - -/** - * RegExp to match quoted-pair in RFC 2616 - * - * quoted-pair = "\" CHAR - * CHAR = - * @private - */ - -var QESC_REGEXP = /\\([\u0000-\u007f])/g // eslint-disable-line no-control-regex - -/** - * RegExp to match chars that must be quoted-pair in RFC 2616 - * @private - */ - -var QUOTE_REGEXP = /([\\"])/g - -/** - * RegExp for various RFC 2616 grammar - * - * parameter = token "=" ( token | quoted-string ) - * token = 1* - * separators = "(" | ")" | "<" | ">" | "@" - * | "," | ";" | ":" | "\" | <"> - * | "/" | "[" | "]" | "?" | "=" - * | "{" | "}" | SP | HT - * quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) - * qdtext = > - * quoted-pair = "\" CHAR - * CHAR = - * TEXT = - * LWS = [CRLF] 1*( SP | HT ) - * CRLF = CR LF - * CR = - * LF = - * SP = - * HT = - * CTL = - * OCTET = - * @private - */ - -var PARAM_REGEXP = /;[\x09\x20]*([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*=[\x09\x20]*("(?:[\x20!\x23-\x5b\x5d-\x7e\x80-\xff]|\\[\x20-\x7e])*"|[!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*/g // eslint-disable-line no-control-regex -var TEXT_REGEXP = /^[\x20-\x7e\x80-\xff]+$/ -var TOKEN_REGEXP = /^[!#$%&'*+.0-9A-Z^_`a-z|~-]+$/ - -/** - * RegExp for various RFC 5987 grammar - * - * ext-value = charset "'" [ language ] "'" value-chars - * charset = "UTF-8" / "ISO-8859-1" / mime-charset - * mime-charset = 1*mime-charsetc - * mime-charsetc = ALPHA / DIGIT - * / "!" / "#" / "$" / "%" / "&" - * / "+" / "-" / "^" / "_" / "`" - * / "{" / "}" / "~" - * language = ( 2*3ALPHA [ extlang ] ) - * / 4ALPHA - * / 5*8ALPHA - * extlang = *3( "-" 3ALPHA ) - * value-chars = *( pct-encoded / attr-char ) - * pct-encoded = "%" HEXDIG HEXDIG - * attr-char = ALPHA / DIGIT - * / "!" / "#" / "$" / "&" / "+" / "-" / "." - * / "^" / "_" / "`" / "|" / "~" - * @private - */ - -var EXT_VALUE_REGEXP = /^([A-Za-z0-9!#$%&+\-^_`{}~]+)'(?:[A-Za-z]{2,3}(?:-[A-Za-z]{3}){0,3}|[A-Za-z]{4,8}|)'((?:%[0-9A-Fa-f]{2}|[A-Za-z0-9!#$&+.^_`|~-])+)$/ - -/** - * RegExp for various RFC 6266 grammar - * - * disposition-type = "inline" | "attachment" | disp-ext-type - * disp-ext-type = token - * disposition-parm = filename-parm | disp-ext-parm - * filename-parm = "filename" "=" value - * | "filename*" "=" ext-value - * disp-ext-parm = token "=" value - * | ext-token "=" ext-value - * ext-token = - * @private - */ - -var DISPOSITION_TYPE_REGEXP = /^([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*(?:$|;)/ // eslint-disable-line no-control-regex - -/** - * Create an attachment Content-Disposition header. - * - * @param {string} [filename] - * @param {object} [options] - * @param {string} [options.type=attachment] - * @param {string|boolean} [options.fallback=true] - * @return {string} - * @public - */ - -function contentDisposition (filename, options) { - var opts = options || {} - - // get type - var type = opts.type || 'attachment' - - // get parameters - var params = createparams(filename, opts.fallback) - - // format into string - return format(new ContentDisposition(type, params)) -} - -/** - * Create parameters object from filename and fallback. - * - * @param {string} [filename] - * @param {string|boolean} [fallback=true] - * @return {object} - * @private - */ - -function createparams (filename, fallback) { - if (filename === undefined) { - return - } - - var params = {} - - if (typeof filename !== 'string') { - throw new TypeError('filename must be a string') - } - - // fallback defaults to true - if (fallback === undefined) { - fallback = true - } - - if (typeof fallback !== 'string' && typeof fallback !== 'boolean') { - throw new TypeError('fallback must be a string or boolean') - } - - if (typeof fallback === 'string' && NON_LATIN1_REGEXP.test(fallback)) { - throw new TypeError('fallback must be ISO-8859-1 string') - } - - // restrict to file base name - var name = basename(filename) - - // determine if name is suitable for quoted string - var isQuotedString = TEXT_REGEXP.test(name) - - // generate fallback name - var fallbackName = typeof fallback !== 'string' - ? fallback && getlatin1(name) - : basename(fallback) - var hasFallback = typeof fallbackName === 'string' && fallbackName !== name - - // set extended filename parameter - if (hasFallback || !isQuotedString || HEX_ESCAPE_REGEXP.test(name)) { - params['filename*'] = name - } - - // set filename parameter - if (isQuotedString || hasFallback) { - params.filename = hasFallback - ? fallbackName - : name - } - - return params -} - -/** - * Format object to Content-Disposition header. - * - * @param {object} obj - * @param {string} obj.type - * @param {object} [obj.parameters] - * @return {string} - * @private - */ - -function format (obj) { - var parameters = obj.parameters - var type = obj.type - - if (!type || typeof type !== 'string' || !TOKEN_REGEXP.test(type)) { - throw new TypeError('invalid type') - } - - // start with normalized type - var string = String(type).toLowerCase() - - // append parameters - if (parameters && typeof parameters === 'object') { - var param - var params = Object.keys(parameters).sort() - - for (var i = 0; i < params.length; i++) { - param = params[i] - - var val = param.substr(-1) === '*' - ? ustring(parameters[param]) - : qstring(parameters[param]) - - string += '; ' + param + '=' + val - } - } - - return string -} - -/** - * Decode a RFC 5987 field value (gracefully). - * - * @param {string} str - * @return {string} - * @private - */ - -function decodefield (str) { - var match = EXT_VALUE_REGEXP.exec(str) - - if (!match) { - throw new TypeError('invalid extended field value') - } - - var charset = match[1].toLowerCase() - var encoded = match[2] - var value - - // to binary string - var binary = encoded.replace(HEX_ESCAPE_REPLACE_REGEXP, pdecode) - - switch (charset) { - case 'iso-8859-1': - value = getlatin1(binary) - break - case 'utf-8': - value = Buffer.from(binary, 'binary').toString('utf8') - break - default: - throw new TypeError('unsupported charset in extended field') - } - - return value -} - -/** - * Get ISO-8859-1 version of string. - * - * @param {string} val - * @return {string} - * @private - */ - -function getlatin1 (val) { - // simple Unicode -> ISO-8859-1 transformation - return String(val).replace(NON_LATIN1_REGEXP, '?') -} - -/** - * Parse Content-Disposition header string. - * - * @param {string} string - * @return {object} - * @public - */ - -function parse (string) { - if (!string || typeof string !== 'string') { - throw new TypeError('argument string is required') - } - - var match = DISPOSITION_TYPE_REGEXP.exec(string) - - if (!match) { - throw new TypeError('invalid type format') - } - - // normalize type - var index = match[0].length - var type = match[1].toLowerCase() - - var key - var names = [] - var params = {} - var value - - // calculate index to start at - index = PARAM_REGEXP.lastIndex = match[0].substr(-1) === ';' - ? index - 1 - : index - - // match parameters - while ((match = PARAM_REGEXP.exec(string))) { - if (match.index !== index) { - throw new TypeError('invalid parameter format') - } - - index += match[0].length - key = match[1].toLowerCase() - value = match[2] - - if (names.indexOf(key) !== -1) { - throw new TypeError('invalid duplicate parameter') - } - - names.push(key) - - if (key.indexOf('*') + 1 === key.length) { - // decode extended value - key = key.slice(0, -1) - value = decodefield(value) - - // overwrite existing value - params[key] = value - continue - } - - if (typeof params[key] === 'string') { - continue - } - - if (value[0] === '"') { - // remove quotes and escapes - value = value - .substr(1, value.length - 2) - .replace(QESC_REGEXP, '$1') - } - - params[key] = value - } - - if (index !== -1 && index !== string.length) { - throw new TypeError('invalid parameter format') - } - - return new ContentDisposition(type, params) -} - -/** - * Percent decode a single character. - * - * @param {string} str - * @param {string} hex - * @return {string} - * @private - */ - -function pdecode (str, hex) { - return String.fromCharCode(parseInt(hex, 16)) -} - -/** - * Percent encode a single character. - * - * @param {string} char - * @return {string} - * @private - */ - -function pencode (char) { - return '%' + String(char) - .charCodeAt(0) - .toString(16) - .toUpperCase() -} - -/** - * Quote a string for HTTP. - * - * @param {string} val - * @return {string} - * @private - */ - -function qstring (val) { - var str = String(val) - - return '"' + str.replace(QUOTE_REGEXP, '\\$1') + '"' -} - -/** - * Encode a Unicode string for HTTP (RFC 5987). - * - * @param {string} val - * @return {string} - * @private - */ - -function ustring (val) { - var str = String(val) - - // percent encode as UTF-8 - var encoded = encodeURIComponent(str) - .replace(ENCODE_URL_ATTR_CHAR_REGEXP, pencode) - - return 'UTF-8\'\'' + encoded -} - -/** - * Class for parsed Content-Disposition header for v8 optimization - * - * @public - * @param {string} type - * @param {object} parameters - * @constructor - */ - -function ContentDisposition (type, parameters) { - this.type = type - this.parameters = parameters -} diff --git a/node_modules/content-disposition/package.json b/node_modules/content-disposition/package.json deleted file mode 100644 index 43c70ce..0000000 --- a/node_modules/content-disposition/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "content-disposition", - "description": "Create and parse Content-Disposition header", - "version": "0.5.4", - "author": "Douglas Christopher Wilson ", - "license": "MIT", - "keywords": [ - "content-disposition", - "http", - "rfc6266", - "res" - ], - "repository": "jshttp/content-disposition", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "devDependencies": { - "deep-equal": "1.0.1", - "eslint": "7.32.0", - "eslint-config-standard": "13.0.1", - "eslint-plugin-import": "2.25.3", - "eslint-plugin-markdown": "2.2.1", - "eslint-plugin-node": "11.1.0", - "eslint-plugin-promise": "5.2.0", - "eslint-plugin-standard": "4.1.0", - "istanbul": "0.4.5", - "mocha": "9.1.3" - }, - "files": [ - "LICENSE", - "HISTORY.md", - "README.md", - "index.js" - ], - "engines": { - "node": ">= 0.6" - }, - "scripts": { - "lint": "eslint .", - "test": "mocha --reporter spec --bail --check-leaks test/", - "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/", - "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/" - } -} diff --git a/node_modules/content-type/HISTORY.md b/node_modules/content-type/HISTORY.md deleted file mode 100644 index 4583671..0000000 --- a/node_modules/content-type/HISTORY.md +++ /dev/null @@ -1,29 +0,0 @@ -1.0.5 / 2023-01-29 -================== - - * perf: skip value escaping when unnecessary - -1.0.4 / 2017-09-11 -================== - - * perf: skip parameter parsing when no parameters - -1.0.3 / 2017-09-10 -================== - - * perf: remove argument reassignment - -1.0.2 / 2016-05-09 -================== - - * perf: enable strict mode - -1.0.1 / 2015-02-13 -================== - - * Improve missing `Content-Type` header error message - -1.0.0 / 2015-02-01 -================== - - * Initial implementation, derived from `media-typer@0.3.0` diff --git a/node_modules/content-type/LICENSE b/node_modules/content-type/LICENSE deleted file mode 100644 index 34b1a2d..0000000 --- a/node_modules/content-type/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2015 Douglas Christopher Wilson - -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. diff --git a/node_modules/content-type/README.md b/node_modules/content-type/README.md deleted file mode 100644 index c1a922a..0000000 --- a/node_modules/content-type/README.md +++ /dev/null @@ -1,94 +0,0 @@ -# content-type - -[![NPM Version][npm-version-image]][npm-url] -[![NPM Downloads][npm-downloads-image]][npm-url] -[![Node.js Version][node-image]][node-url] -[![Build Status][ci-image]][ci-url] -[![Coverage Status][coveralls-image]][coveralls-url] - -Create and parse HTTP Content-Type header according to RFC 7231 - -## Installation - -```sh -$ npm install content-type -``` - -## API - -```js -var contentType = require('content-type') -``` - -### contentType.parse(string) - -```js -var obj = contentType.parse('image/svg+xml; charset=utf-8') -``` - -Parse a `Content-Type` header. This will return an object with the following -properties (examples are shown for the string `'image/svg+xml; charset=utf-8'`): - - - `type`: The media type (the type and subtype, always lower case). - Example: `'image/svg+xml'` - - - `parameters`: An object of the parameters in the media type (name of parameter - always lower case). Example: `{charset: 'utf-8'}` - -Throws a `TypeError` if the string is missing or invalid. - -### contentType.parse(req) - -```js -var obj = contentType.parse(req) -``` - -Parse the `Content-Type` header from the given `req`. Short-cut for -`contentType.parse(req.headers['content-type'])`. - -Throws a `TypeError` if the `Content-Type` header is missing or invalid. - -### contentType.parse(res) - -```js -var obj = contentType.parse(res) -``` - -Parse the `Content-Type` header set on the given `res`. Short-cut for -`contentType.parse(res.getHeader('content-type'))`. - -Throws a `TypeError` if the `Content-Type` header is missing or invalid. - -### contentType.format(obj) - -```js -var str = contentType.format({ - type: 'image/svg+xml', - parameters: { charset: 'utf-8' } -}) -``` - -Format an object into a `Content-Type` header. This will return a string of the -content type for the given object with the following properties (examples are -shown that produce the string `'image/svg+xml; charset=utf-8'`): - - - `type`: The media type (will be lower-cased). Example: `'image/svg+xml'` - - - `parameters`: An object of the parameters in the media type (name of the - parameter will be lower-cased). Example: `{charset: 'utf-8'}` - -Throws a `TypeError` if the object contains an invalid type or parameter names. - -## License - -[MIT](LICENSE) - -[ci-image]: https://badgen.net/github/checks/jshttp/content-type/master?label=ci -[ci-url]: https://github.com/jshttp/content-type/actions/workflows/ci.yml -[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/content-type/master -[coveralls-url]: https://coveralls.io/r/jshttp/content-type?branch=master -[node-image]: https://badgen.net/npm/node/content-type -[node-url]: https://nodejs.org/en/download -[npm-downloads-image]: https://badgen.net/npm/dm/content-type -[npm-url]: https://npmjs.org/package/content-type -[npm-version-image]: https://badgen.net/npm/v/content-type diff --git a/node_modules/content-type/index.js b/node_modules/content-type/index.js deleted file mode 100644 index 41840e7..0000000 --- a/node_modules/content-type/index.js +++ /dev/null @@ -1,225 +0,0 @@ -/*! - * content-type - * Copyright(c) 2015 Douglas Christopher Wilson - * MIT Licensed - */ - -'use strict' - -/** - * RegExp to match *( ";" parameter ) in RFC 7231 sec 3.1.1.1 - * - * parameter = token "=" ( token / quoted-string ) - * token = 1*tchar - * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" - * / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" - * / DIGIT / ALPHA - * ; any VCHAR, except delimiters - * quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE - * qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text - * obs-text = %x80-FF - * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) - */ -var PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g // eslint-disable-line no-control-regex -var TEXT_REGEXP = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/ // eslint-disable-line no-control-regex -var TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/ - -/** - * RegExp to match quoted-pair in RFC 7230 sec 3.2.6 - * - * quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text ) - * obs-text = %x80-FF - */ -var QESC_REGEXP = /\\([\u000b\u0020-\u00ff])/g // eslint-disable-line no-control-regex - -/** - * RegExp to match chars that must be quoted-pair in RFC 7230 sec 3.2.6 - */ -var QUOTE_REGEXP = /([\\"])/g - -/** - * RegExp to match type in RFC 7231 sec 3.1.1.1 - * - * media-type = type "/" subtype - * type = token - * subtype = token - */ -var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/ - -/** - * Module exports. - * @public - */ - -exports.format = format -exports.parse = parse - -/** - * Format object to media type. - * - * @param {object} obj - * @return {string} - * @public - */ - -function format (obj) { - if (!obj || typeof obj !== 'object') { - throw new TypeError('argument obj is required') - } - - var parameters = obj.parameters - var type = obj.type - - if (!type || !TYPE_REGEXP.test(type)) { - throw new TypeError('invalid type') - } - - var string = type - - // append parameters - if (parameters && typeof parameters === 'object') { - var param - var params = Object.keys(parameters).sort() - - for (var i = 0; i < params.length; i++) { - param = params[i] - - if (!TOKEN_REGEXP.test(param)) { - throw new TypeError('invalid parameter name') - } - - string += '; ' + param + '=' + qstring(parameters[param]) - } - } - - return string -} - -/** - * Parse media type to object. - * - * @param {string|object} string - * @return {Object} - * @public - */ - -function parse (string) { - if (!string) { - throw new TypeError('argument string is required') - } - - // support req/res-like objects as argument - var header = typeof string === 'object' - ? getcontenttype(string) - : string - - if (typeof header !== 'string') { - throw new TypeError('argument string is required to be a string') - } - - var index = header.indexOf(';') - var type = index !== -1 - ? header.slice(0, index).trim() - : header.trim() - - if (!TYPE_REGEXP.test(type)) { - throw new TypeError('invalid media type') - } - - var obj = new ContentType(type.toLowerCase()) - - // parse parameters - if (index !== -1) { - var key - var match - var value - - PARAM_REGEXP.lastIndex = index - - while ((match = PARAM_REGEXP.exec(header))) { - if (match.index !== index) { - throw new TypeError('invalid parameter format') - } - - index += match[0].length - key = match[1].toLowerCase() - value = match[2] - - if (value.charCodeAt(0) === 0x22 /* " */) { - // remove quotes - value = value.slice(1, -1) - - // remove escapes - if (value.indexOf('\\') !== -1) { - value = value.replace(QESC_REGEXP, '$1') - } - } - - obj.parameters[key] = value - } - - if (index !== header.length) { - throw new TypeError('invalid parameter format') - } - } - - return obj -} - -/** - * Get content-type from req/res objects. - * - * @param {object} - * @return {Object} - * @private - */ - -function getcontenttype (obj) { - var header - - if (typeof obj.getHeader === 'function') { - // res-like - header = obj.getHeader('content-type') - } else if (typeof obj.headers === 'object') { - // req-like - header = obj.headers && obj.headers['content-type'] - } - - if (typeof header !== 'string') { - throw new TypeError('content-type header is missing from object') - } - - return header -} - -/** - * Quote a string if necessary. - * - * @param {string} val - * @return {string} - * @private - */ - -function qstring (val) { - var str = String(val) - - // no need to quote tokens - if (TOKEN_REGEXP.test(str)) { - return str - } - - if (str.length > 0 && !TEXT_REGEXP.test(str)) { - throw new TypeError('invalid parameter value') - } - - return '"' + str.replace(QUOTE_REGEXP, '\\$1') + '"' -} - -/** - * Class to represent a content type. - * @private - */ -function ContentType (type) { - this.parameters = Object.create(null) - this.type = type -} diff --git a/node_modules/content-type/package.json b/node_modules/content-type/package.json deleted file mode 100644 index 9db19f6..0000000 --- a/node_modules/content-type/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "content-type", - "description": "Create and parse HTTP Content-Type header", - "version": "1.0.5", - "author": "Douglas Christopher Wilson ", - "license": "MIT", - "keywords": [ - "content-type", - "http", - "req", - "res", - "rfc7231" - ], - "repository": "jshttp/content-type", - "devDependencies": { - "deep-equal": "1.0.1", - "eslint": "8.32.0", - "eslint-config-standard": "15.0.1", - "eslint-plugin-import": "2.27.5", - "eslint-plugin-node": "11.1.0", - "eslint-plugin-promise": "6.1.1", - "eslint-plugin-standard": "4.1.0", - "mocha": "10.2.0", - "nyc": "15.1.0" - }, - "files": [ - "LICENSE", - "HISTORY.md", - "README.md", - "index.js" - ], - "engines": { - "node": ">= 0.6" - }, - "scripts": { - "lint": "eslint .", - "test": "mocha --reporter spec --check-leaks --bail test/", - "test-ci": "nyc --reporter=lcovonly --reporter=text npm test", - "test-cov": "nyc --reporter=html --reporter=text npm test", - "version": "node scripts/version-history.js && git add HISTORY.md" - } -} diff --git a/node_modules/cookie-signature/History.md b/node_modules/cookie-signature/History.md deleted file mode 100644 index bcf8cc9..0000000 --- a/node_modules/cookie-signature/History.md +++ /dev/null @@ -1,42 +0,0 @@ -1.0.7 / 2023-04-12 -================== - -* backport the buffer support from the 1.2.x release branch (thanks @FadhiliNjagi!) - -1.0.6 / 2015-02-03 -================== - -* use `npm test` instead of `make test` to run tests -* clearer assertion messages when checking input - -1.0.5 / 2014-09-05 -================== - -* add license to package.json - -1.0.4 / 2014-06-25 -================== - - * corrected avoidance of timing attacks (thanks @tenbits!) - -1.0.3 / 2014-01-28 -================== - - * [incorrect] fix for timing attacks - -1.0.2 / 2014-01-28 -================== - - * fix missing repository warning - * fix typo in test - -1.0.1 / 2013-04-15 -================== - - * Revert "Changed underlying HMAC algo. to sha512." - * Revert "Fix for timing attacks on MAC verification." - -0.0.1 / 2010-01-03 -================== - - * Initial release diff --git a/node_modules/cookie-signature/Readme.md b/node_modules/cookie-signature/Readme.md deleted file mode 100644 index 2559e84..0000000 --- a/node_modules/cookie-signature/Readme.md +++ /dev/null @@ -1,42 +0,0 @@ - -# cookie-signature - - Sign and unsign cookies. - -## Example - -```js -var cookie = require('cookie-signature'); - -var val = cookie.sign('hello', 'tobiiscool'); -val.should.equal('hello.DGDUkGlIkCzPz+C0B064FNgHdEjox7ch8tOBGslZ5QI'); - -var val = cookie.sign('hello', 'tobiiscool'); -cookie.unsign(val, 'tobiiscool').should.equal('hello'); -cookie.unsign(val, 'luna').should.be.false; -``` - -## License - -(The MIT License) - -Copyright (c) 2012 LearnBoost <tj@learnboost.com> - -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. \ No newline at end of file diff --git a/node_modules/cookie-signature/index.js b/node_modules/cookie-signature/index.js deleted file mode 100644 index 336d487..0000000 --- a/node_modules/cookie-signature/index.js +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Module dependencies. - */ - -var crypto = require('crypto'); - -/** - * Sign the given `val` with `secret`. - * - * @param {String} val - * @param {String|NodeJS.ArrayBufferView|crypto.KeyObject} secret - * @return {String} - * @api private - */ - -exports.sign = function(val, secret){ - if ('string' !== typeof val) throw new TypeError("Cookie value must be provided as a string."); - if (null == secret) throw new TypeError("Secret key must be provided."); - return val + '.' + crypto - .createHmac('sha256', secret) - .update(val) - .digest('base64') - .replace(/\=+$/, ''); -}; - -/** - * Unsign and decode the given `val` with `secret`, - * returning `false` if the signature is invalid. - * - * @param {String} val - * @param {String|NodeJS.ArrayBufferView|crypto.KeyObject} secret - * @return {String|Boolean} - * @api private - */ - -exports.unsign = function(val, secret){ - if ('string' !== typeof val) throw new TypeError("Signed cookie string must be provided."); - if (null == secret) throw new TypeError("Secret key must be provided."); - var str = val.slice(0, val.lastIndexOf('.')) - , mac = exports.sign(str, secret); - - return sha1(mac) == sha1(val) ? str : false; -}; - -/** - * Private - */ - -function sha1(str){ - return crypto.createHash('sha1').update(str).digest('hex'); -} diff --git a/node_modules/cookie-signature/package.json b/node_modules/cookie-signature/package.json deleted file mode 100644 index 738487b..0000000 --- a/node_modules/cookie-signature/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "cookie-signature", - "version": "1.0.7", - "description": "Sign and unsign cookies", - "keywords": ["cookie", "sign", "unsign"], - "author": "TJ Holowaychuk ", - "license": "MIT", - "repository": { "type": "git", "url": "https://github.com/visionmedia/node-cookie-signature.git"}, - "dependencies": {}, - "devDependencies": { - "mocha": "*", - "should": "*" - }, - "scripts": { - "test": "mocha --require should --reporter spec" - }, - "main": "index" -} \ No newline at end of file diff --git a/node_modules/cookie/LICENSE b/node_modules/cookie/LICENSE deleted file mode 100644 index 058b6b4..0000000 --- a/node_modules/cookie/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -(The MIT License) - -Copyright (c) 2012-2014 Roman Shtylman -Copyright (c) 2015 Douglas Christopher Wilson - -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. - diff --git a/node_modules/cookie/README.md b/node_modules/cookie/README.md deleted file mode 100644 index 71fdac1..0000000 --- a/node_modules/cookie/README.md +++ /dev/null @@ -1,317 +0,0 @@ -# cookie - -[![NPM Version][npm-version-image]][npm-url] -[![NPM Downloads][npm-downloads-image]][npm-url] -[![Node.js Version][node-image]][node-url] -[![Build Status][ci-image]][ci-url] -[![Coverage Status][coveralls-image]][coveralls-url] - -Basic HTTP cookie parser and serializer for HTTP servers. - -## Installation - -This is a [Node.js](https://nodejs.org/en/) module available through the -[npm registry](https://www.npmjs.com/). Installation is done using the -[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): - -```sh -$ npm install cookie -``` - -## API - -```js -var cookie = require('cookie'); -``` - -### cookie.parse(str, options) - -Parse an HTTP `Cookie` header string and returning an object of all cookie name-value pairs. -The `str` argument is the string representing a `Cookie` header value and `options` is an -optional object containing additional parsing options. - -```js -var cookies = cookie.parse('foo=bar; equation=E%3Dmc%5E2'); -// { foo: 'bar', equation: 'E=mc^2' } -``` - -#### Options - -`cookie.parse` accepts these properties in the options object. - -##### decode - -Specifies a function that will be used to decode a cookie's value. Since the value of a cookie -has a limited character set (and must be a simple string), this function can be used to decode -a previously-encoded cookie value into a JavaScript string or other object. - -The default function is the global `decodeURIComponent`, which will decode any URL-encoded -sequences into their byte representations. - -**note** if an error is thrown from this function, the original, non-decoded cookie value will -be returned as the cookie's value. - -### cookie.serialize(name, value, options) - -Serialize a cookie name-value pair into a `Set-Cookie` header string. The `name` argument is the -name for the cookie, the `value` argument is the value to set the cookie to, and the `options` -argument is an optional object containing additional serialization options. - -```js -var setCookie = cookie.serialize('foo', 'bar'); -// foo=bar -``` - -#### Options - -`cookie.serialize` accepts these properties in the options object. - -##### domain - -Specifies the value for the [`Domain` `Set-Cookie` attribute][rfc-6265-5.2.3]. By default, no -domain is set, and most clients will consider the cookie to apply to only the current domain. - -##### encode - -Specifies a function that will be used to encode a cookie's value. Since value of a cookie -has a limited character set (and must be a simple string), this function can be used to encode -a value into a string suited for a cookie's value. - -The default function is the global `encodeURIComponent`, which will encode a JavaScript string -into UTF-8 byte sequences and then URL-encode any that fall outside of the cookie range. - -##### expires - -Specifies the `Date` object to be the value for the [`Expires` `Set-Cookie` attribute][rfc-6265-5.2.1]. -By default, no expiration is set, and most clients will consider this a "non-persistent cookie" and -will delete it on a condition like exiting a web browser application. - -**note** the [cookie storage model specification][rfc-6265-5.3] states that if both `expires` and -`maxAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this, -so if both are set, they should point to the same date and time. - -##### httpOnly - -Specifies the `boolean` value for the [`HttpOnly` `Set-Cookie` attribute][rfc-6265-5.2.6]. When truthy, -the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly` attribute is not set. - -**note** be careful when setting this to `true`, as compliant clients will not allow client-side -JavaScript to see the cookie in `document.cookie`. - -##### maxAge - -Specifies the `number` (in seconds) to be the value for the [`Max-Age` `Set-Cookie` attribute][rfc-6265-5.2.2]. -The given number will be converted to an integer by rounding down. By default, no maximum age is set. - -**note** the [cookie storage model specification][rfc-6265-5.3] states that if both `expires` and -`maxAge` are set, then `maxAge` takes precedence, but it is possible not all clients by obey this, -so if both are set, they should point to the same date and time. - -##### partitioned - -Specifies the `boolean` value for the [`Partitioned` `Set-Cookie`](rfc-cutler-httpbis-partitioned-cookies) -attribute. When truthy, the `Partitioned` attribute is set, otherwise it is not. By default, the -`Partitioned` attribute is not set. - -**note** This is an attribute that has not yet been fully standardized, and may change in the future. -This also means many clients may ignore this attribute until they understand it. - -More information about can be found in [the proposal](https://github.com/privacycg/CHIPS). - -##### path - -Specifies the value for the [`Path` `Set-Cookie` attribute][rfc-6265-5.2.4]. By default, the path -is considered the ["default path"][rfc-6265-5.1.4]. - -##### priority - -Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1]. - - - `'low'` will set the `Priority` attribute to `Low`. - - `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set. - - `'high'` will set the `Priority` attribute to `High`. - -More information about the different priority levels can be found in -[the specification][rfc-west-cookie-priority-00-4.1]. - -**note** This is an attribute that has not yet been fully standardized, and may change in the future. -This also means many clients may ignore this attribute until they understand it. - -##### sameSite - -Specifies the `boolean` or `string` to be the value for the [`SameSite` `Set-Cookie` attribute][rfc-6265bis-09-5.4.7]. - - - `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement. - - `false` will not set the `SameSite` attribute. - - `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement. - - `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie. - - `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement. - -More information about the different enforcement levels can be found in -[the specification][rfc-6265bis-09-5.4.7]. - -**note** This is an attribute that has not yet been fully standardized, and may change in the future. -This also means many clients may ignore this attribute until they understand it. - -##### secure - -Specifies the `boolean` value for the [`Secure` `Set-Cookie` attribute][rfc-6265-5.2.5]. When truthy, -the `Secure` attribute is set, otherwise it is not. By default, the `Secure` attribute is not set. - -**note** be careful when setting this to `true`, as compliant clients will not send the cookie back to -the server in the future if the browser does not have an HTTPS connection. - -## Example - -The following example uses this module in conjunction with the Node.js core HTTP server -to prompt a user for their name and display it back on future visits. - -```js -var cookie = require('cookie'); -var escapeHtml = require('escape-html'); -var http = require('http'); -var url = require('url'); - -function onRequest(req, res) { - // Parse the query string - var query = url.parse(req.url, true, true).query; - - if (query && query.name) { - // Set a new cookie with the name - res.setHeader('Set-Cookie', cookie.serialize('name', String(query.name), { - httpOnly: true, - maxAge: 60 * 60 * 24 * 7 // 1 week - })); - - // Redirect back after setting cookie - res.statusCode = 302; - res.setHeader('Location', req.headers.referer || '/'); - res.end(); - return; - } - - // Parse the cookies on the request - var cookies = cookie.parse(req.headers.cookie || ''); - - // Get the visitor name set in the cookie - var name = cookies.name; - - res.setHeader('Content-Type', 'text/html; charset=UTF-8'); - - if (name) { - res.write('

Welcome back, ' + escapeHtml(name) + '!

'); - } else { - res.write('

Hello, new visitor!

'); - } - - res.write('
'); - res.write(' '); - res.end('
'); -} - -http.createServer(onRequest).listen(3000); -``` - -## Testing - -```sh -$ npm test -``` - -## Benchmark - -``` -$ npm run bench - -> cookie@0.5.0 bench -> node benchmark/index.js - - node@18.18.2 - acorn@8.10.0 - ada@2.6.0 - ares@1.19.1 - brotli@1.0.9 - cldr@43.1 - icu@73.2 - llhttp@6.0.11 - modules@108 - napi@9 - nghttp2@1.57.0 - nghttp3@0.7.0 - ngtcp2@0.8.1 - openssl@3.0.10+quic - simdutf@3.2.14 - tz@2023c - undici@5.26.3 - unicode@15.0 - uv@1.44.2 - uvwasi@0.0.18 - v8@10.2.154.26-node.26 - zlib@1.2.13.1-motley - -> node benchmark/parse-top.js - - cookie.parse - top sites - - 14 tests completed. - - parse accounts.google.com x 2,588,913 ops/sec ±0.74% (186 runs sampled) - parse apple.com x 2,370,002 ops/sec ±0.69% (186 runs sampled) - parse cloudflare.com x 2,213,102 ops/sec ±0.88% (188 runs sampled) - parse docs.google.com x 2,194,157 ops/sec ±1.03% (184 runs sampled) - parse drive.google.com x 2,265,084 ops/sec ±0.79% (187 runs sampled) - parse en.wikipedia.org x 457,099 ops/sec ±0.81% (186 runs sampled) - parse linkedin.com x 504,407 ops/sec ±0.89% (186 runs sampled) - parse maps.google.com x 1,230,959 ops/sec ±0.98% (186 runs sampled) - parse microsoft.com x 926,294 ops/sec ±0.88% (184 runs sampled) - parse play.google.com x 2,311,338 ops/sec ±0.83% (185 runs sampled) - parse support.google.com x 1,508,850 ops/sec ±0.86% (186 runs sampled) - parse www.google.com x 1,022,582 ops/sec ±1.32% (182 runs sampled) - parse youtu.be x 332,136 ops/sec ±1.02% (185 runs sampled) - parse youtube.com x 323,833 ops/sec ±0.77% (183 runs sampled) - -> node benchmark/parse.js - - cookie.parse - generic - - 6 tests completed. - - simple x 3,214,032 ops/sec ±1.61% (183 runs sampled) - decode x 587,237 ops/sec ±1.16% (187 runs sampled) - unquote x 2,954,618 ops/sec ±1.35% (183 runs sampled) - duplicates x 857,008 ops/sec ±0.89% (187 runs sampled) - 10 cookies x 292,133 ops/sec ±0.89% (187 runs sampled) - 100 cookies x 22,610 ops/sec ±0.68% (187 runs sampled) -``` - -## References - -- [RFC 6265: HTTP State Management Mechanism][rfc-6265] -- [Same-site Cookies][rfc-6265bis-09-5.4.7] - -[rfc-cutler-httpbis-partitioned-cookies]: https://tools.ietf.org/html/draft-cutler-httpbis-partitioned-cookies/ -[rfc-west-cookie-priority-00-4.1]: https://tools.ietf.org/html/draft-west-cookie-priority-00#section-4.1 -[rfc-6265bis-09-5.4.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-09#section-5.4.7 -[rfc-6265]: https://tools.ietf.org/html/rfc6265 -[rfc-6265-5.1.4]: https://tools.ietf.org/html/rfc6265#section-5.1.4 -[rfc-6265-5.2.1]: https://tools.ietf.org/html/rfc6265#section-5.2.1 -[rfc-6265-5.2.2]: https://tools.ietf.org/html/rfc6265#section-5.2.2 -[rfc-6265-5.2.3]: https://tools.ietf.org/html/rfc6265#section-5.2.3 -[rfc-6265-5.2.4]: https://tools.ietf.org/html/rfc6265#section-5.2.4 -[rfc-6265-5.2.5]: https://tools.ietf.org/html/rfc6265#section-5.2.5 -[rfc-6265-5.2.6]: https://tools.ietf.org/html/rfc6265#section-5.2.6 -[rfc-6265-5.3]: https://tools.ietf.org/html/rfc6265#section-5.3 - -## License - -[MIT](LICENSE) - -[ci-image]: https://badgen.net/github/checks/jshttp/cookie/master?label=ci -[ci-url]: https://github.com/jshttp/cookie/actions/workflows/ci.yml -[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/cookie/master -[coveralls-url]: https://coveralls.io/r/jshttp/cookie?branch=master -[node-image]: https://badgen.net/npm/node/cookie -[node-url]: https://nodejs.org/en/download -[npm-downloads-image]: https://badgen.net/npm/dm/cookie -[npm-url]: https://npmjs.org/package/cookie -[npm-version-image]: https://badgen.net/npm/v/cookie diff --git a/node_modules/cookie/SECURITY.md b/node_modules/cookie/SECURITY.md deleted file mode 100644 index fd4a6c5..0000000 --- a/node_modules/cookie/SECURITY.md +++ /dev/null @@ -1,25 +0,0 @@ -# Security Policies and Procedures - -## Reporting a Bug - -The `cookie` team and community take all security bugs seriously. Thank -you for improving the security of the project. We appreciate your efforts and -responsible disclosure and will make every effort to acknowledge your -contributions. - -Report security bugs by emailing the current owner(s) of `cookie`. This -information can be found in the npm registry using the command -`npm owner ls cookie`. -If unsure or unable to get the information from the above, open an issue -in the [project issue tracker](https://github.com/jshttp/cookie/issues) -asking for the current contact information. - -To ensure the timely response to your report, please ensure that the entirety -of the report is contained within the email body and not solely behind a web -link or an attachment. - -At least one owner will acknowledge your email within 48 hours, and will send a -more detailed response within 48 hours indicating the next steps in handling -your report. After the initial reply to your report, the owners will -endeavor to keep you informed of the progress towards a fix and full -announcement, and may ask for additional information or guidance. diff --git a/node_modules/cookie/index.js b/node_modules/cookie/index.js deleted file mode 100644 index acd5acd..0000000 --- a/node_modules/cookie/index.js +++ /dev/null @@ -1,335 +0,0 @@ -/*! - * cookie - * Copyright(c) 2012-2014 Roman Shtylman - * Copyright(c) 2015 Douglas Christopher Wilson - * MIT Licensed - */ - -'use strict'; - -/** - * Module exports. - * @public - */ - -exports.parse = parse; -exports.serialize = serialize; - -/** - * Module variables. - * @private - */ - -var __toString = Object.prototype.toString -var __hasOwnProperty = Object.prototype.hasOwnProperty - -/** - * RegExp to match cookie-name in RFC 6265 sec 4.1.1 - * This refers out to the obsoleted definition of token in RFC 2616 sec 2.2 - * which has been replaced by the token definition in RFC 7230 appendix B. - * - * cookie-name = token - * token = 1*tchar - * tchar = "!" / "#" / "$" / "%" / "&" / "'" / - * "*" / "+" / "-" / "." / "^" / "_" / - * "`" / "|" / "~" / DIGIT / ALPHA - */ - -var cookieNameRegExp = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/; - -/** - * RegExp to match cookie-value in RFC 6265 sec 4.1.1 - * - * cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) - * cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E - * ; US-ASCII characters excluding CTLs, - * ; whitespace DQUOTE, comma, semicolon, - * ; and backslash - */ - -var cookieValueRegExp = /^("?)[\u0021\u0023-\u002B\u002D-\u003A\u003C-\u005B\u005D-\u007E]*\1$/; - -/** - * RegExp to match domain-value in RFC 6265 sec 4.1.1 - * - * domain-value = - * ; defined in [RFC1034], Section 3.5, as - * ; enhanced by [RFC1123], Section 2.1 - * =