From cd3cdc57576b1f1cba5825e856a270ce93bd6af6 Mon Sep 17 00:00:00 2001 From: Diwakar Singh <101459162+itsdiwakarsingh@users.noreply.github.com> Date: Sun, 17 Aug 2025 20:19:31 +0530 Subject: [PATCH 01/12] actuall idk --- .../starter/.vscode/c_cpp_properties.json | 18 + 2-how-node-works/starter/.vscode/launch.json | 24 + .../starter/.vscode/settings.json | 60 + 2-how-node-works/starter/event-loop.js | 44 + 2-how-node-works/starter/event.js | 58 + 2-how-node-works/starter/stream.js | 33 + .../starter/tempCodeRunnerFile.js | 2 + 3-asynchronous-JS/final/dog-img.txt | 6 +- 3-asynchronous-JS/index.js | 17 + 3-asynchronous-JS/node_modules/.bin/mime | 16 + 3-asynchronous-JS/node_modules/.bin/mime.cmd | 17 + 3-asynchronous-JS/node_modules/.bin/mime.ps1 | 28 + .../node_modules/.package-lock.json | 459 + .../node_modules/asap/CHANGES.md | 70 + .../node_modules/asap/LICENSE.md | 21 + 3-asynchronous-JS/node_modules/asap/README.md | 237 + 3-asynchronous-JS/node_modules/asap/asap.js | 65 + .../node_modules/asap/browser-asap.js | 66 + .../node_modules/asap/browser-raw.js | 223 + .../node_modules/asap/package.json | 58 + 3-asynchronous-JS/node_modules/asap/raw.js | 101 + .../node_modules/asynckit/LICENSE | 21 + .../node_modules/asynckit/README.md | 233 + .../node_modules/asynckit/bench.js | 76 + .../node_modules/asynckit/index.js | 6 + .../node_modules/asynckit/lib/abort.js | 29 + .../node_modules/asynckit/lib/async.js | 34 + .../node_modules/asynckit/lib/defer.js | 26 + .../node_modules/asynckit/lib/iterate.js | 75 + .../asynckit/lib/readable_asynckit.js | 91 + .../asynckit/lib/readable_parallel.js | 25 + .../asynckit/lib/readable_serial.js | 25 + .../asynckit/lib/readable_serial_ordered.js | 29 + .../node_modules/asynckit/lib/state.js | 37 + .../node_modules/asynckit/lib/streamify.js | 141 + .../node_modules/asynckit/lib/terminator.js | 29 + .../node_modules/asynckit/package.json | 63 + .../node_modules/asynckit/parallel.js | 43 + .../node_modules/asynckit/serial.js | 17 + .../node_modules/asynckit/serialOrdered.js | 75 + .../node_modules/asynckit/stream.js | 21 + .../call-bind-apply-helpers/.eslintrc | 16 + .../.github/FUNDING.yml | 12 + .../call-bind-apply-helpers/.nycrc | 9 + .../call-bind-apply-helpers/CHANGELOG.md | 23 + .../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 | 46 + .../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 + .../call-bound/.github/FUNDING.yml | 12 + .../node_modules/call-bound/.nycrc | 9 + .../node_modules/call-bound/CHANGELOG.md | 34 + .../node_modules/call-bound/LICENSE | 21 + .../node_modules/call-bound/README.md | 53 + .../node_modules/call-bound/index.d.ts | 13 + .../node_modules/call-bound/index.js | 18 + .../node_modules/call-bound/package.json | 99 + .../node_modules/call-bound/test/index.js | 54 + .../node_modules/call-bound/tsconfig.json | 9 + .../node_modules/combined-stream/License | 19 + .../node_modules/combined-stream/Readme.md | 138 + .../combined-stream/lib/combined_stream.js | 208 + .../node_modules/combined-stream/package.json | 25 + .../node_modules/combined-stream/yarn.lock | 17 + .../node_modules/component-emitter/LICENSE | 24 + .../node_modules/component-emitter/Readme.md | 74 + .../node_modules/component-emitter/index.js | 175 + .../component-emitter/package.json | 28 + .../node_modules/cookiejar/LICENSE | 9 + .../node_modules/cookiejar/cookiejar.js | 281 + .../node_modules/cookiejar/package.json | 26 + .../node_modules/cookiejar/readme.md | 60 + 3-asynchronous-JS/node_modules/debug/LICENSE | 20 + .../node_modules/debug/README.md | 481 + .../node_modules/debug/package.json | 65 + .../node_modules/debug/src/browser.js | 272 + .../node_modules/debug/src/common.js | 292 + .../node_modules/debug/src/index.js | 10 + .../node_modules/debug/src/node.js | 263 + .../node_modules/delayed-stream/.npmignore | 1 + .../node_modules/delayed-stream/License | 19 + .../node_modules/delayed-stream/Makefile | 7 + .../node_modules/delayed-stream/Readme.md | 141 + .../delayed-stream/lib/delayed_stream.js | 107 + .../node_modules/delayed-stream/package.json | 27 + .../node_modules/dezalgo/LICENSE | 15 + .../node_modules/dezalgo/README.md | 29 + .../node_modules/dezalgo/dezalgo.js | 22 + .../node_modules/dezalgo/package.json | 46 + .../node_modules/dunder-proto/.eslintrc | 5 + .../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/es-define-property/.eslintrc | 13 + .../es-define-property/.github/FUNDING.yml | 12 + .../node_modules/es-define-property/.nycrc | 9 + .../es-define-property/CHANGELOG.md | 29 + .../node_modules/es-define-property/LICENSE | 21 + .../node_modules/es-define-property/README.md | 49 + .../es-define-property/index.d.ts | 3 + .../node_modules/es-define-property/index.js | 14 + .../es-define-property/package.json | 81 + .../es-define-property/test/index.js | 56 + .../es-define-property/tsconfig.json | 10 + .../node_modules/es-errors/.eslintrc | 5 + .../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 | 16 + .../node_modules/es-object-atoms/LICENSE | 21 + .../node_modules/es-object-atoms/README.md | 56 + .../RequireObjectCoercible.d.ts | 3 + .../es-object-atoms/RequireObjectCoercible.js | 11 + .../es-object-atoms/ToObject.d.ts | 3 + .../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/package.json | 79 + .../es-object-atoms/test/index.js | 28 + .../es-object-atoms/tsconfig.json | 6 + .../fast-safe-stringify/.travis.yml | 8 + .../fast-safe-stringify/CHANGELOG.md | 17 + .../node_modules/fast-safe-stringify/LICENSE | 23 + .../fast-safe-stringify/benchmark.js | 137 + .../fast-safe-stringify/index.d.ts | 23 + .../node_modules/fast-safe-stringify/index.js | 229 + .../fast-safe-stringify/package.json | 46 + .../fast-safe-stringify/readme.md | 170 + .../fast-safe-stringify/test-stable.js | 404 + .../node_modules/fast-safe-stringify/test.js | 397 + .../node_modules/form-data/License | 19 + .../node_modules/form-data/Readme.md | 358 + .../node_modules/form-data/index.d.ts | 62 + .../node_modules/form-data/lib/browser.js | 2 + .../node_modules/form-data/lib/form_data.js | 501 + .../node_modules/form-data/lib/populate.js | 10 + .../node_modules/form-data/package.json | 71 + .../node_modules/formidable/LICENSE | 21 + .../node_modules/formidable/README.md | 884 ++ .../node_modules/formidable/README_pt_BR.md | 841 ++ .../formidable/dist/helpers/firstValues.cjs | 394 + .../formidable/dist/helpers/readBooleans.cjs | 12 + .../node_modules/formidable/dist/index.cjs | 1690 ++++ .../formidable/dist/parsers/JSON.cjs | 35 + .../formidable/dist/parsers/Multipart.cjs | 372 + .../formidable/dist/parsers/OctetStream.cjs | 14 + .../formidable/dist/parsers/Querystring.cjs | 38 + .../dist/parsers/StreamingQuerystring.cjs | 131 + .../node_modules/formidable/package.json | 140 + .../node_modules/formidable/src/Formidable.js | 684 ++ .../formidable/src/FormidableError.js | 51 + .../formidable/src/PersistentFile.js | 88 + .../formidable/src/VolatileFile.js | 80 + .../formidable/src/helpers/firstValues.js | 19 + .../formidable/src/helpers/readBooleans.js | 10 + .../node_modules/formidable/src/index.js | 32 + .../formidable/src/parsers/Dummy.js | 19 + .../formidable/src/parsers/JSON.js | 30 + .../formidable/src/parsers/Multipart.js | 356 + .../formidable/src/parsers/OctetStream.js | 10 + .../formidable/src/parsers/Querystring.js | 33 + .../src/parsers/StreamingQuerystring.js | 117 + .../formidable/src/parsers/index.js | 15 + .../formidable/src/plugins/index.js | 6 + .../formidable/src/plugins/json.js | 39 + .../formidable/src/plugins/multipart.js | 173 + .../formidable/src/plugins/octetstream.js | 84 + .../formidable/src/plugins/querystring.js | 41 + .../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 + .../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 | 38 + .../get-intrinsic/.github/FUNDING.yml | 12 + .../node_modules/get-intrinsic/.nycrc | 9 + .../node_modules/get-intrinsic/CHANGELOG.md | 170 + .../node_modules/get-intrinsic/LICENSE | 21 + .../node_modules/get-intrinsic/README.md | 71 + .../node_modules/get-intrinsic/index.js | 372 + .../node_modules/get-intrinsic/package.json | 97 + .../get-intrinsic/test/GetIntrinsic.js | 274 + 3-asynchronous-JS/node_modules/gopd/.eslintrc | 16 + .../node_modules/gopd/.github/FUNDING.yml | 12 + .../node_modules/gopd/CHANGELOG.md | 45 + 3-asynchronous-JS/node_modules/gopd/LICENSE | 21 + 3-asynchronous-JS/node_modules/gopd/README.md | 40 + 3-asynchronous-JS/node_modules/gopd/gOPD.d.ts | 1 + 3-asynchronous-JS/node_modules/gopd/gOPD.js | 4 + .../node_modules/gopd/index.d.ts | 5 + 3-asynchronous-JS/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 + .../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/.eslintrc | 5 + .../node_modules/hasown/.github/FUNDING.yml | 12 + 3-asynchronous-JS/node_modules/hasown/.nycrc | 13 + .../node_modules/hasown/CHANGELOG.md | 40 + 3-asynchronous-JS/node_modules/hasown/LICENSE | 21 + .../node_modules/hasown/README.md | 40 + .../node_modules/hasown/index.d.ts | 3 + .../node_modules/hasown/index.js | 8 + .../node_modules/hasown/package.json | 92 + .../node_modules/hasown/tsconfig.json | 6 + .../node_modules/hexoid/dist/index.d.ts | 1 + .../node_modules/hexoid/dist/index.js | 1 + .../node_modules/hexoid/dist/index.mjs | 1 + 3-asynchronous-JS/node_modules/hexoid/license | 9 + .../node_modules/hexoid/package.json | 45 + .../node_modules/hexoid/readme.md | 118 + .../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 + .../math-intrinsics/isFinite.d.ts | 3 + .../node_modules/math-intrinsics/isFinite.js | 12 + .../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 + .../math-intrinsics/test/index.js | 192 + .../math-intrinsics/tsconfig.json | 3 + .../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/CHANGELOG.md | 296 + 3-asynchronous-JS/node_modules/mime/LICENSE | 21 + 3-asynchronous-JS/node_modules/mime/Mime.js | 97 + 3-asynchronous-JS/node_modules/mime/README.md | 187 + 3-asynchronous-JS/node_modules/mime/cli.js | 46 + 3-asynchronous-JS/node_modules/mime/index.js | 4 + 3-asynchronous-JS/node_modules/mime/lite.js | 4 + .../node_modules/mime/package.json | 52 + .../node_modules/mime/types/other.js | 1 + .../node_modules/mime/types/standard.js | 1 + 3-asynchronous-JS/node_modules/ms/index.js | 162 + 3-asynchronous-JS/node_modules/ms/license.md | 21 + .../node_modules/ms/package.json | 38 + 3-asynchronous-JS/node_modules/ms/readme.md | 59 + .../node_modules/object-inspect/.eslintrc | 53 + .../object-inspect/.github/FUNDING.yml | 12 + .../node_modules/object-inspect/.nycrc | 13 + .../node_modules/object-inspect/CHANGELOG.md | 416 + .../node_modules/object-inspect/LICENSE | 21 + .../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 | 541 ++ .../object-inspect/package-support.json | 20 + .../node_modules/object-inspect/package.json | 104 + .../object-inspect/readme.markdown | 84 + .../object-inspect/test-core-js.js | 26 + .../object-inspect/test/bigint.js | 58 + .../object-inspect/test/browser/dom.js | 15 + .../object-inspect/test/circular.js | 16 + .../node_modules/object-inspect/test/deep.js | 12 + .../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 + .../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 + .../object-inspect/test/inspect.js | 139 + .../object-inspect/test/lowbyte.js | 12 + .../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 + .../object-inspect/test/values.js | 211 + .../object-inspect/util.inspect.js | 1 + 3-asynchronous-JS/node_modules/once/LICENSE | 15 + 3-asynchronous-JS/node_modules/once/README.md | 79 + 3-asynchronous-JS/node_modules/once/once.js | 42 + .../node_modules/once/package.json | 33 + .../node_modules/qs/.editorconfig | 46 + 3-asynchronous-JS/node_modules/qs/.eslintrc | 39 + .../node_modules/qs/.github/FUNDING.yml | 12 + 3-asynchronous-JS/node_modules/qs/.nycrc | 13 + .../node_modules/qs/CHANGELOG.md | 612 ++ 3-asynchronous-JS/node_modules/qs/LICENSE.md | 29 + 3-asynchronous-JS/node_modules/qs/README.md | 709 ++ 3-asynchronous-JS/node_modules/qs/dist/qs.js | 90 + .../node_modules/qs/lib/formats.js | 23 + .../node_modules/qs/lib/index.js | 11 + .../node_modules/qs/lib/parse.js | 297 + .../node_modules/qs/lib/stringify.js | 356 + .../node_modules/qs/lib/utils.js | 268 + .../node_modules/qs/package.json | 93 + .../node_modules/qs/test/empty-keys-cases.js | 267 + .../node_modules/qs/test/parse.js | 1187 +++ .../node_modules/qs/test/stringify.js | 1306 +++ .../node_modules/qs/test/utils.js | 150 + .../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 + .../side-channel-list/CHANGELOG.md | 15 + .../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 | 113 + .../node_modules/side-channel-list/list.d.ts | 14 + .../side-channel-list/package.json | 77 + .../side-channel-list/test/index.js | 104 + .../side-channel-list/tsconfig.json | 9 + .../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 + .../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 + .../side-channel-map/package.json | 80 + .../side-channel-map/test/index.js | 114 + .../side-channel-map/tsconfig.json | 9 + .../side-channel-weakmap/.editorconfig | 9 + .../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 + .../side-channel-weakmap/README.md | 62 + .../side-channel-weakmap/index.d.ts | 15 + .../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 + .../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/superagent/LICENSE | 22 + .../node_modules/superagent/README.md | 273 + .../superagent/dist/superagent.js | 3229 +++++++ .../superagent/dist/superagent.min.js | 1 + .../node_modules/superagent/lib/agent-base.js | 28 + .../node_modules/superagent/lib/client.js | 949 ++ .../node_modules/superagent/lib/node/agent.js | 100 + .../superagent/lib/node/decompress.js | 20 + .../superagent/lib/node/http2wrapper.js | 154 + .../node_modules/superagent/lib/node/index.js | 1318 +++ .../superagent/lib/node/parsers/image.js | 13 + .../superagent/lib/node/parsers/index.js | 11 + .../superagent/lib/node/parsers/json.js | 25 + .../superagent/lib/node/parsers/text.js | 11 + .../superagent/lib/node/parsers/urlencoded.js | 22 + .../superagent/lib/node/response.js | 143 + .../node_modules/superagent/lib/node/unzip.js | 74 + .../superagent/lib/request-base.js | 720 ++ .../superagent/lib/response-base.js | 120 + .../node_modules/superagent/lib/utils.js | 122 + .../node_modules/superagent/package.json | 131 + 3-asynchronous-JS/node_modules/wrappy/LICENSE | 15 + .../node_modules/wrappy/README.md | 36 + .../node_modules/wrappy/package.json | 29 + .../node_modules/wrappy/wrappy.js | 33 + 3-asynchronous-JS/package-lock.json | 467 + 3-asynchronous-JS/package.json | 14 + 478 files changed, 49340 insertions(+), 3 deletions(-) create mode 100644 2-how-node-works/starter/.vscode/c_cpp_properties.json create mode 100644 2-how-node-works/starter/.vscode/launch.json create mode 100644 2-how-node-works/starter/.vscode/settings.json create mode 100644 2-how-node-works/starter/event-loop.js create mode 100644 2-how-node-works/starter/event.js create mode 100644 2-how-node-works/starter/stream.js create mode 100644 2-how-node-works/starter/tempCodeRunnerFile.js create mode 100644 3-asynchronous-JS/index.js create mode 100644 3-asynchronous-JS/node_modules/.bin/mime create mode 100644 3-asynchronous-JS/node_modules/.bin/mime.cmd create mode 100644 3-asynchronous-JS/node_modules/.bin/mime.ps1 create mode 100644 3-asynchronous-JS/node_modules/.package-lock.json create mode 100644 3-asynchronous-JS/node_modules/asap/CHANGES.md create mode 100644 3-asynchronous-JS/node_modules/asap/LICENSE.md create mode 100644 3-asynchronous-JS/node_modules/asap/README.md create mode 100644 3-asynchronous-JS/node_modules/asap/asap.js create mode 100644 3-asynchronous-JS/node_modules/asap/browser-asap.js create mode 100644 3-asynchronous-JS/node_modules/asap/browser-raw.js create mode 100644 3-asynchronous-JS/node_modules/asap/package.json create mode 100644 3-asynchronous-JS/node_modules/asap/raw.js create mode 100644 3-asynchronous-JS/node_modules/asynckit/LICENSE create mode 100644 3-asynchronous-JS/node_modules/asynckit/README.md create mode 100644 3-asynchronous-JS/node_modules/asynckit/bench.js create mode 100644 3-asynchronous-JS/node_modules/asynckit/index.js create mode 100644 3-asynchronous-JS/node_modules/asynckit/lib/abort.js create mode 100644 3-asynchronous-JS/node_modules/asynckit/lib/async.js create mode 100644 3-asynchronous-JS/node_modules/asynckit/lib/defer.js create mode 100644 3-asynchronous-JS/node_modules/asynckit/lib/iterate.js create mode 100644 3-asynchronous-JS/node_modules/asynckit/lib/readable_asynckit.js create mode 100644 3-asynchronous-JS/node_modules/asynckit/lib/readable_parallel.js create mode 100644 3-asynchronous-JS/node_modules/asynckit/lib/readable_serial.js create mode 100644 3-asynchronous-JS/node_modules/asynckit/lib/readable_serial_ordered.js create mode 100644 3-asynchronous-JS/node_modules/asynckit/lib/state.js create mode 100644 3-asynchronous-JS/node_modules/asynckit/lib/streamify.js create mode 100644 3-asynchronous-JS/node_modules/asynckit/lib/terminator.js create mode 100644 3-asynchronous-JS/node_modules/asynckit/package.json create mode 100644 3-asynchronous-JS/node_modules/asynckit/parallel.js create mode 100644 3-asynchronous-JS/node_modules/asynckit/serial.js create mode 100644 3-asynchronous-JS/node_modules/asynckit/serialOrdered.js create mode 100644 3-asynchronous-JS/node_modules/asynckit/stream.js create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/.nycrc create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/LICENSE create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/README.md create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/actualApply.d.ts create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/actualApply.js create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/applyBind.d.ts create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/applyBind.js create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/functionApply.d.ts create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/functionApply.js create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/functionCall.d.ts create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/functionCall.js create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/index.d.ts create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/index.js create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/package.json create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/reflectApply.d.ts create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/reflectApply.js create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/test/index.js create mode 100644 3-asynchronous-JS/node_modules/call-bind-apply-helpers/tsconfig.json create mode 100644 3-asynchronous-JS/node_modules/call-bound/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/call-bound/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/call-bound/.nycrc create mode 100644 3-asynchronous-JS/node_modules/call-bound/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/call-bound/LICENSE create mode 100644 3-asynchronous-JS/node_modules/call-bound/README.md create mode 100644 3-asynchronous-JS/node_modules/call-bound/index.d.ts create mode 100644 3-asynchronous-JS/node_modules/call-bound/index.js create mode 100644 3-asynchronous-JS/node_modules/call-bound/package.json create mode 100644 3-asynchronous-JS/node_modules/call-bound/test/index.js create mode 100644 3-asynchronous-JS/node_modules/call-bound/tsconfig.json create mode 100644 3-asynchronous-JS/node_modules/combined-stream/License create mode 100644 3-asynchronous-JS/node_modules/combined-stream/Readme.md create mode 100644 3-asynchronous-JS/node_modules/combined-stream/lib/combined_stream.js create mode 100644 3-asynchronous-JS/node_modules/combined-stream/package.json create mode 100644 3-asynchronous-JS/node_modules/combined-stream/yarn.lock create mode 100644 3-asynchronous-JS/node_modules/component-emitter/LICENSE create mode 100644 3-asynchronous-JS/node_modules/component-emitter/Readme.md create mode 100644 3-asynchronous-JS/node_modules/component-emitter/index.js create mode 100644 3-asynchronous-JS/node_modules/component-emitter/package.json create mode 100644 3-asynchronous-JS/node_modules/cookiejar/LICENSE create mode 100644 3-asynchronous-JS/node_modules/cookiejar/cookiejar.js create mode 100644 3-asynchronous-JS/node_modules/cookiejar/package.json create mode 100644 3-asynchronous-JS/node_modules/cookiejar/readme.md create mode 100644 3-asynchronous-JS/node_modules/debug/LICENSE create mode 100644 3-asynchronous-JS/node_modules/debug/README.md create mode 100644 3-asynchronous-JS/node_modules/debug/package.json create mode 100644 3-asynchronous-JS/node_modules/debug/src/browser.js create mode 100644 3-asynchronous-JS/node_modules/debug/src/common.js create mode 100644 3-asynchronous-JS/node_modules/debug/src/index.js create mode 100644 3-asynchronous-JS/node_modules/debug/src/node.js create mode 100644 3-asynchronous-JS/node_modules/delayed-stream/.npmignore create mode 100644 3-asynchronous-JS/node_modules/delayed-stream/License create mode 100644 3-asynchronous-JS/node_modules/delayed-stream/Makefile create mode 100644 3-asynchronous-JS/node_modules/delayed-stream/Readme.md create mode 100644 3-asynchronous-JS/node_modules/delayed-stream/lib/delayed_stream.js create mode 100644 3-asynchronous-JS/node_modules/delayed-stream/package.json create mode 100644 3-asynchronous-JS/node_modules/dezalgo/LICENSE create mode 100644 3-asynchronous-JS/node_modules/dezalgo/README.md create mode 100644 3-asynchronous-JS/node_modules/dezalgo/dezalgo.js create mode 100644 3-asynchronous-JS/node_modules/dezalgo/package.json create mode 100644 3-asynchronous-JS/node_modules/dunder-proto/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/dunder-proto/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/dunder-proto/.nycrc create mode 100644 3-asynchronous-JS/node_modules/dunder-proto/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/dunder-proto/LICENSE create mode 100644 3-asynchronous-JS/node_modules/dunder-proto/README.md create mode 100644 3-asynchronous-JS/node_modules/dunder-proto/get.d.ts create mode 100644 3-asynchronous-JS/node_modules/dunder-proto/get.js create mode 100644 3-asynchronous-JS/node_modules/dunder-proto/package.json create mode 100644 3-asynchronous-JS/node_modules/dunder-proto/set.d.ts create mode 100644 3-asynchronous-JS/node_modules/dunder-proto/set.js create mode 100644 3-asynchronous-JS/node_modules/dunder-proto/test/get.js create mode 100644 3-asynchronous-JS/node_modules/dunder-proto/test/index.js create mode 100644 3-asynchronous-JS/node_modules/dunder-proto/test/set.js create mode 100644 3-asynchronous-JS/node_modules/dunder-proto/tsconfig.json create mode 100644 3-asynchronous-JS/node_modules/es-define-property/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/es-define-property/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/es-define-property/.nycrc create mode 100644 3-asynchronous-JS/node_modules/es-define-property/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/es-define-property/LICENSE create mode 100644 3-asynchronous-JS/node_modules/es-define-property/README.md create mode 100644 3-asynchronous-JS/node_modules/es-define-property/index.d.ts create mode 100644 3-asynchronous-JS/node_modules/es-define-property/index.js create mode 100644 3-asynchronous-JS/node_modules/es-define-property/package.json create mode 100644 3-asynchronous-JS/node_modules/es-define-property/test/index.js create mode 100644 3-asynchronous-JS/node_modules/es-define-property/tsconfig.json create mode 100644 3-asynchronous-JS/node_modules/es-errors/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/es-errors/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/es-errors/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/es-errors/LICENSE create mode 100644 3-asynchronous-JS/node_modules/es-errors/README.md create mode 100644 3-asynchronous-JS/node_modules/es-errors/eval.d.ts create mode 100644 3-asynchronous-JS/node_modules/es-errors/eval.js create mode 100644 3-asynchronous-JS/node_modules/es-errors/index.d.ts create mode 100644 3-asynchronous-JS/node_modules/es-errors/index.js create mode 100644 3-asynchronous-JS/node_modules/es-errors/package.json create mode 100644 3-asynchronous-JS/node_modules/es-errors/range.d.ts create mode 100644 3-asynchronous-JS/node_modules/es-errors/range.js create mode 100644 3-asynchronous-JS/node_modules/es-errors/ref.d.ts create mode 100644 3-asynchronous-JS/node_modules/es-errors/ref.js create mode 100644 3-asynchronous-JS/node_modules/es-errors/syntax.d.ts create mode 100644 3-asynchronous-JS/node_modules/es-errors/syntax.js create mode 100644 3-asynchronous-JS/node_modules/es-errors/test/index.js create mode 100644 3-asynchronous-JS/node_modules/es-errors/tsconfig.json create mode 100644 3-asynchronous-JS/node_modules/es-errors/type.d.ts create mode 100644 3-asynchronous-JS/node_modules/es-errors/type.js create mode 100644 3-asynchronous-JS/node_modules/es-errors/uri.d.ts create mode 100644 3-asynchronous-JS/node_modules/es-errors/uri.js create mode 100644 3-asynchronous-JS/node_modules/es-object-atoms/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/es-object-atoms/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/es-object-atoms/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/es-object-atoms/LICENSE create mode 100644 3-asynchronous-JS/node_modules/es-object-atoms/README.md create mode 100644 3-asynchronous-JS/node_modules/es-object-atoms/RequireObjectCoercible.d.ts create mode 100644 3-asynchronous-JS/node_modules/es-object-atoms/RequireObjectCoercible.js create mode 100644 3-asynchronous-JS/node_modules/es-object-atoms/ToObject.d.ts create mode 100644 3-asynchronous-JS/node_modules/es-object-atoms/ToObject.js create mode 100644 3-asynchronous-JS/node_modules/es-object-atoms/index.d.ts create mode 100644 3-asynchronous-JS/node_modules/es-object-atoms/index.js create mode 100644 3-asynchronous-JS/node_modules/es-object-atoms/package.json create mode 100644 3-asynchronous-JS/node_modules/es-object-atoms/test/index.js create mode 100644 3-asynchronous-JS/node_modules/es-object-atoms/tsconfig.json create mode 100644 3-asynchronous-JS/node_modules/fast-safe-stringify/.travis.yml create mode 100644 3-asynchronous-JS/node_modules/fast-safe-stringify/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/fast-safe-stringify/LICENSE create mode 100644 3-asynchronous-JS/node_modules/fast-safe-stringify/benchmark.js create mode 100644 3-asynchronous-JS/node_modules/fast-safe-stringify/index.d.ts create mode 100644 3-asynchronous-JS/node_modules/fast-safe-stringify/index.js create mode 100644 3-asynchronous-JS/node_modules/fast-safe-stringify/package.json create mode 100644 3-asynchronous-JS/node_modules/fast-safe-stringify/readme.md create mode 100644 3-asynchronous-JS/node_modules/fast-safe-stringify/test-stable.js create mode 100644 3-asynchronous-JS/node_modules/fast-safe-stringify/test.js create mode 100644 3-asynchronous-JS/node_modules/form-data/License create mode 100644 3-asynchronous-JS/node_modules/form-data/Readme.md create mode 100644 3-asynchronous-JS/node_modules/form-data/index.d.ts create mode 100644 3-asynchronous-JS/node_modules/form-data/lib/browser.js create mode 100644 3-asynchronous-JS/node_modules/form-data/lib/form_data.js create mode 100644 3-asynchronous-JS/node_modules/form-data/lib/populate.js create mode 100644 3-asynchronous-JS/node_modules/form-data/package.json create mode 100644 3-asynchronous-JS/node_modules/formidable/LICENSE create mode 100644 3-asynchronous-JS/node_modules/formidable/README.md create mode 100644 3-asynchronous-JS/node_modules/formidable/README_pt_BR.md create mode 100644 3-asynchronous-JS/node_modules/formidable/dist/helpers/firstValues.cjs create mode 100644 3-asynchronous-JS/node_modules/formidable/dist/helpers/readBooleans.cjs create mode 100644 3-asynchronous-JS/node_modules/formidable/dist/index.cjs create mode 100644 3-asynchronous-JS/node_modules/formidable/dist/parsers/JSON.cjs create mode 100644 3-asynchronous-JS/node_modules/formidable/dist/parsers/Multipart.cjs create mode 100644 3-asynchronous-JS/node_modules/formidable/dist/parsers/OctetStream.cjs create mode 100644 3-asynchronous-JS/node_modules/formidable/dist/parsers/Querystring.cjs create mode 100644 3-asynchronous-JS/node_modules/formidable/dist/parsers/StreamingQuerystring.cjs create mode 100644 3-asynchronous-JS/node_modules/formidable/package.json create mode 100644 3-asynchronous-JS/node_modules/formidable/src/Formidable.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/FormidableError.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/PersistentFile.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/VolatileFile.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/helpers/firstValues.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/helpers/readBooleans.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/index.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/parsers/Dummy.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/parsers/JSON.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/parsers/Multipart.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/parsers/OctetStream.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/parsers/Querystring.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/parsers/StreamingQuerystring.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/parsers/index.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/plugins/index.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/plugins/json.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/plugins/multipart.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/plugins/octetstream.js create mode 100644 3-asynchronous-JS/node_modules/formidable/src/plugins/querystring.js create mode 100644 3-asynchronous-JS/node_modules/function-bind/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/function-bind/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/function-bind/.github/SECURITY.md create mode 100644 3-asynchronous-JS/node_modules/function-bind/.nycrc create mode 100644 3-asynchronous-JS/node_modules/function-bind/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/function-bind/LICENSE create mode 100644 3-asynchronous-JS/node_modules/function-bind/README.md create mode 100644 3-asynchronous-JS/node_modules/function-bind/implementation.js create mode 100644 3-asynchronous-JS/node_modules/function-bind/index.js create mode 100644 3-asynchronous-JS/node_modules/function-bind/package.json create mode 100644 3-asynchronous-JS/node_modules/function-bind/test/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/function-bind/test/index.js create mode 100644 3-asynchronous-JS/node_modules/get-intrinsic/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/get-intrinsic/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/get-intrinsic/.nycrc create mode 100644 3-asynchronous-JS/node_modules/get-intrinsic/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/get-intrinsic/LICENSE create mode 100644 3-asynchronous-JS/node_modules/get-intrinsic/README.md create mode 100644 3-asynchronous-JS/node_modules/get-intrinsic/index.js create mode 100644 3-asynchronous-JS/node_modules/get-intrinsic/package.json create mode 100644 3-asynchronous-JS/node_modules/get-intrinsic/test/GetIntrinsic.js create mode 100644 3-asynchronous-JS/node_modules/gopd/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/gopd/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/gopd/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/gopd/LICENSE create mode 100644 3-asynchronous-JS/node_modules/gopd/README.md create mode 100644 3-asynchronous-JS/node_modules/gopd/gOPD.d.ts create mode 100644 3-asynchronous-JS/node_modules/gopd/gOPD.js create mode 100644 3-asynchronous-JS/node_modules/gopd/index.d.ts create mode 100644 3-asynchronous-JS/node_modules/gopd/index.js create mode 100644 3-asynchronous-JS/node_modules/gopd/package.json create mode 100644 3-asynchronous-JS/node_modules/gopd/test/index.js create mode 100644 3-asynchronous-JS/node_modules/gopd/tsconfig.json create mode 100644 3-asynchronous-JS/node_modules/has-symbols/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/has-symbols/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/has-symbols/.nycrc create mode 100644 3-asynchronous-JS/node_modules/has-symbols/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/has-symbols/LICENSE create mode 100644 3-asynchronous-JS/node_modules/has-symbols/README.md create mode 100644 3-asynchronous-JS/node_modules/has-symbols/index.d.ts create mode 100644 3-asynchronous-JS/node_modules/has-symbols/index.js create mode 100644 3-asynchronous-JS/node_modules/has-symbols/package.json create mode 100644 3-asynchronous-JS/node_modules/has-symbols/shams.d.ts create mode 100644 3-asynchronous-JS/node_modules/has-symbols/shams.js create mode 100644 3-asynchronous-JS/node_modules/has-symbols/test/index.js create mode 100644 3-asynchronous-JS/node_modules/has-symbols/test/shams/core-js.js create mode 100644 3-asynchronous-JS/node_modules/has-symbols/test/shams/get-own-property-symbols.js create mode 100644 3-asynchronous-JS/node_modules/has-symbols/test/tests.js create mode 100644 3-asynchronous-JS/node_modules/has-symbols/tsconfig.json create mode 100644 3-asynchronous-JS/node_modules/hasown/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/hasown/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/hasown/.nycrc create mode 100644 3-asynchronous-JS/node_modules/hasown/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/hasown/LICENSE create mode 100644 3-asynchronous-JS/node_modules/hasown/README.md create mode 100644 3-asynchronous-JS/node_modules/hasown/index.d.ts create mode 100644 3-asynchronous-JS/node_modules/hasown/index.js create mode 100644 3-asynchronous-JS/node_modules/hasown/package.json create mode 100644 3-asynchronous-JS/node_modules/hasown/tsconfig.json create mode 100644 3-asynchronous-JS/node_modules/hexoid/dist/index.d.ts create mode 100644 3-asynchronous-JS/node_modules/hexoid/dist/index.js create mode 100644 3-asynchronous-JS/node_modules/hexoid/dist/index.mjs create mode 100644 3-asynchronous-JS/node_modules/hexoid/license create mode 100644 3-asynchronous-JS/node_modules/hexoid/package.json create mode 100644 3-asynchronous-JS/node_modules/hexoid/readme.md create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/LICENSE create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/README.md create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/abs.d.ts create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/abs.js create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/constants/maxArrayLength.d.ts create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/constants/maxArrayLength.js create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/constants/maxSafeInteger.d.ts create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/constants/maxSafeInteger.js create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/constants/maxValue.d.ts create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/constants/maxValue.js create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/floor.d.ts create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/floor.js create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/isFinite.d.ts create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/isFinite.js create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/isInteger.d.ts create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/isInteger.js create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/isNaN.d.ts create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/isNaN.js create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/isNegativeZero.d.ts create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/isNegativeZero.js create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/max.d.ts create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/max.js create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/min.d.ts create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/min.js create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/mod.d.ts create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/mod.js create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/package.json create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/pow.d.ts create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/pow.js create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/round.d.ts create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/round.js create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/sign.d.ts create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/sign.js create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/test/index.js create mode 100644 3-asynchronous-JS/node_modules/math-intrinsics/tsconfig.json create mode 100644 3-asynchronous-JS/node_modules/methods/HISTORY.md create mode 100644 3-asynchronous-JS/node_modules/methods/LICENSE create mode 100644 3-asynchronous-JS/node_modules/methods/README.md create mode 100644 3-asynchronous-JS/node_modules/methods/index.js create mode 100644 3-asynchronous-JS/node_modules/methods/package.json create mode 100644 3-asynchronous-JS/node_modules/mime-db/HISTORY.md create mode 100644 3-asynchronous-JS/node_modules/mime-db/LICENSE create mode 100644 3-asynchronous-JS/node_modules/mime-db/README.md create mode 100644 3-asynchronous-JS/node_modules/mime-db/db.json create mode 100644 3-asynchronous-JS/node_modules/mime-db/index.js create mode 100644 3-asynchronous-JS/node_modules/mime-db/package.json create mode 100644 3-asynchronous-JS/node_modules/mime-types/HISTORY.md create mode 100644 3-asynchronous-JS/node_modules/mime-types/LICENSE create mode 100644 3-asynchronous-JS/node_modules/mime-types/README.md create mode 100644 3-asynchronous-JS/node_modules/mime-types/index.js create mode 100644 3-asynchronous-JS/node_modules/mime-types/package.json create mode 100644 3-asynchronous-JS/node_modules/mime/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/mime/LICENSE create mode 100644 3-asynchronous-JS/node_modules/mime/Mime.js create mode 100644 3-asynchronous-JS/node_modules/mime/README.md create mode 100644 3-asynchronous-JS/node_modules/mime/cli.js create mode 100644 3-asynchronous-JS/node_modules/mime/index.js create mode 100644 3-asynchronous-JS/node_modules/mime/lite.js create mode 100644 3-asynchronous-JS/node_modules/mime/package.json create mode 100644 3-asynchronous-JS/node_modules/mime/types/other.js create mode 100644 3-asynchronous-JS/node_modules/mime/types/standard.js create mode 100644 3-asynchronous-JS/node_modules/ms/index.js create mode 100644 3-asynchronous-JS/node_modules/ms/license.md create mode 100644 3-asynchronous-JS/node_modules/ms/package.json create mode 100644 3-asynchronous-JS/node_modules/ms/readme.md create mode 100644 3-asynchronous-JS/node_modules/object-inspect/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/object-inspect/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/object-inspect/.nycrc create mode 100644 3-asynchronous-JS/node_modules/object-inspect/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/object-inspect/LICENSE create mode 100644 3-asynchronous-JS/node_modules/object-inspect/example/all.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/example/circular.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/example/fn.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/example/inspect.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/index.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/package-support.json create mode 100644 3-asynchronous-JS/node_modules/object-inspect/package.json create mode 100644 3-asynchronous-JS/node_modules/object-inspect/readme.markdown create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test-core-js.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/bigint.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/browser/dom.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/circular.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/deep.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/element.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/err.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/fakes.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/fn.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/global.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/has.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/holes.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/indent-option.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/inspect.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/lowbyte.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/number.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/quoteStyle.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/toStringTag.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/undef.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/test/values.js create mode 100644 3-asynchronous-JS/node_modules/object-inspect/util.inspect.js create mode 100644 3-asynchronous-JS/node_modules/once/LICENSE create mode 100644 3-asynchronous-JS/node_modules/once/README.md create mode 100644 3-asynchronous-JS/node_modules/once/once.js create mode 100644 3-asynchronous-JS/node_modules/once/package.json create mode 100644 3-asynchronous-JS/node_modules/qs/.editorconfig create mode 100644 3-asynchronous-JS/node_modules/qs/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/qs/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/qs/.nycrc create mode 100644 3-asynchronous-JS/node_modules/qs/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/qs/LICENSE.md create mode 100644 3-asynchronous-JS/node_modules/qs/README.md create mode 100644 3-asynchronous-JS/node_modules/qs/dist/qs.js create mode 100644 3-asynchronous-JS/node_modules/qs/lib/formats.js create mode 100644 3-asynchronous-JS/node_modules/qs/lib/index.js create mode 100644 3-asynchronous-JS/node_modules/qs/lib/parse.js create mode 100644 3-asynchronous-JS/node_modules/qs/lib/stringify.js create mode 100644 3-asynchronous-JS/node_modules/qs/lib/utils.js create mode 100644 3-asynchronous-JS/node_modules/qs/package.json create mode 100644 3-asynchronous-JS/node_modules/qs/test/empty-keys-cases.js create mode 100644 3-asynchronous-JS/node_modules/qs/test/parse.js create mode 100644 3-asynchronous-JS/node_modules/qs/test/stringify.js create mode 100644 3-asynchronous-JS/node_modules/qs/test/utils.js create mode 100644 3-asynchronous-JS/node_modules/side-channel-list/.editorconfig create mode 100644 3-asynchronous-JS/node_modules/side-channel-list/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/side-channel-list/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/side-channel-list/.nycrc create mode 100644 3-asynchronous-JS/node_modules/side-channel-list/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/side-channel-list/LICENSE create mode 100644 3-asynchronous-JS/node_modules/side-channel-list/README.md create mode 100644 3-asynchronous-JS/node_modules/side-channel-list/index.d.ts create mode 100644 3-asynchronous-JS/node_modules/side-channel-list/index.js create mode 100644 3-asynchronous-JS/node_modules/side-channel-list/list.d.ts create mode 100644 3-asynchronous-JS/node_modules/side-channel-list/package.json create mode 100644 3-asynchronous-JS/node_modules/side-channel-list/test/index.js create mode 100644 3-asynchronous-JS/node_modules/side-channel-list/tsconfig.json create mode 100644 3-asynchronous-JS/node_modules/side-channel-map/.editorconfig create mode 100644 3-asynchronous-JS/node_modules/side-channel-map/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/side-channel-map/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/side-channel-map/.nycrc create mode 100644 3-asynchronous-JS/node_modules/side-channel-map/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/side-channel-map/LICENSE create mode 100644 3-asynchronous-JS/node_modules/side-channel-map/README.md create mode 100644 3-asynchronous-JS/node_modules/side-channel-map/index.d.ts create mode 100644 3-asynchronous-JS/node_modules/side-channel-map/index.js create mode 100644 3-asynchronous-JS/node_modules/side-channel-map/package.json create mode 100644 3-asynchronous-JS/node_modules/side-channel-map/test/index.js create mode 100644 3-asynchronous-JS/node_modules/side-channel-map/tsconfig.json create mode 100644 3-asynchronous-JS/node_modules/side-channel-weakmap/.editorconfig create mode 100644 3-asynchronous-JS/node_modules/side-channel-weakmap/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/side-channel-weakmap/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/side-channel-weakmap/.nycrc create mode 100644 3-asynchronous-JS/node_modules/side-channel-weakmap/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/side-channel-weakmap/LICENSE create mode 100644 3-asynchronous-JS/node_modules/side-channel-weakmap/README.md create mode 100644 3-asynchronous-JS/node_modules/side-channel-weakmap/index.d.ts create mode 100644 3-asynchronous-JS/node_modules/side-channel-weakmap/index.js create mode 100644 3-asynchronous-JS/node_modules/side-channel-weakmap/package.json create mode 100644 3-asynchronous-JS/node_modules/side-channel-weakmap/test/index.js create mode 100644 3-asynchronous-JS/node_modules/side-channel-weakmap/tsconfig.json create mode 100644 3-asynchronous-JS/node_modules/side-channel/.editorconfig create mode 100644 3-asynchronous-JS/node_modules/side-channel/.eslintrc create mode 100644 3-asynchronous-JS/node_modules/side-channel/.github/FUNDING.yml create mode 100644 3-asynchronous-JS/node_modules/side-channel/.nycrc create mode 100644 3-asynchronous-JS/node_modules/side-channel/CHANGELOG.md create mode 100644 3-asynchronous-JS/node_modules/side-channel/LICENSE create mode 100644 3-asynchronous-JS/node_modules/side-channel/README.md create mode 100644 3-asynchronous-JS/node_modules/side-channel/index.d.ts create mode 100644 3-asynchronous-JS/node_modules/side-channel/index.js create mode 100644 3-asynchronous-JS/node_modules/side-channel/package.json create mode 100644 3-asynchronous-JS/node_modules/side-channel/test/index.js create mode 100644 3-asynchronous-JS/node_modules/side-channel/tsconfig.json create mode 100644 3-asynchronous-JS/node_modules/superagent/LICENSE create mode 100644 3-asynchronous-JS/node_modules/superagent/README.md create mode 100644 3-asynchronous-JS/node_modules/superagent/dist/superagent.js create mode 100644 3-asynchronous-JS/node_modules/superagent/dist/superagent.min.js create mode 100644 3-asynchronous-JS/node_modules/superagent/lib/agent-base.js create mode 100644 3-asynchronous-JS/node_modules/superagent/lib/client.js create mode 100644 3-asynchronous-JS/node_modules/superagent/lib/node/agent.js create mode 100644 3-asynchronous-JS/node_modules/superagent/lib/node/decompress.js create mode 100644 3-asynchronous-JS/node_modules/superagent/lib/node/http2wrapper.js create mode 100644 3-asynchronous-JS/node_modules/superagent/lib/node/index.js create mode 100644 3-asynchronous-JS/node_modules/superagent/lib/node/parsers/image.js create mode 100644 3-asynchronous-JS/node_modules/superagent/lib/node/parsers/index.js create mode 100644 3-asynchronous-JS/node_modules/superagent/lib/node/parsers/json.js create mode 100644 3-asynchronous-JS/node_modules/superagent/lib/node/parsers/text.js create mode 100644 3-asynchronous-JS/node_modules/superagent/lib/node/parsers/urlencoded.js create mode 100644 3-asynchronous-JS/node_modules/superagent/lib/node/response.js create mode 100644 3-asynchronous-JS/node_modules/superagent/lib/node/unzip.js create mode 100644 3-asynchronous-JS/node_modules/superagent/lib/request-base.js create mode 100644 3-asynchronous-JS/node_modules/superagent/lib/response-base.js create mode 100644 3-asynchronous-JS/node_modules/superagent/lib/utils.js create mode 100644 3-asynchronous-JS/node_modules/superagent/package.json create mode 100644 3-asynchronous-JS/node_modules/wrappy/LICENSE create mode 100644 3-asynchronous-JS/node_modules/wrappy/README.md create mode 100644 3-asynchronous-JS/node_modules/wrappy/package.json create mode 100644 3-asynchronous-JS/node_modules/wrappy/wrappy.js create mode 100644 3-asynchronous-JS/package-lock.json create mode 100644 3-asynchronous-JS/package.json diff --git a/2-how-node-works/starter/.vscode/c_cpp_properties.json b/2-how-node-works/starter/.vscode/c_cpp_properties.json new file mode 100644 index 0000000000..f912847052 --- /dev/null +++ b/2-how-node-works/starter/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "windows-gcc-x86", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "C:/MinGW/bin/gcc.exe", + "cStandard": "${default}", + "cppStandard": "${default}", + "intelliSenseMode": "windows-gcc-x86", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/2-how-node-works/starter/.vscode/launch.json b/2-how-node-works/starter/.vscode/launch.json new file mode 100644 index 0000000000..4ae976db2b --- /dev/null +++ b/2-how-node-works/starter/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C/C++ Runner: Debug Session", + "type": "cppdbg", + "request": "launch", + "args": [], + "stopAtEntry": false, + "externalConsole": true, + "cwd": "c:/Users/Esdeath/Documents/git--Jonas/complete-node-bootcamp/2-how-node-works/starter", + "program": "c:/Users/Esdeath/Documents/git--Jonas/complete-node-bootcamp/2-how-node-works/starter/build/Debug/outDebug", + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/2-how-node-works/starter/.vscode/settings.json b/2-how-node-works/starter/.vscode/settings.json new file mode 100644 index 0000000000..d663149f9c --- /dev/null +++ b/2-how-node-works/starter/.vscode/settings.json @@ -0,0 +1,60 @@ +{ + "C_Cpp_Runner.cCompilerPath": "gcc", + "C_Cpp_Runner.cppCompilerPath": "g++", + "C_Cpp_Runner.debuggerPath": "gdb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "", + "C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvarsall.bat", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wcast-align", + "-Wconversion", + "-Wsign-conversion", + "-Wnull-dereference" + ], + "C_Cpp_Runner.msvcWarnings": [ + "/W4", + "/permissive-", + "/w14242", + "/w14287", + "/w14296", + "/w14311", + "/w14826", + "/w44062", + "/w44242", + "/w14905", + "/w14906", + "/w14263", + "/w44265", + "/w14928" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": ["*", "**/*"], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "C_Cpp_Runner.useUndefinedSanitizer": false, + "C_Cpp_Runner.useLeakSanitizer": false, + "C_Cpp_Runner.showCompilationTime": false, + "C_Cpp_Runner.useLinkTimeOptimization": false, + "C_Cpp_Runner.msvcSecureNoWarnings": false, + "files.associations": { + "*.embeddedhtml": "html", + "SHUBHAM4.C": "cpp" + } +} diff --git a/2-how-node-works/starter/event-loop.js b/2-how-node-works/starter/event-loop.js new file mode 100644 index 0000000000..8bc05c94fd --- /dev/null +++ b/2-how-node-works/starter/event-loop.js @@ -0,0 +1,44 @@ +const EventEmitter = require("events"); +const http = require("http"); +class Sales extends EventEmitter { + constructor() { + super(); + } +} + +const myEmitter = new EventEmitter(); + +myEmitter.on("newSales", () => { + console.log("There as a slae"); +}); + +myEmitter.on("newSales", () => { + console.log("Costumere"); +}); + +myEmitter.on("newSales", (stock) => { + console.log(`There aer now ${stock} items left in stock.`); +}); + +myEmitter.emit("newSales", 9); + +//////////////////// + +const server = http.createServer(); + +server.on("request", (req, res) => { + console.log("Request revievd"); + console.log(req.url); + res.end("Request received"); +}); + +server.on("request", (req, res) => { + console.log("Another requst 😊"); +}); +server.on("close", () => { + console.log("Server closed"); +}); + +server.listen(8000, "127.0.0.1", () => { + console.log("Waiting for requesetes..."); +}); diff --git a/2-how-node-works/starter/event.js b/2-how-node-works/starter/event.js new file mode 100644 index 0000000000..af4a5840e6 --- /dev/null +++ b/2-how-node-works/starter/event.js @@ -0,0 +1,58 @@ +const fs = require("fs"); +const crypto = require("crypto"); + +const start = Date.now(); + +process.env.UV_THREADPOOL_SIZE = 4; + +setTimeout(() => console.log("Timer 1 finished"), 0); +setImmediate(() => console.log("Immediate 1 finished")); + +console.log("Hello from the top-level code"); + +fs.readFile("style.css", () => { + console.log("I/O finished"); + + console.log("--------------------"); + + setTimeout(() => console.log("Timer 2 finished"), 0); + setTimeout(() => console.log("Timer 3 finished"), 3000); + + setImmediate(() => console.log("Immediate 2 finished")); + process.nextTick(() => console.log("Process.nextTick")); + + crypto.pbkdf2Sync("password", "salt", 100000, 1024, "sha512"); + console.log(`${Date.now() - start} - Password encrypted`); + crypto.pbkdf2("password", "salt", 100000, 1024, "sha512", () => { + console.log(`${Date.now() - start} - Password encrypted`); + }); + crypto.pbkdf2("password", "salt", 100000, 1024, "sha512", () => { + console.log(`${Date.now() - start} - Password encrypted`); + }); +}); + ////////////////////////////// + const EventEmitter = require("events"); +const http = require("http"); + +// Custom EventEmitter class +class Sales extends EventEmitter { + constructor() { + super(); + } +} + +const myEmitter = new EventEmitter(); + +myEmitter.on("newSales", () => { + console.log("There was a sale"); +}); + +myEmitter.on("newSales", () => { + console.log("Customer"); +}); + +myEmitter.on("newSales", (stock) => { + console.log(`There are now ${stock} items left in stock.`); +}); + +myEmitter.emit("newSales", 9); diff --git a/2-how-node-works/starter/stream.js b/2-how-node-works/starter/stream.js new file mode 100644 index 0000000000..9e19424302 --- /dev/null +++ b/2-how-node-works/starter/stream.js @@ -0,0 +1,33 @@ +const fs = require("fs"); +const server = require("http").createServer(); + +server.on("request", (req, res) => { + // Solution 1 + // fs.readFile("test-file.txt", (err, data) => { + // if (err) console.log(err); + // res.end(data); + // }); + + // Solution 2 + // const readable = fs.createReadStream("tests-file.txt"); + // readable.on("data", (chunk) => { + // res.write(chunk); + // }); + // readable.on("end", () => { + // res.end(); + // }); + // readable.on("error", (err) => { + // console.log(err); + // res.statusCode = 500; + // res.end("File not found!"); + // }); + + // Solution 3 + const readable = fs.createReadStream("test-file.txt"); + readable.pipe(res); + +}); + +server.listen(8000, "127.0.0.1", () => { + console.log("Listening..."); +}); diff --git a/2-how-node-works/starter/tempCodeRunnerFile.js b/2-how-node-works/starter/tempCodeRunnerFile.js new file mode 100644 index 0000000000..23303c2cd5 --- /dev/null +++ b/2-how-node-works/starter/tempCodeRunnerFile.js @@ -0,0 +1,2 @@ + + }); \ No newline at end of file diff --git a/3-asynchronous-JS/final/dog-img.txt b/3-asynchronous-JS/final/dog-img.txt index b74e95bd6e..6fe4911a40 100644 --- a/3-asynchronous-JS/final/dog-img.txt +++ b/3-asynchronous-JS/final/dog-img.txt @@ -1,3 +1,3 @@ -https://images.dog.ceo/breeds/labrador/n02099712_7411.jpg -https://images.dog.ceo/breeds/labrador/n02099712_6644.jpg -https://images.dog.ceo/breeds/labrador/n02099712_4705.jpg \ No newline at end of file +https://images.dog.ceo/breeds/labrador/n02099712_7605.jpg +https://images.dog.ceo/breeds/labrador/n02099712_7608.jpg +https://images.dog.ceo/breeds/labrador/n02099712_7866.jpg \ No newline at end of file diff --git a/3-asynchronous-JS/index.js b/3-asynchronous-JS/index.js new file mode 100644 index 0000000000..8827d1df1a --- /dev/null +++ b/3-asynchronous-JS/index.js @@ -0,0 +1,17 @@ +const fs = require("fs"); +const superganet = require("superagent"); + +fs.readFile(`${__dirname}/dog.txt`, (err, data) => { + console.log(`Bread: ${data}`); + superganet + .get(`https://dog.ceo/api/breeds${data}/images/random`) + .end((err, res) => { + if (err) return console.log(err.message); + console.log(res.body.message); + + fs.writeFile("dog-image.txt", res.body.message, (err) => { + if (err) return console.log(err.message); + console.log("Random dog image saved to file!"); + }); + }); +}); diff --git a/3-asynchronous-JS/node_modules/.bin/mime b/3-asynchronous-JS/node_modules/.bin/mime new file mode 100644 index 0000000000..7751de3cbb --- /dev/null +++ b/3-asynchronous-JS/node_modules/.bin/mime @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../mime/cli.js" "$@" +else + exec node "$basedir/../mime/cli.js" "$@" +fi diff --git a/3-asynchronous-JS/node_modules/.bin/mime.cmd b/3-asynchronous-JS/node_modules/.bin/mime.cmd new file mode 100644 index 0000000000..54491f12e0 --- /dev/null +++ b/3-asynchronous-JS/node_modules/.bin/mime.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mime\cli.js" %* diff --git a/3-asynchronous-JS/node_modules/.bin/mime.ps1 b/3-asynchronous-JS/node_modules/.bin/mime.ps1 new file mode 100644 index 0000000000..2222f40bcf --- /dev/null +++ b/3-asynchronous-JS/node_modules/.bin/mime.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../mime/cli.js" $args + } else { + & "$basedir/node$exe" "$basedir/../mime/cli.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../mime/cli.js" $args + } else { + & "node$exe" "$basedir/../mime/cli.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/3-asynchronous-JS/node_modules/.package-lock.json b/3-asynchronous-JS/node_modules/.package-lock.json new file mode 100644 index 0000000000..8ca42a4f33 --- /dev/null +++ b/3-asynchronous-JS/node_modules/.package-lock.json @@ -0,0 +1,459 @@ +{ + "name": "3-asynchronous-js", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "license": "ISC", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "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/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.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "license": "MIT" + }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formidable": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.2.tgz", + "integrity": "sha512-Jqc1btCy3QzRbJaICGwKcBfGWuLADRerLzDqi2NwSt/UkXLsHJw2TVResiaoBufHVHy9aSgClOHCeJsSsFLTbg==", + "license": "MIT", + "dependencies": { + "dezalgo": "^1.0.4", + "hexoid": "^2.0.0", + "once": "^1.4.0" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "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.2.6", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz", + "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "function-bind": "^1.1.2", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hexoid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-2.0.0.tgz", + "integrity": "sha512-qlspKUK7IlSQv2o+5I7yhUd7TxlOG2Vr5LTa3ve2XSNVKAL/n/u/7KLvKmFNimomDIKvZFXWHv0T12mv7rT8Aw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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/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": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "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.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/qs": { + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.1.tgz", + "integrity": "sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "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/superagent": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.1.1.tgz", + "integrity": "sha512-9pIwrHrOj3uAnqg9gDlW7EA2xv+N5au/dSM0kM22HTqmUu8jBxNT+8uA7tA3UoCnmiqzpSbu8rasIUZvbyamMQ==", + "license": "MIT", + "dependencies": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.4", + "debug": "^4.3.4", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.0", + "formidable": "^3.5.2", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.11.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + } + } +} diff --git a/3-asynchronous-JS/node_modules/asap/CHANGES.md b/3-asynchronous-JS/node_modules/asap/CHANGES.md new file mode 100644 index 0000000000..f105b91956 --- /dev/null +++ b/3-asynchronous-JS/node_modules/asap/CHANGES.md @@ -0,0 +1,70 @@ + +## 2.0.6 + +Version 2.0.4 adds support for React Native by clarifying in package.json that +the browser environment does not support Node.js domains. +Why this is necessary, we leave as an exercise for the user. + +## 2.0.3 + +Version 2.0.3 fixes a bug when adjusting the capacity of the task queue. + +## 2.0.1-2.02 + +Version 2.0.1 fixes a bug in the way redirects were expressed that affected the +function of Browserify, but which Mr would tolerate. + +## 2.0.0 + +Version 2 of ASAP is a full rewrite with a few salient changes. +First, the ASAP source is CommonJS only and designed with [Browserify][] and +[Browserify-compatible][Mr] module loaders in mind. + +[Browserify]: https://github.com/substack/node-browserify +[Mr]: https://github.com/montagejs/mr + +The new version has been refactored in two dimensions. +Support for Node.js and browsers have been separated, using Browserify +redirects and ASAP has been divided into two modules. +The "raw" layer depends on the tasks to catch thrown exceptions and unravel +Node.js domains. + +The full implementation of ASAP is loadable as `require("asap")` in both Node.js +and browsers. + +The raw layer that lacks exception handling overhead is loadable as +`require("asap/raw")`. +The interface is the same for both layers. + +Tasks are no longer required to be functions, but can rather be any object that +implements `task.call()`. +With this feature you can recycle task objects to avoid garbage collector churn +and avoid closures in general. + +The implementation has been rigorously documented so that our successors can +understand the scope of the problem that this module solves and all of its +nuances, ensuring that the next generation of implementations know what details +are essential. + +- [asap.js](https://github.com/kriskowal/asap/blob/master/asap.js) +- [raw.js](https://github.com/kriskowal/asap/blob/master/raw.js) +- [browser-asap.js](https://github.com/kriskowal/asap/blob/master/browser-asap.js) +- [browser-raw.js](https://github.com/kriskowal/asap/blob/master/browser-raw.js) + +The new version has also been rigorously tested across a broad spectrum of +browsers, in both the window and worker context. +The following charts capture the browser test results for the most recent +release. +The first chart shows test results for ASAP running in the main window context. +The second chart shows test results for ASAP running in a web worker context. +Test results are inconclusive (grey) on browsers that do not support web +workers. +These data are captured automatically by [Continuous +Integration][]. + +![Browser Compatibility](http://kriskowal-asap.s3-website-us-west-2.amazonaws.com/train/integration-2/saucelabs-results-matrix.svg) + +![Compatibility in Web Workers](http://kriskowal-asap.s3-website-us-west-2.amazonaws.com/train/integration-2/saucelabs-worker-results-matrix.svg) + +[Continuous Integration]: https://github.com/kriskowal/asap/blob/master/CONTRIBUTING.md + diff --git a/3-asynchronous-JS/node_modules/asap/LICENSE.md b/3-asynchronous-JS/node_modules/asap/LICENSE.md new file mode 100644 index 0000000000..ba18c61390 --- /dev/null +++ b/3-asynchronous-JS/node_modules/asap/LICENSE.md @@ -0,0 +1,21 @@ + +Copyright 2009–2014 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. + diff --git a/3-asynchronous-JS/node_modules/asap/README.md b/3-asynchronous-JS/node_modules/asap/README.md new file mode 100644 index 0000000000..452fd8c203 --- /dev/null +++ b/3-asynchronous-JS/node_modules/asap/README.md @@ -0,0 +1,237 @@ +# ASAP + +[![Build Status](https://travis-ci.org/kriskowal/asap.png?branch=master)](https://travis-ci.org/kriskowal/asap) + +Promise and asynchronous observer libraries, as well as hand-rolled callback +programs and libraries, often need a mechanism to postpone the execution of a +callback until the next available event. +(See [Designing API’s for Asynchrony][Zalgo].) +The `asap` function executes a task **as soon as possible** but not before it +returns, waiting only for the completion of the current event and previously +scheduled tasks. + +```javascript +asap(function () { + // ... +}); +``` + +[Zalgo]: http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony + +This CommonJS package provides an `asap` module that exports a function that +executes a task function *as soon as possible*. + +ASAP strives to schedule events to occur before yielding for IO, reflow, +or redrawing. +Each event receives an independent stack, with only platform code in parent +frames and the events run in the order they are scheduled. + +ASAP provides a fast event queue that will execute tasks until it is +empty before yielding to the JavaScript engine's underlying event-loop. +When a task gets added to a previously empty event queue, ASAP schedules a flush +event, preferring for that event to occur before the JavaScript engine has an +opportunity to perform IO tasks or rendering, thus making the first task and +subsequent tasks semantically indistinguishable. +ASAP uses a variety of techniques to preserve this invariant on different +versions of browsers and Node.js. + +By design, ASAP prevents input events from being handled until the task +queue is empty. +If the process is busy enough, this may cause incoming connection requests to be +dropped, and may cause existing connections to inform the sender to reduce the +transmission rate or stall. +ASAP allows this on the theory that, if there is enough work to do, there is no +sense in looking for trouble. +As a consequence, ASAP can interfere with smooth animation. +If your task should be tied to the rendering loop, consider using +`requestAnimationFrame` instead. +A long sequence of tasks can also effect the long running script dialog. +If this is a problem, you may be able to use ASAP’s cousin `setImmediate` to +break long processes into shorter intervals and periodically allow the browser +to breathe. +`setImmediate` will yield for IO, reflow, and repaint events. +It also returns a handler and can be canceled. +For a `setImmediate` shim, consider [YuzuJS setImmediate][setImmediate]. + +[setImmediate]: https://github.com/YuzuJS/setImmediate + +Take care. +ASAP can sustain infinite recursive calls without warning. +It will not halt from a stack overflow, and it will not consume unbounded +memory. +This is behaviorally equivalent to an infinite loop. +Just as with infinite loops, you can monitor a Node.js process for this behavior +with a heart-beat signal. +As with infinite loops, a very small amount of caution goes a long way to +avoiding problems. + +```javascript +function loop() { + asap(loop); +} +loop(); +``` + +In browsers, if a task throws an exception, it will not interrupt the flushing +of high-priority tasks. +The exception will be postponed to a later, low-priority event to avoid +slow-downs. +In Node.js, if a task throws an exception, ASAP will resume flushing only if—and +only after—the error is handled by `domain.on("error")` or +`process.on("uncaughtException")`. + +## Raw ASAP + +Checking for exceptions comes at a cost. +The package also provides an `asap/raw` module that exports the underlying +implementation which is faster but stalls if a task throws an exception. +This internal version of the ASAP function does not check for errors. +If a task does throw an error, it will stall the event queue unless you manually +call `rawAsap.requestFlush()` before throwing the error, or any time after. + +In Node.js, `asap/raw` also runs all tasks outside any domain. +If you need a task to be bound to your domain, you will have to do it manually. + +```js +if (process.domain) { + task = process.domain.bind(task); +} +rawAsap(task); +``` + +## Tasks + +A task may be any object that implements `call()`. +A function will suffice, but closures tend not to be reusable and can cause +garbage collector churn. +Both `asap` and `rawAsap` accept task objects to give you the option of +recycling task objects or using higher callable object abstractions. +See the `asap` source for an illustration. + + +## Compatibility + +ASAP is tested on Node.js v0.10 and in a broad spectrum of web browsers. +The following charts capture the browser test results for the most recent +release. +The first chart shows test results for ASAP running in the main window context. +The second chart shows test results for ASAP running in a web worker context. +Test results are inconclusive (grey) on browsers that do not support web +workers. +These data are captured automatically by [Continuous +Integration][]. + +[Continuous Integration]: https://github.com/kriskowal/asap/blob/master/CONTRIBUTING.md + +![Browser Compatibility](http://kriskowal-asap.s3-website-us-west-2.amazonaws.com/train/integration-2/saucelabs-results-matrix.svg) + +![Compatibility in Web Workers](http://kriskowal-asap.s3-website-us-west-2.amazonaws.com/train/integration-2/saucelabs-worker-results-matrix.svg) + +## Caveats + +When a task is added to an empty event queue, it is not always possible to +guarantee that the task queue will begin flushing immediately after the current +event. +However, once the task queue begins flushing, it will not yield until the queue +is empty, even if the queue grows while executing tasks. + +The following browsers allow the use of [DOM mutation observers][] to access +the HTML [microtask queue][], and thus begin flushing ASAP's task queue +immediately at the end of the current event loop turn, before any rendering or +IO: + +[microtask queue]: http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#microtask-queue +[DOM mutation observers]: http://dom.spec.whatwg.org/#mutation-observers + +- Android 4–4.3 +- Chrome 26–34 +- Firefox 14–29 +- Internet Explorer 11 +- iPad Safari 6–7.1 +- iPhone Safari 7–7.1 +- Safari 6–7 + +In the absense of mutation observers, there are a few browsers, and situations +like web workers in some of the above browsers, where [message channels][] +would be a useful way to avoid falling back to timers. +Message channels give direct access to the HTML [task queue][], so the ASAP +task queue would flush after any already queued rendering and IO tasks, but +without having the minimum delay imposed by timers. +However, among these browsers, Internet Explorer 10 and Safari do not reliably +dispatch messages, so they are not worth the trouble to implement. + +[message channels]: http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html#message-channels +[task queue]: http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#concept-task + +- Internet Explorer 10 +- Safair 5.0-1 +- Opera 11-12 + +In the absense of mutation observers, these browsers and the following browsers +all fall back to using `setTimeout` and `setInterval` to ensure that a `flush` +occurs. +The implementation uses both and cancels whatever handler loses the race, since +`setTimeout` tends to occasionally skip tasks in unisolated circumstances. +Timers generally delay the flushing of ASAP's task queue for four milliseconds. + +- Firefox 3–13 +- Internet Explorer 6–10 +- iPad Safari 4.3 +- Lynx 2.8.7 + + +## Heritage + +ASAP has been factored out of the [Q][] asynchronous promise library. +It originally had a naïve implementation in terms of `setTimeout`, but +[Malte Ubl][NonBlocking] provided an insight that `postMessage` might be +useful for creating a high-priority, no-delay event dispatch hack. +Since then, Internet Explorer proposed and implemented `setImmediate`. +Robert Katić began contributing to Q by measuring the performance of +the internal implementation of `asap`, paying particular attention to +error recovery. +Domenic, Robert, and Kris Kowal collectively settled on the current strategy of +unrolling the high-priority event queue internally regardless of what strategy +we used to dispatch the potentially lower-priority flush event. +Domenic went on to make ASAP cooperate with Node.js domains. + +[Q]: https://github.com/kriskowal/q +[NonBlocking]: http://www.nonblocking.io/2011/06/windownexttick.html + +For further reading, Nicholas Zakas provided a thorough article on [The +Case for setImmediate][NCZ]. + +[NCZ]: http://www.nczonline.net/blog/2013/07/09/the-case-for-setimmediate/ + +Ember’s RSVP promise implementation later [adopted][RSVP ASAP] the name ASAP but +further developed the implentation. +Particularly, The `MessagePort` implementation was abandoned due to interaction +[problems with Mobile Internet Explorer][IE Problems] in favor of an +implementation backed on the newer and more reliable DOM `MutationObserver` +interface. +These changes were back-ported into this library. + +[IE Problems]: https://github.com/cujojs/when/issues/197 +[RSVP ASAP]: https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js + +In addition, ASAP factored into `asap` and `asap/raw`, such that `asap` remained +exception-safe, but `asap/raw` provided a tight kernel that could be used for +tasks that guaranteed that they would not throw exceptions. +This core is useful for promise implementations that capture thrown errors in +rejected promises and do not need a second safety net. +At the same time, the exception handling in `asap` was factored into separate +implementations for Node.js and browsers, using the the [Browserify][Browser +Config] `browser` property in `package.json` to instruct browser module loaders +and bundlers, including [Browserify][], [Mr][], and [Mop][], to use the +browser-only implementation. + +[Browser Config]: https://gist.github.com/defunctzombie/4339901 +[Browserify]: https://github.com/substack/node-browserify +[Mr]: https://github.com/montagejs/mr +[Mop]: https://github.com/montagejs/mop + +## License + +Copyright 2009-2014 by Contributors +MIT License (enclosed) + diff --git a/3-asynchronous-JS/node_modules/asap/asap.js b/3-asynchronous-JS/node_modules/asap/asap.js new file mode 100644 index 0000000000..f04fcd58fc --- /dev/null +++ b/3-asynchronous-JS/node_modules/asap/asap.js @@ -0,0 +1,65 @@ +"use strict"; + +var rawAsap = require("./raw"); +var freeTasks = []; + +/** + * Calls a task as soon as possible after returning, in its own event, with + * priority over IO events. An exception thrown in a task can be handled by + * `process.on("uncaughtException") or `domain.on("error")`, but will otherwise + * crash the process. If the error is handled, all subsequent tasks will + * resume. + * + * @param {{call}} task A callable object, typically a function that takes no + * arguments. + */ +module.exports = asap; +function asap(task) { + var rawTask; + if (freeTasks.length) { + rawTask = freeTasks.pop(); + } else { + rawTask = new RawTask(); + } + rawTask.task = task; + rawTask.domain = process.domain; + rawAsap(rawTask); +} + +function RawTask() { + this.task = null; + this.domain = null; +} + +RawTask.prototype.call = function () { + if (this.domain) { + this.domain.enter(); + } + var threw = true; + try { + this.task.call(); + threw = false; + // If the task throws an exception (presumably) Node.js restores the + // domain stack for the next event. + if (this.domain) { + this.domain.exit(); + } + } finally { + // We use try/finally and a threw flag to avoid messing up stack traces + // when we catch and release errors. + if (threw) { + // In Node.js, uncaught exceptions are considered fatal errors. + // Re-throw them to interrupt flushing! + // Ensure that flushing continues if an uncaught exception is + // suppressed listening process.on("uncaughtException") or + // domain.on("error"). + rawAsap.requestFlush(); + } + // If the task threw an error, we do not want to exit the domain here. + // Exiting the domain would prevent the domain from catching the error. + this.task = null; + this.domain = null; + freeTasks.push(this); + } +}; + diff --git a/3-asynchronous-JS/node_modules/asap/browser-asap.js b/3-asynchronous-JS/node_modules/asap/browser-asap.js new file mode 100644 index 0000000000..805c982460 --- /dev/null +++ b/3-asynchronous-JS/node_modules/asap/browser-asap.js @@ -0,0 +1,66 @@ +"use strict"; + +// rawAsap provides everything we need except exception management. +var rawAsap = require("./raw"); +// RawTasks are recycled to reduce GC churn. +var freeTasks = []; +// We queue errors to ensure they are thrown in right order (FIFO). +// Array-as-queue is good enough here, since we are just dealing with exceptions. +var pendingErrors = []; +var requestErrorThrow = rawAsap.makeRequestCallFromTimer(throwFirstError); + +function throwFirstError() { + if (pendingErrors.length) { + throw pendingErrors.shift(); + } +} + +/** + * Calls a task as soon as possible after returning, in its own event, with priority + * over other events like animation, reflow, and repaint. An error thrown from an + * event will not interrupt, nor even substantially slow down the processing of + * other events, but will be rather postponed to a lower priority event. + * @param {{call}} task A callable object, typically a function that takes no + * arguments. + */ +module.exports = asap; +function asap(task) { + var rawTask; + if (freeTasks.length) { + rawTask = freeTasks.pop(); + } else { + rawTask = new RawTask(); + } + rawTask.task = task; + rawAsap(rawTask); +} + +// We wrap tasks with recyclable task objects. A task object implements +// `call`, just like a function. +function RawTask() { + this.task = null; +} + +// The sole purpose of wrapping the task is to catch the exception and recycle +// the task object after its single use. +RawTask.prototype.call = function () { + try { + this.task.call(); + } catch (error) { + if (asap.onerror) { + // This hook exists purely for testing purposes. + // Its name will be periodically randomized to break any code that + // depends on its existence. + asap.onerror(error); + } else { + // In a web browser, exceptions are not fatal. However, to avoid + // slowing down the queue of pending tasks, we rethrow the error in a + // lower priority turn. + pendingErrors.push(error); + requestErrorThrow(); + } + } finally { + this.task = null; + freeTasks[freeTasks.length] = this; + } +}; diff --git a/3-asynchronous-JS/node_modules/asap/browser-raw.js b/3-asynchronous-JS/node_modules/asap/browser-raw.js new file mode 100644 index 0000000000..9cee7e32eb --- /dev/null +++ b/3-asynchronous-JS/node_modules/asap/browser-raw.js @@ -0,0 +1,223 @@ +"use strict"; + +// Use the fastest means possible to execute a task in its own turn, with +// priority over other events including IO, animation, reflow, and redraw +// events in browsers. +// +// An exception thrown by a task will permanently interrupt the processing of +// subsequent tasks. The higher level `asap` function ensures that if an +// exception is thrown by a task, that the task queue will continue flushing as +// soon as possible, but if you use `rawAsap` directly, you are responsible to +// either ensure that no exceptions are thrown from your task, or to manually +// call `rawAsap.requestFlush` if an exception is thrown. +module.exports = rawAsap; +function rawAsap(task) { + if (!queue.length) { + requestFlush(); + flushing = true; + } + // Equivalent to push, but avoids a function call. + queue[queue.length] = task; +} + +var queue = []; +// Once a flush has been requested, no further calls to `requestFlush` are +// necessary until the next `flush` completes. +var flushing = false; +// `requestFlush` is an implementation-specific method that attempts to kick +// off a `flush` event as quickly as possible. `flush` will attempt to exhaust +// the event queue before yielding to the browser's own event loop. +var requestFlush; +// The position of the next task to execute in the task queue. This is +// preserved between calls to `flush` so that it can be resumed if +// a task throws an exception. +var index = 0; +// If a task schedules additional tasks recursively, the task queue can grow +// unbounded. To prevent memory exhaustion, the task queue will periodically +// truncate already-completed tasks. +var capacity = 1024; + +// The flush function processes all tasks that have been scheduled with +// `rawAsap` unless and until one of those tasks throws an exception. +// If a task throws an exception, `flush` ensures that its state will remain +// consistent and will resume where it left off when called again. +// However, `flush` does not make any arrangements to be called again if an +// exception is thrown. +function flush() { + while (index < queue.length) { + var currentIndex = index; + // Advance the index before calling the task. This ensures that we will + // begin flushing on the next task the task throws an error. + index = index + 1; + queue[currentIndex].call(); + // Prevent leaking memory for long chains of recursive calls to `asap`. + // If we call `asap` within tasks scheduled by `asap`, the queue will + // grow, but to avoid an O(n) walk for every task we execute, we don't + // shift tasks off the queue after they have been executed. + // Instead, we periodically shift 1024 tasks off the queue. + if (index > capacity) { + // Manually shift all values starting at the index back to the + // beginning of the queue. + for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) { + queue[scan] = queue[scan + index]; + } + queue.length -= index; + index = 0; + } + } + queue.length = 0; + index = 0; + flushing = false; +} + +// `requestFlush` is implemented using a strategy based on data collected from +// every available SauceLabs Selenium web driver worker at time of writing. +// https://docs.google.com/spreadsheets/d/1mG-5UYGup5qxGdEMWkhP6BWCz053NUb2E1QoUTU16uA/edit#gid=783724593 + +// Safari 6 and 6.1 for desktop, iPad, and iPhone are the only browsers that +// have WebKitMutationObserver but not un-prefixed MutationObserver. +// Must use `global` or `self` instead of `window` to work in both frames and web +// workers. `global` is a provision of Browserify, Mr, Mrs, or Mop. + +/* globals self */ +var scope = typeof global !== "undefined" ? global : self; +var BrowserMutationObserver = scope.MutationObserver || scope.WebKitMutationObserver; + +// MutationObservers are desirable because they have high priority and work +// reliably everywhere they are implemented. +// They are implemented in all modern browsers. +// +// - Android 4-4.3 +// - Chrome 26-34 +// - Firefox 14-29 +// - Internet Explorer 11 +// - iPad Safari 6-7.1 +// - iPhone Safari 7-7.1 +// - Safari 6-7 +if (typeof BrowserMutationObserver === "function") { + requestFlush = makeRequestCallFromMutationObserver(flush); + +// MessageChannels are desirable because they give direct access to the HTML +// task queue, are implemented in Internet Explorer 10, Safari 5.0-1, and Opera +// 11-12, and in web workers in many engines. +// Although message channels yield to any queued rendering and IO tasks, they +// would be better than imposing the 4ms delay of timers. +// However, they do not work reliably in Internet Explorer or Safari. + +// Internet Explorer 10 is the only browser that has setImmediate but does +// not have MutationObservers. +// Although setImmediate yields to the browser's renderer, it would be +// preferrable to falling back to setTimeout since it does not have +// the minimum 4ms penalty. +// Unfortunately there appears to be a bug in Internet Explorer 10 Mobile (and +// Desktop to a lesser extent) that renders both setImmediate and +// MessageChannel useless for the purposes of ASAP. +// https://github.com/kriskowal/q/issues/396 + +// Timers are implemented universally. +// We fall back to timers in workers in most engines, and in foreground +// contexts in the following browsers. +// However, note that even this simple case requires nuances to operate in a +// broad spectrum of browsers. +// +// - Firefox 3-13 +// - Internet Explorer 6-9 +// - iPad Safari 4.3 +// - Lynx 2.8.7 +} else { + requestFlush = makeRequestCallFromTimer(flush); +} + +// `requestFlush` requests that the high priority event queue be flushed as +// soon as possible. +// This is useful to prevent an error thrown in a task from stalling the event +// queue if the exception handled by Node.js’s +// `process.on("uncaughtException")` or by a domain. +rawAsap.requestFlush = requestFlush; + +// To request a high priority event, we induce a mutation observer by toggling +// the text of a text node between "1" and "-1". +function makeRequestCallFromMutationObserver(callback) { + var toggle = 1; + var observer = new BrowserMutationObserver(callback); + var node = document.createTextNode(""); + observer.observe(node, {characterData: true}); + return function requestCall() { + toggle = -toggle; + node.data = toggle; + }; +} + +// The message channel technique was discovered by Malte Ubl and was the +// original foundation for this library. +// http://www.nonblocking.io/2011/06/windownexttick.html + +// Safari 6.0.5 (at least) intermittently fails to create message ports on a +// page's first load. Thankfully, this version of Safari supports +// MutationObservers, so we don't need to fall back in that case. + +// function makeRequestCallFromMessageChannel(callback) { +// var channel = new MessageChannel(); +// channel.port1.onmessage = callback; +// return function requestCall() { +// channel.port2.postMessage(0); +// }; +// } + +// For reasons explained above, we are also unable to use `setImmediate` +// under any circumstances. +// Even if we were, there is another bug in Internet Explorer 10. +// It is not sufficient to assign `setImmediate` to `requestFlush` because +// `setImmediate` must be called *by name* and therefore must be wrapped in a +// closure. +// Never forget. + +// function makeRequestCallFromSetImmediate(callback) { +// return function requestCall() { +// setImmediate(callback); +// }; +// } + +// Safari 6.0 has a problem where timers will get lost while the user is +// scrolling. This problem does not impact ASAP because Safari 6.0 supports +// mutation observers, so that implementation is used instead. +// However, if we ever elect to use timers in Safari, the prevalent work-around +// is to add a scroll event listener that calls for a flush. + +// `setTimeout` does not call the passed callback if the delay is less than +// approximately 7 in web workers in Firefox 8 through 18, and sometimes not +// even then. + +function makeRequestCallFromTimer(callback) { + return function requestCall() { + // We dispatch a timeout with a specified delay of 0 for engines that + // can reliably accommodate that request. This will usually be snapped + // to a 4 milisecond delay, but once we're flushing, there's no delay + // between events. + var timeoutHandle = setTimeout(handleTimer, 0); + // However, since this timer gets frequently dropped in Firefox + // workers, we enlist an interval handle that will try to fire + // an event 20 times per second until it succeeds. + var intervalHandle = setInterval(handleTimer, 50); + + function handleTimer() { + // Whichever timer succeeds will cancel both timers and + // execute the callback. + clearTimeout(timeoutHandle); + clearInterval(intervalHandle); + callback(); + } + }; +} + +// This is for `asap.js` only. +// Its name will be periodically randomized to break any code that depends on +// its existence. +rawAsap.makeRequestCallFromTimer = makeRequestCallFromTimer; + +// ASAP was originally a nextTick shim included in Q. This was factored out +// into this ASAP package. It was later adapted to RSVP which made further +// amendments. These decisions, particularly to marginalize MessageChannel and +// to capture the MutationObserver implementation in a closure, were integrated +// back into ASAP proper. +// https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js diff --git a/3-asynchronous-JS/node_modules/asap/package.json b/3-asynchronous-JS/node_modules/asap/package.json new file mode 100644 index 0000000000..ae9f303bcd --- /dev/null +++ b/3-asynchronous-JS/node_modules/asap/package.json @@ -0,0 +1,58 @@ +{ + "name": "asap", + "version": "2.0.6", + "description": "High-priority task queue for Node.js and browsers", + "keywords": [ + "event", + "task", + "queue" + ], + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/kriskowal/asap.git" + }, + "main": "./asap.js", + "browser": { + "./asap": "./browser-asap.js", + "./asap.js": "./browser-asap.js", + "./raw": "./browser-raw.js", + "./raw.js": "./browser-raw.js", + "./test/domain.js": "./test/browser-domain.js" + }, + "react-native": { + "domain": false + }, + "files": [ + "raw.js", + "asap.js", + "browser-raw.js", + "browser-asap.js" + ], + "scripts": { + "test": "npm run lint && npm run test-node", + "test-travis": "npm run lint && npm run test-node && npm run test-saucelabs && npm run test-saucelabs-worker", + "test-node": "node test/asap-test.js", + "test-publish": "node scripts/publish-bundle.js test/asap-test.js | pbcopy", + "test-browser": "node scripts/publish-bundle.js test/asap-test.js | xargs opener", + "test-saucelabs": "node scripts/saucelabs.js test/asap-test.js scripts/saucelabs-spot-configurations.json", + "test-saucelabs-all": "node scripts/saucelabs.js test/asap-test.js scripts/saucelabs-all-configurations.json", + "test-saucelabs-worker": "node scripts/saucelabs-worker-test.js scripts/saucelabs-spot-configurations.json", + "test-saucelabs-worker-all": "node scripts/saucelabs-worker-test.js scripts/saucelabs-all-configurations.json", + "lint": "jshint raw.js asap.js browser-raw.js browser-asap.js $(find scripts -name '*.js' | grep -v gauntlet)", + "benchmarks": "node benchmarks" + }, + "devDependencies": { + "events": "^1.0.1", + "jshint": "^2.5.1", + "knox": "^0.8.10", + "mr": "^2.0.5", + "opener": "^1.3.0", + "q": "^2.0.3", + "q-io": "^2.0.3", + "saucelabs": "^0.1.1", + "wd": "^0.2.21", + "weak-map": "^1.0.5", + "benchmark": "^1.0.0" + } +} diff --git a/3-asynchronous-JS/node_modules/asap/raw.js b/3-asynchronous-JS/node_modules/asap/raw.js new file mode 100644 index 0000000000..ae3b892316 --- /dev/null +++ b/3-asynchronous-JS/node_modules/asap/raw.js @@ -0,0 +1,101 @@ +"use strict"; + +var domain; // The domain module is executed on demand +var hasSetImmediate = typeof setImmediate === "function"; + +// Use the fastest means possible to execute a task in its own turn, with +// priority over other events including network IO events in Node.js. +// +// An exception thrown by a task will permanently interrupt the processing of +// subsequent tasks. The higher level `asap` function ensures that if an +// exception is thrown by a task, that the task queue will continue flushing as +// soon as possible, but if you use `rawAsap` directly, you are responsible to +// either ensure that no exceptions are thrown from your task, or to manually +// call `rawAsap.requestFlush` if an exception is thrown. +module.exports = rawAsap; +function rawAsap(task) { + if (!queue.length) { + requestFlush(); + flushing = true; + } + // Avoids a function call + queue[queue.length] = task; +} + +var queue = []; +// Once a flush has been requested, no further calls to `requestFlush` are +// necessary until the next `flush` completes. +var flushing = false; +// The position of the next task to execute in the task queue. This is +// preserved between calls to `flush` so that it can be resumed if +// a task throws an exception. +var index = 0; +// If a task schedules additional tasks recursively, the task queue can grow +// unbounded. To prevent memory excaustion, the task queue will periodically +// truncate already-completed tasks. +var capacity = 1024; + +// The flush function processes all tasks that have been scheduled with +// `rawAsap` unless and until one of those tasks throws an exception. +// If a task throws an exception, `flush` ensures that its state will remain +// consistent and will resume where it left off when called again. +// However, `flush` does not make any arrangements to be called again if an +// exception is thrown. +function flush() { + while (index < queue.length) { + var currentIndex = index; + // Advance the index before calling the task. This ensures that we will + // begin flushing on the next task the task throws an error. + index = index + 1; + queue[currentIndex].call(); + // Prevent leaking memory for long chains of recursive calls to `asap`. + // If we call `asap` within tasks scheduled by `asap`, the queue will + // grow, but to avoid an O(n) walk for every task we execute, we don't + // shift tasks off the queue after they have been executed. + // Instead, we periodically shift 1024 tasks off the queue. + if (index > capacity) { + // Manually shift all values starting at the index back to the + // beginning of the queue. + for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) { + queue[scan] = queue[scan + index]; + } + queue.length -= index; + index = 0; + } + } + queue.length = 0; + index = 0; + flushing = false; +} + +rawAsap.requestFlush = requestFlush; +function requestFlush() { + // Ensure flushing is not bound to any domain. + // It is not sufficient to exit the domain, because domains exist on a stack. + // To execute code outside of any domain, the following dance is necessary. + var parentDomain = process.domain; + if (parentDomain) { + if (!domain) { + // Lazy execute the domain module. + // Only employed if the user elects to use domains. + domain = require("domain"); + } + domain.active = process.domain = null; + } + + // `setImmediate` is slower that `process.nextTick`, but `process.nextTick` + // cannot handle recursion. + // `requestFlush` will only be called recursively from `asap.js`, to resume + // flushing after an error is thrown into a domain. + // Conveniently, `setImmediate` was introduced in the same version + // `process.nextTick` started throwing recursion errors. + if (flushing && hasSetImmediate) { + setImmediate(flush); + } else { + process.nextTick(flush); + } + + if (parentDomain) { + domain.active = process.domain = parentDomain; + } +} diff --git a/3-asynchronous-JS/node_modules/asynckit/LICENSE b/3-asynchronous-JS/node_modules/asynckit/LICENSE new file mode 100644 index 0000000000..c9eca5dd99 --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Alex Indigo + +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/3-asynchronous-JS/node_modules/asynckit/README.md b/3-asynchronous-JS/node_modules/asynckit/README.md new file mode 100644 index 0000000000..ddcc7e6b95 --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/README.md @@ -0,0 +1,233 @@ +# asynckit [![NPM Module](https://img.shields.io/npm/v/asynckit.svg?style=flat)](https://www.npmjs.com/package/asynckit) + +Minimal async jobs utility library, with streams support. + +[![PhantomJS Build](https://img.shields.io/travis/alexindigo/asynckit/v0.4.0.svg?label=browser&style=flat)](https://travis-ci.org/alexindigo/asynckit) +[![Linux Build](https://img.shields.io/travis/alexindigo/asynckit/v0.4.0.svg?label=linux:0.12-6.x&style=flat)](https://travis-ci.org/alexindigo/asynckit) +[![Windows Build](https://img.shields.io/appveyor/ci/alexindigo/asynckit/v0.4.0.svg?label=windows:0.12-6.x&style=flat)](https://ci.appveyor.com/project/alexindigo/asynckit) + +[![Coverage Status](https://img.shields.io/coveralls/alexindigo/asynckit/v0.4.0.svg?label=code+coverage&style=flat)](https://coveralls.io/github/alexindigo/asynckit?branch=master) +[![Dependency Status](https://img.shields.io/david/alexindigo/asynckit/v0.4.0.svg?style=flat)](https://david-dm.org/alexindigo/asynckit) +[![bitHound Overall Score](https://www.bithound.io/github/alexindigo/asynckit/badges/score.svg)](https://www.bithound.io/github/alexindigo/asynckit) + + + +AsyncKit provides harness for `parallel` and `serial` iterators over list of items represented by arrays or objects. +Optionally it accepts abort function (should be synchronously return by iterator for each item), and terminates left over jobs upon an error event. For specific iteration order built-in (`ascending` and `descending`) and custom sort helpers also supported, via `asynckit.serialOrdered` method. + +It ensures async operations to keep behavior more stable and prevent `Maximum call stack size exceeded` errors, from sync iterators. + +| compression | size | +| :----------------- | -------: | +| asynckit.js | 12.34 kB | +| asynckit.min.js | 4.11 kB | +| asynckit.min.js.gz | 1.47 kB | + + +## Install + +```sh +$ npm install --save asynckit +``` + +## Examples + +### Parallel Jobs + +Runs iterator over provided array in parallel. Stores output in the `result` array, +on the matching positions. In unlikely event of an error from one of the jobs, +will terminate rest of the active jobs (if abort function is provided) +and return error along with salvaged data to the main callback function. + +#### Input Array + +```javascript +var parallel = require('asynckit').parallel + , assert = require('assert') + ; + +var source = [ 1, 1, 4, 16, 64, 32, 8, 2 ] + , expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ] + , expectedTarget = [ 1, 1, 2, 4, 8, 16, 32, 64 ] + , target = [] + ; + +parallel(source, asyncJob, function(err, result) +{ + assert.deepEqual(result, expectedResult); + assert.deepEqual(target, expectedTarget); +}); + +// async job accepts one element from the array +// and a callback function +function asyncJob(item, cb) +{ + // different delays (in ms) per item + var delay = item * 25; + + // pretend different jobs take different time to finish + // and not in consequential order + var timeoutId = setTimeout(function() { + target.push(item); + cb(null, item * 2); + }, delay); + + // allow to cancel "leftover" jobs upon error + // return function, invoking of which will abort this job + return clearTimeout.bind(null, timeoutId); +} +``` + +More examples could be found in [test/test-parallel-array.js](test/test-parallel-array.js). + +#### Input Object + +Also it supports named jobs, listed via object. + +```javascript +var parallel = require('asynckit/parallel') + , assert = require('assert') + ; + +var source = { first: 1, one: 1, four: 4, sixteen: 16, sixtyFour: 64, thirtyTwo: 32, eight: 8, two: 2 } + , expectedResult = { first: 2, one: 2, four: 8, sixteen: 32, sixtyFour: 128, thirtyTwo: 64, eight: 16, two: 4 } + , expectedTarget = [ 1, 1, 2, 4, 8, 16, 32, 64 ] + , expectedKeys = [ 'first', 'one', 'two', 'four', 'eight', 'sixteen', 'thirtyTwo', 'sixtyFour' ] + , target = [] + , keys = [] + ; + +parallel(source, asyncJob, function(err, result) +{ + assert.deepEqual(result, expectedResult); + assert.deepEqual(target, expectedTarget); + assert.deepEqual(keys, expectedKeys); +}); + +// supports full value, key, callback (shortcut) interface +function asyncJob(item, key, cb) +{ + // different delays (in ms) per item + var delay = item * 25; + + // pretend different jobs take different time to finish + // and not in consequential order + var timeoutId = setTimeout(function() { + keys.push(key); + target.push(item); + cb(null, item * 2); + }, delay); + + // allow to cancel "leftover" jobs upon error + // return function, invoking of which will abort this job + return clearTimeout.bind(null, timeoutId); +} +``` + +More examples could be found in [test/test-parallel-object.js](test/test-parallel-object.js). + +### Serial Jobs + +Runs iterator over provided array sequentially. Stores output in the `result` array, +on the matching positions. In unlikely event of an error from one of the jobs, +will not proceed to the rest of the items in the list +and return error along with salvaged data to the main callback function. + +#### Input Array + +```javascript +var serial = require('asynckit/serial') + , assert = require('assert') + ; + +var source = [ 1, 1, 4, 16, 64, 32, 8, 2 ] + , expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ] + , expectedTarget = [ 0, 1, 2, 3, 4, 5, 6, 7 ] + , target = [] + ; + +serial(source, asyncJob, function(err, result) +{ + assert.deepEqual(result, expectedResult); + assert.deepEqual(target, expectedTarget); +}); + +// extended interface (item, key, callback) +// also supported for arrays +function asyncJob(item, key, cb) +{ + target.push(key); + + // it will be automatically made async + // even it iterator "returns" in the same event loop + cb(null, item * 2); +} +``` + +More examples could be found in [test/test-serial-array.js](test/test-serial-array.js). + +#### Input Object + +Also it supports named jobs, listed via object. + +```javascript +var serial = require('asynckit').serial + , assert = require('assert') + ; + +var source = [ 1, 1, 4, 16, 64, 32, 8, 2 ] + , expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ] + , expectedTarget = [ 0, 1, 2, 3, 4, 5, 6, 7 ] + , target = [] + ; + +var source = { first: 1, one: 1, four: 4, sixteen: 16, sixtyFour: 64, thirtyTwo: 32, eight: 8, two: 2 } + , expectedResult = { first: 2, one: 2, four: 8, sixteen: 32, sixtyFour: 128, thirtyTwo: 64, eight: 16, two: 4 } + , expectedTarget = [ 1, 1, 4, 16, 64, 32, 8, 2 ] + , target = [] + ; + + +serial(source, asyncJob, function(err, result) +{ + assert.deepEqual(result, expectedResult); + assert.deepEqual(target, expectedTarget); +}); + +// shortcut interface (item, callback) +// works for object as well as for the arrays +function asyncJob(item, cb) +{ + target.push(item); + + // it will be automatically made async + // even it iterator "returns" in the same event loop + cb(null, item * 2); +} +``` + +More examples could be found in [test/test-serial-object.js](test/test-serial-object.js). + +_Note: Since _object_ is an _unordered_ collection of properties, +it may produce unexpected results with sequential iterations. +Whenever order of the jobs' execution is important please use `serialOrdered` method._ + +### Ordered Serial Iterations + +TBD + +For example [compare-property](compare-property) package. + +### Streaming interface + +TBD + +## Want to Know More? + +More examples can be found in [test folder](test/). + +Or open an [issue](https://github.com/alexindigo/asynckit/issues) with questions and/or suggestions. + +## License + +AsyncKit is licensed under the MIT license. diff --git a/3-asynchronous-JS/node_modules/asynckit/bench.js b/3-asynchronous-JS/node_modules/asynckit/bench.js new file mode 100644 index 0000000000..c612f1a55f --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/bench.js @@ -0,0 +1,76 @@ +/* eslint no-console: "off" */ + +var asynckit = require('./') + , async = require('async') + , assert = require('assert') + , expected = 0 + ; + +var Benchmark = require('benchmark'); +var suite = new Benchmark.Suite; + +var source = []; +for (var z = 1; z < 100; z++) +{ + source.push(z); + expected += z; +} + +suite +// add tests + +.add('async.map', function(deferred) +{ + var total = 0; + + async.map(source, + function(i, cb) + { + setImmediate(function() + { + total += i; + cb(null, total); + }); + }, + function(err, result) + { + assert.ifError(err); + assert.equal(result[result.length - 1], expected); + deferred.resolve(); + }); +}, {'defer': true}) + + +.add('asynckit.parallel', function(deferred) +{ + var total = 0; + + asynckit.parallel(source, + function(i, cb) + { + setImmediate(function() + { + total += i; + cb(null, total); + }); + }, + function(err, result) + { + assert.ifError(err); + assert.equal(result[result.length - 1], expected); + deferred.resolve(); + }); +}, {'defer': true}) + + +// add listeners +.on('cycle', function(ev) +{ + console.log(String(ev.target)); +}) +.on('complete', function() +{ + console.log('Fastest is ' + this.filter('fastest').map('name')); +}) +// run async +.run({ 'async': true }); diff --git a/3-asynchronous-JS/node_modules/asynckit/index.js b/3-asynchronous-JS/node_modules/asynckit/index.js new file mode 100644 index 0000000000..455f9454ee --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/index.js @@ -0,0 +1,6 @@ +module.exports = +{ + parallel : require('./parallel.js'), + serial : require('./serial.js'), + serialOrdered : require('./serialOrdered.js') +}; diff --git a/3-asynchronous-JS/node_modules/asynckit/lib/abort.js b/3-asynchronous-JS/node_modules/asynckit/lib/abort.js new file mode 100644 index 0000000000..114367e5fb --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/lib/abort.js @@ -0,0 +1,29 @@ +// API +module.exports = abort; + +/** + * Aborts leftover active jobs + * + * @param {object} state - current state object + */ +function abort(state) +{ + Object.keys(state.jobs).forEach(clean.bind(state)); + + // reset leftover jobs + state.jobs = {}; +} + +/** + * Cleans up leftover job by invoking abort function for the provided job id + * + * @this state + * @param {string|number} key - job id to abort + */ +function clean(key) +{ + if (typeof this.jobs[key] == 'function') + { + this.jobs[key](); + } +} diff --git a/3-asynchronous-JS/node_modules/asynckit/lib/async.js b/3-asynchronous-JS/node_modules/asynckit/lib/async.js new file mode 100644 index 0000000000..7f1288a4ce --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/lib/async.js @@ -0,0 +1,34 @@ +var defer = require('./defer.js'); + +// API +module.exports = async; + +/** + * Runs provided callback asynchronously + * even if callback itself is not + * + * @param {function} callback - callback to invoke + * @returns {function} - augmented callback + */ +function async(callback) +{ + var isAsync = false; + + // check if async happened + defer(function() { isAsync = true; }); + + return function async_callback(err, result) + { + if (isAsync) + { + callback(err, result); + } + else + { + defer(function nextTick_callback() + { + callback(err, result); + }); + } + }; +} diff --git a/3-asynchronous-JS/node_modules/asynckit/lib/defer.js b/3-asynchronous-JS/node_modules/asynckit/lib/defer.js new file mode 100644 index 0000000000..b67110c7ad --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/lib/defer.js @@ -0,0 +1,26 @@ +module.exports = defer; + +/** + * Runs provided function on next iteration of the event loop + * + * @param {function} fn - function to run + */ +function defer(fn) +{ + var nextTick = typeof setImmediate == 'function' + ? setImmediate + : ( + typeof process == 'object' && typeof process.nextTick == 'function' + ? process.nextTick + : null + ); + + if (nextTick) + { + nextTick(fn); + } + else + { + setTimeout(fn, 0); + } +} diff --git a/3-asynchronous-JS/node_modules/asynckit/lib/iterate.js b/3-asynchronous-JS/node_modules/asynckit/lib/iterate.js new file mode 100644 index 0000000000..5d2839a590 --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/lib/iterate.js @@ -0,0 +1,75 @@ +var async = require('./async.js') + , abort = require('./abort.js') + ; + +// API +module.exports = iterate; + +/** + * Iterates over each job object + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {object} state - current job status + * @param {function} callback - invoked when all elements processed + */ +function iterate(list, iterator, state, callback) +{ + // store current index + var key = state['keyedList'] ? state['keyedList'][state.index] : state.index; + + state.jobs[key] = runJob(iterator, key, list[key], function(error, output) + { + // don't repeat yourself + // skip secondary callbacks + if (!(key in state.jobs)) + { + return; + } + + // clean up jobs + delete state.jobs[key]; + + if (error) + { + // don't process rest of the results + // stop still active jobs + // and reset the list + abort(state); + } + else + { + state.results[key] = output; + } + + // return salvaged results + callback(error, state.results); + }); +} + +/** + * Runs iterator over provided job element + * + * @param {function} iterator - iterator to invoke + * @param {string|number} key - key/index of the element in the list of jobs + * @param {mixed} item - job description + * @param {function} callback - invoked after iterator is done with the job + * @returns {function|mixed} - job abort function or something else + */ +function runJob(iterator, key, item, callback) +{ + var aborter; + + // allow shortcut if iterator expects only two arguments + if (iterator.length == 2) + { + aborter = iterator(item, async(callback)); + } + // otherwise go with full three arguments + else + { + aborter = iterator(item, key, async(callback)); + } + + return aborter; +} diff --git a/3-asynchronous-JS/node_modules/asynckit/lib/readable_asynckit.js b/3-asynchronous-JS/node_modules/asynckit/lib/readable_asynckit.js new file mode 100644 index 0000000000..78ad240f0a --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/lib/readable_asynckit.js @@ -0,0 +1,91 @@ +var streamify = require('./streamify.js') + , defer = require('./defer.js') + ; + +// API +module.exports = ReadableAsyncKit; + +/** + * Base constructor for all streams + * used to hold properties/methods + */ +function ReadableAsyncKit() +{ + ReadableAsyncKit.super_.apply(this, arguments); + + // list of active jobs + this.jobs = {}; + + // add stream methods + this.destroy = destroy; + this._start = _start; + this._read = _read; +} + +/** + * Destroys readable stream, + * by aborting outstanding jobs + * + * @returns {void} + */ +function destroy() +{ + if (this.destroyed) + { + return; + } + + this.destroyed = true; + + if (typeof this.terminator == 'function') + { + this.terminator(); + } +} + +/** + * Starts provided jobs in async manner + * + * @private + */ +function _start() +{ + // first argument – runner function + var runner = arguments[0] + // take away first argument + , args = Array.prototype.slice.call(arguments, 1) + // second argument - input data + , input = args[0] + // last argument - result callback + , endCb = streamify.callback.call(this, args[args.length - 1]) + ; + + args[args.length - 1] = endCb; + // third argument - iterator + args[1] = streamify.iterator.call(this, args[1]); + + // allow time for proper setup + defer(function() + { + if (!this.destroyed) + { + this.terminator = runner.apply(null, args); + } + else + { + endCb(null, Array.isArray(input) ? [] : {}); + } + }.bind(this)); +} + + +/** + * Implement _read to comply with Readable streams + * Doesn't really make sense for flowing object mode + * + * @private + */ +function _read() +{ + +} diff --git a/3-asynchronous-JS/node_modules/asynckit/lib/readable_parallel.js b/3-asynchronous-JS/node_modules/asynckit/lib/readable_parallel.js new file mode 100644 index 0000000000..5d2929f7a6 --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/lib/readable_parallel.js @@ -0,0 +1,25 @@ +var parallel = require('../parallel.js'); + +// API +module.exports = ReadableParallel; + +/** + * Streaming wrapper to `asynckit.parallel` + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {stream.Readable#} + */ +function ReadableParallel(list, iterator, callback) +{ + if (!(this instanceof ReadableParallel)) + { + return new ReadableParallel(list, iterator, callback); + } + + // turn on object mode + ReadableParallel.super_.call(this, {objectMode: true}); + + this._start(parallel, list, iterator, callback); +} diff --git a/3-asynchronous-JS/node_modules/asynckit/lib/readable_serial.js b/3-asynchronous-JS/node_modules/asynckit/lib/readable_serial.js new file mode 100644 index 0000000000..7822698204 --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/lib/readable_serial.js @@ -0,0 +1,25 @@ +var serial = require('../serial.js'); + +// API +module.exports = ReadableSerial; + +/** + * Streaming wrapper to `asynckit.serial` + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {stream.Readable#} + */ +function ReadableSerial(list, iterator, callback) +{ + if (!(this instanceof ReadableSerial)) + { + return new ReadableSerial(list, iterator, callback); + } + + // turn on object mode + ReadableSerial.super_.call(this, {objectMode: true}); + + this._start(serial, list, iterator, callback); +} diff --git a/3-asynchronous-JS/node_modules/asynckit/lib/readable_serial_ordered.js b/3-asynchronous-JS/node_modules/asynckit/lib/readable_serial_ordered.js new file mode 100644 index 0000000000..3de89c4729 --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/lib/readable_serial_ordered.js @@ -0,0 +1,29 @@ +var serialOrdered = require('../serialOrdered.js'); + +// API +module.exports = ReadableSerialOrdered; +// expose sort helpers +module.exports.ascending = serialOrdered.ascending; +module.exports.descending = serialOrdered.descending; + +/** + * Streaming wrapper to `asynckit.serialOrdered` + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} sortMethod - custom sort function + * @param {function} callback - invoked when all elements processed + * @returns {stream.Readable#} + */ +function ReadableSerialOrdered(list, iterator, sortMethod, callback) +{ + if (!(this instanceof ReadableSerialOrdered)) + { + return new ReadableSerialOrdered(list, iterator, sortMethod, callback); + } + + // turn on object mode + ReadableSerialOrdered.super_.call(this, {objectMode: true}); + + this._start(serialOrdered, list, iterator, sortMethod, callback); +} diff --git a/3-asynchronous-JS/node_modules/asynckit/lib/state.js b/3-asynchronous-JS/node_modules/asynckit/lib/state.js new file mode 100644 index 0000000000..cbea7ad8f6 --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/lib/state.js @@ -0,0 +1,37 @@ +// API +module.exports = state; + +/** + * Creates initial state object + * for iteration over list + * + * @param {array|object} list - list to iterate over + * @param {function|null} sortMethod - function to use for keys sort, + * or `null` to keep them as is + * @returns {object} - initial state object + */ +function state(list, sortMethod) +{ + var isNamedList = !Array.isArray(list) + , initState = + { + index : 0, + keyedList: isNamedList || sortMethod ? Object.keys(list) : null, + jobs : {}, + results : isNamedList ? {} : [], + size : isNamedList ? Object.keys(list).length : list.length + } + ; + + if (sortMethod) + { + // sort array keys based on it's values + // sort object's keys just on own merit + initState.keyedList.sort(isNamedList ? sortMethod : function(a, b) + { + return sortMethod(list[a], list[b]); + }); + } + + return initState; +} diff --git a/3-asynchronous-JS/node_modules/asynckit/lib/streamify.js b/3-asynchronous-JS/node_modules/asynckit/lib/streamify.js new file mode 100644 index 0000000000..f56a1c92bf --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/lib/streamify.js @@ -0,0 +1,141 @@ +var async = require('./async.js'); + +// API +module.exports = { + iterator: wrapIterator, + callback: wrapCallback +}; + +/** + * Wraps iterators with long signature + * + * @this ReadableAsyncKit# + * @param {function} iterator - function to wrap + * @returns {function} - wrapped function + */ +function wrapIterator(iterator) +{ + var stream = this; + + return function(item, key, cb) + { + var aborter + , wrappedCb = async(wrapIteratorCallback.call(stream, cb, key)) + ; + + stream.jobs[key] = wrappedCb; + + // it's either shortcut (item, cb) + if (iterator.length == 2) + { + aborter = iterator(item, wrappedCb); + } + // or long format (item, key, cb) + else + { + aborter = iterator(item, key, wrappedCb); + } + + return aborter; + }; +} + +/** + * Wraps provided callback function + * allowing to execute snitch function before + * real callback + * + * @this ReadableAsyncKit# + * @param {function} callback - function to wrap + * @returns {function} - wrapped function + */ +function wrapCallback(callback) +{ + var stream = this; + + var wrapped = function(error, result) + { + return finisher.call(stream, error, result, callback); + }; + + return wrapped; +} + +/** + * Wraps provided iterator callback function + * makes sure snitch only called once, + * but passes secondary calls to the original callback + * + * @this ReadableAsyncKit# + * @param {function} callback - callback to wrap + * @param {number|string} key - iteration key + * @returns {function} wrapped callback + */ +function wrapIteratorCallback(callback, key) +{ + var stream = this; + + return function(error, output) + { + // don't repeat yourself + if (!(key in stream.jobs)) + { + callback(error, output); + return; + } + + // clean up jobs + delete stream.jobs[key]; + + return streamer.call(stream, error, {key: key, value: output}, callback); + }; +} + +/** + * Stream wrapper for iterator callback + * + * @this ReadableAsyncKit# + * @param {mixed} error - error response + * @param {mixed} output - iterator output + * @param {function} callback - callback that expects iterator results + */ +function streamer(error, output, callback) +{ + if (error && !this.error) + { + this.error = error; + this.pause(); + this.emit('error', error); + // send back value only, as expected + callback(error, output && output.value); + return; + } + + // stream stuff + this.push(output); + + // back to original track + // send back value only, as expected + callback(error, output && output.value); +} + +/** + * Stream wrapper for finishing callback + * + * @this ReadableAsyncKit# + * @param {mixed} error - error response + * @param {mixed} output - iterator output + * @param {function} callback - callback that expects final results + */ +function finisher(error, output, callback) +{ + // signal end of the stream + // only for successfully finished streams + if (!error) + { + this.push(null); + } + + // back to original track + callback(error, output); +} diff --git a/3-asynchronous-JS/node_modules/asynckit/lib/terminator.js b/3-asynchronous-JS/node_modules/asynckit/lib/terminator.js new file mode 100644 index 0000000000..d6eb99219f --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/lib/terminator.js @@ -0,0 +1,29 @@ +var abort = require('./abort.js') + , async = require('./async.js') + ; + +// API +module.exports = terminator; + +/** + * Terminates jobs in the attached state context + * + * @this AsyncKitState# + * @param {function} callback - final callback to invoke after termination + */ +function terminator(callback) +{ + if (!Object.keys(this.jobs).length) + { + return; + } + + // fast forward iteration index + this.index = this.size; + + // abort jobs + abort(this); + + // send back results we have so far + async(callback)(null, this.results); +} diff --git a/3-asynchronous-JS/node_modules/asynckit/package.json b/3-asynchronous-JS/node_modules/asynckit/package.json new file mode 100644 index 0000000000..51147d6569 --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/package.json @@ -0,0 +1,63 @@ +{ + "name": "asynckit", + "version": "0.4.0", + "description": "Minimal async jobs utility library, with streams support", + "main": "index.js", + "scripts": { + "clean": "rimraf coverage", + "lint": "eslint *.js lib/*.js test/*.js", + "test": "istanbul cover --reporter=json tape -- 'test/test-*.js' | tap-spec", + "win-test": "tape test/test-*.js", + "browser": "browserify -t browserify-istanbul test/lib/browserify_adjustment.js test/test-*.js | obake --coverage | tap-spec", + "report": "istanbul report", + "size": "browserify index.js | size-table asynckit", + "debug": "tape test/test-*.js" + }, + "pre-commit": [ + "clean", + "lint", + "test", + "browser", + "report", + "size" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/alexindigo/asynckit.git" + }, + "keywords": [ + "async", + "jobs", + "parallel", + "serial", + "iterator", + "array", + "object", + "stream", + "destroy", + "terminate", + "abort" + ], + "author": "Alex Indigo ", + "license": "MIT", + "bugs": { + "url": "https://github.com/alexindigo/asynckit/issues" + }, + "homepage": "https://github.com/alexindigo/asynckit#readme", + "devDependencies": { + "browserify": "^13.0.0", + "browserify-istanbul": "^2.0.0", + "coveralls": "^2.11.9", + "eslint": "^2.9.0", + "istanbul": "^0.4.3", + "obake": "^0.1.2", + "phantomjs-prebuilt": "^2.1.7", + "pre-commit": "^1.1.3", + "reamde": "^1.1.0", + "rimraf": "^2.5.2", + "size-table": "^0.2.0", + "tap-spec": "^4.1.1", + "tape": "^4.5.1" + }, + "dependencies": {} +} diff --git a/3-asynchronous-JS/node_modules/asynckit/parallel.js b/3-asynchronous-JS/node_modules/asynckit/parallel.js new file mode 100644 index 0000000000..3c50344d85 --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/parallel.js @@ -0,0 +1,43 @@ +var iterate = require('./lib/iterate.js') + , initState = require('./lib/state.js') + , terminator = require('./lib/terminator.js') + ; + +// Public API +module.exports = parallel; + +/** + * Runs iterator over provided array elements in parallel + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function parallel(list, iterator, callback) +{ + var state = initState(list); + + while (state.index < (state['keyedList'] || list).length) + { + iterate(list, iterator, state, function(error, result) + { + if (error) + { + callback(error, result); + return; + } + + // looks like it's the last one + if (Object.keys(state.jobs).length === 0) + { + callback(null, state.results); + return; + } + }); + + state.index++; + } + + return terminator.bind(state, callback); +} diff --git a/3-asynchronous-JS/node_modules/asynckit/serial.js b/3-asynchronous-JS/node_modules/asynckit/serial.js new file mode 100644 index 0000000000..6cd949a677 --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/serial.js @@ -0,0 +1,17 @@ +var serialOrdered = require('./serialOrdered.js'); + +// Public API +module.exports = serial; + +/** + * Runs iterator over provided array elements in series + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function serial(list, iterator, callback) +{ + return serialOrdered(list, iterator, null, callback); +} diff --git a/3-asynchronous-JS/node_modules/asynckit/serialOrdered.js b/3-asynchronous-JS/node_modules/asynckit/serialOrdered.js new file mode 100644 index 0000000000..607eafea56 --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/serialOrdered.js @@ -0,0 +1,75 @@ +var iterate = require('./lib/iterate.js') + , initState = require('./lib/state.js') + , terminator = require('./lib/terminator.js') + ; + +// Public API +module.exports = serialOrdered; +// sorting helpers +module.exports.ascending = ascending; +module.exports.descending = descending; + +/** + * Runs iterator over provided sorted array elements in series + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} sortMethod - custom sort function + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function serialOrdered(list, iterator, sortMethod, callback) +{ + var state = initState(list, sortMethod); + + iterate(list, iterator, state, function iteratorHandler(error, result) + { + if (error) + { + callback(error, result); + return; + } + + state.index++; + + // are we there yet? + if (state.index < (state['keyedList'] || list).length) + { + iterate(list, iterator, state, iteratorHandler); + return; + } + + // done here + callback(null, state.results); + }); + + return terminator.bind(state, callback); +} + +/* + * -- Sort methods + */ + +/** + * sort helper to sort array elements in ascending order + * + * @param {mixed} a - an item to compare + * @param {mixed} b - an item to compare + * @returns {number} - comparison result + */ +function ascending(a, b) +{ + return a < b ? -1 : a > b ? 1 : 0; +} + +/** + * sort helper to sort array elements in descending order + * + * @param {mixed} a - an item to compare + * @param {mixed} b - an item to compare + * @returns {number} - comparison result + */ +function descending(a, b) +{ + return -1 * ascending(a, b); +} diff --git a/3-asynchronous-JS/node_modules/asynckit/stream.js b/3-asynchronous-JS/node_modules/asynckit/stream.js new file mode 100644 index 0000000000..d43465f903 --- /dev/null +++ b/3-asynchronous-JS/node_modules/asynckit/stream.js @@ -0,0 +1,21 @@ +var inherits = require('util').inherits + , Readable = require('stream').Readable + , ReadableAsyncKit = require('./lib/readable_asynckit.js') + , ReadableParallel = require('./lib/readable_parallel.js') + , ReadableSerial = require('./lib/readable_serial.js') + , ReadableSerialOrdered = require('./lib/readable_serial_ordered.js') + ; + +// API +module.exports = +{ + parallel : ReadableParallel, + serial : ReadableSerial, + serialOrdered : ReadableSerialOrdered, +}; + +inherits(ReadableAsyncKit, Readable); + +inherits(ReadableParallel, ReadableAsyncKit); +inherits(ReadableSerial, ReadableAsyncKit); +inherits(ReadableSerialOrdered, ReadableAsyncKit); diff --git a/3-asynchronous-JS/node_modules/call-bind-apply-helpers/.eslintrc b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/.eslintrc new file mode 100644 index 0000000000..dfa9a6cdcf --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/.eslintrc @@ -0,0 +1,16 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "func-name-matching": 0, + "id-length": 0, + "new-cap": [2, { + "capIsNewExceptions": [ + "GetIntrinsic", + ], + }], + "no-magic-numbers": 0, + }, +} diff --git a/3-asynchronous-JS/node_modules/call-bind-apply-helpers/.github/FUNDING.yml b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/.github/FUNDING.yml new file mode 100644 index 0000000000..0011e9d65f --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# 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/3-asynchronous-JS/node_modules/call-bind-apply-helpers/.nycrc b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/.nycrc new file mode 100644 index 0000000000..bdd626ce91 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/.nycrc @@ -0,0 +1,9 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "exclude": [ + "coverage", + "test" + ] +} diff --git a/3-asynchronous-JS/node_modules/call-bind-apply-helpers/CHANGELOG.md b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/CHANGELOG.md new file mode 100644 index 0000000000..cf630e88e1 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/CHANGELOG.md @@ -0,0 +1,23 @@ +# 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.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/3-asynchronous-JS/node_modules/call-bind-apply-helpers/LICENSE b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/LICENSE new file mode 100644 index 0000000000..f82f38963b --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/LICENSE @@ -0,0 +1,21 @@ +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/3-asynchronous-JS/node_modules/call-bind-apply-helpers/README.md b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/README.md new file mode 100644 index 0000000000..8fc0dae1b3 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/README.md @@ -0,0 +1,62 @@ +# 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/3-asynchronous-JS/node_modules/call-bind-apply-helpers/actualApply.d.ts b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/actualApply.d.ts new file mode 100644 index 0000000000..b87286a21e --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/actualApply.d.ts @@ -0,0 +1 @@ +export = Reflect.apply; \ No newline at end of file diff --git a/3-asynchronous-JS/node_modules/call-bind-apply-helpers/actualApply.js b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/actualApply.js new file mode 100644 index 0000000000..ffa51355dc --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/actualApply.js @@ -0,0 +1,10 @@ +'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/3-asynchronous-JS/node_modules/call-bind-apply-helpers/applyBind.d.ts b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/applyBind.d.ts new file mode 100644 index 0000000000..d176c1ab30 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/applyBind.d.ts @@ -0,0 +1,19 @@ +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/3-asynchronous-JS/node_modules/call-bind-apply-helpers/applyBind.js b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/applyBind.js new file mode 100644 index 0000000000..d2b7723147 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/applyBind.js @@ -0,0 +1,10 @@ +'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/3-asynchronous-JS/node_modules/call-bind-apply-helpers/functionApply.d.ts b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/functionApply.d.ts new file mode 100644 index 0000000000..1f6e11b3d0 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/functionApply.d.ts @@ -0,0 +1 @@ +export = Function.prototype.apply; \ No newline at end of file diff --git a/3-asynchronous-JS/node_modules/call-bind-apply-helpers/functionApply.js b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/functionApply.js new file mode 100644 index 0000000000..c71df9c2bc --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/functionApply.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./functionApply')} */ +module.exports = Function.prototype.apply; diff --git a/3-asynchronous-JS/node_modules/call-bind-apply-helpers/functionCall.d.ts b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/functionCall.d.ts new file mode 100644 index 0000000000..15e93df350 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/functionCall.d.ts @@ -0,0 +1 @@ +export = Function.prototype.call; \ No newline at end of file diff --git a/3-asynchronous-JS/node_modules/call-bind-apply-helpers/functionCall.js b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/functionCall.js new file mode 100644 index 0000000000..7a8d873575 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/functionCall.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./functionCall')} */ +module.exports = Function.prototype.call; diff --git a/3-asynchronous-JS/node_modules/call-bind-apply-helpers/index.d.ts b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/index.d.ts new file mode 100644 index 0000000000..a7ae2c57c7 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/index.d.ts @@ -0,0 +1,46 @@ +type RemoveFromTuple< + Tuple extends unknown[], + RemoveCount extends number, + Index extends 1[] = [] +> = Index["length"] extends RemoveCount + ? Tuple + : Tuple extends [first: unknown, ...infer Rest] + ? RemoveFromTuple + : Tuple; + +type ConcatTuples< + Prefix extends unknown[], + Suffix extends unknown[] +> = [...Prefix, ...Suffix]; + +type ReplaceThis = T extends (this: infer OldThis, ...args: infer A) => infer R + ? (this: NewThis, ...args: A) => R + : never; + +type BindFunction< + TThis, + T extends (this: TThis, ...args: any[]) => any, // Allow specific types to propagate + TBoundArgs extends unknown[], + ReceiverBound extends boolean +> = ReceiverBound extends true + ? (...args: RemoveFromTuple, TBoundArgs["length"] & number>) => ReturnType> + : (...args: ConcatTuples<[TThis], RemoveFromTuple, TBoundArgs["length"] & number>>) => ReturnType; + +declare function callBind< + TThis, + T extends (this: TThis, ...args: any[]) => any, + TBoundArgs extends Partial> +>( + args: [fn: T, thisArg: TThis, ...boundArgs: TBoundArgs] +): BindFunction; + +declare function callBind< + TThis, + T extends (this: TThis, ...args: any[]) => any, + TBoundArgs extends Partial> +>( + args: [fn: T, ...boundArgs: TBoundArgs] +): BindFunction; + +export as namespace callBind; +export = callBind; diff --git a/3-asynchronous-JS/node_modules/call-bind-apply-helpers/index.js b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/index.js new file mode 100644 index 0000000000..8b6b99463c --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/index.js @@ -0,0 +1,15 @@ +'use strict'; + +var bind = require('function-bind'); +var $TypeError = require('es-errors/type'); + +var $call = require('./functionCall'); +var $actualApply = require('./actualApply'); + +/** @type {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/3-asynchronous-JS/node_modules/call-bind-apply-helpers/package.json b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/package.json new file mode 100644 index 0000000000..7398be7043 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/package.json @@ -0,0 +1,85 @@ +{ + "name": "call-bind-apply-helpers", + "version": "1.0.1", + "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.1", + "@ljharb/eslint-config": "^21.1.1", + "@ljharb/tsconfig": "^0.2.2", + "@types/for-each": "^0.3.3", + "@types/function-bind": "^1.1.10", + "@types/object-inspect": "^1.13.0", + "@types/tape": "^5.6.5", + "auto-changelog": "^2.5.0", + "encoding": "^0.1.13", + "es-value-fixtures": "^1.5.0", + "eslint": "=8.8.0", + "evalmd": "^0.0.19", + "for-each": "^0.3.3", + "has-strict-mode": "^1.0.1", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "object-inspect": "^1.13.3", + "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/3-asynchronous-JS/node_modules/call-bind-apply-helpers/reflectApply.d.ts b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/reflectApply.d.ts new file mode 100644 index 0000000000..6b2ae764c5 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/reflectApply.d.ts @@ -0,0 +1,3 @@ +declare const reflectApply: false | typeof Reflect.apply; + +export = reflectApply; diff --git a/3-asynchronous-JS/node_modules/call-bind-apply-helpers/reflectApply.js b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/reflectApply.js new file mode 100644 index 0000000000..3d03caa695 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/reflectApply.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./reflectApply')} */ +module.exports = typeof Reflect !== 'undefined' && Reflect && Reflect.apply; diff --git a/3-asynchronous-JS/node_modules/call-bind-apply-helpers/test/index.js b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/test/index.js new file mode 100644 index 0000000000..8acc08a68f --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/test/index.js @@ -0,0 +1,63 @@ +'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: number, b: number) => [T | undefined, number, number]} */ + 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) => [sentinel, typeof a, typeof b])} */ + var boundR = callBind([func, sentinel]); + /** type {((b: number) => [sentinel, number, typeof b])} */ + var boundArg = callBind([func, sentinel, 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/3-asynchronous-JS/node_modules/call-bind-apply-helpers/tsconfig.json b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/tsconfig.json new file mode 100644 index 0000000000..aef9993084 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bind-apply-helpers/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + "target": "es2021", + }, + "exclude": [ + "coverage", + ], +} \ No newline at end of file diff --git a/3-asynchronous-JS/node_modules/call-bound/.eslintrc b/3-asynchronous-JS/node_modules/call-bound/.eslintrc new file mode 100644 index 0000000000..2612ed8fef --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bound/.eslintrc @@ -0,0 +1,13 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "new-cap": [2, { + "capIsNewExceptions": [ + "GetIntrinsic", + ], + }], + }, +} diff --git a/3-asynchronous-JS/node_modules/call-bound/.github/FUNDING.yml b/3-asynchronous-JS/node_modules/call-bound/.github/FUNDING.yml new file mode 100644 index 0000000000..2a2a135713 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bound/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# 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/3-asynchronous-JS/node_modules/call-bound/.nycrc b/3-asynchronous-JS/node_modules/call-bound/.nycrc new file mode 100644 index 0000000000..bdd626ce91 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bound/.nycrc @@ -0,0 +1,9 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "exclude": [ + "coverage", + "test" + ] +} diff --git a/3-asynchronous-JS/node_modules/call-bound/CHANGELOG.md b/3-asynchronous-JS/node_modules/call-bound/CHANGELOG.md new file mode 100644 index 0000000000..25fa7a5e12 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bound/CHANGELOG.md @@ -0,0 +1,34 @@ +# 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.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/3-asynchronous-JS/node_modules/call-bound/LICENSE b/3-asynchronous-JS/node_modules/call-bound/LICENSE new file mode 100644 index 0000000000..f82f38963b --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bound/LICENSE @@ -0,0 +1,21 @@ +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/3-asynchronous-JS/node_modules/call-bound/README.md b/3-asynchronous-JS/node_modules/call-bound/README.md new file mode 100644 index 0000000000..a44e43e56e --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bound/README.md @@ -0,0 +1,53 @@ +# 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/3-asynchronous-JS/node_modules/call-bound/index.d.ts b/3-asynchronous-JS/node_modules/call-bound/index.d.ts new file mode 100644 index 0000000000..e3d772ce58 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bound/index.d.ts @@ -0,0 +1,13 @@ +import callBind from 'call-bind-apply-helpers'; + +declare function callBoundIntrinsic( + name: string, + allowMissing?: false +): ReturnType; + +declare function callBoundIntrinsic( + name: string, + allowMissing: true +): undefined | ReturnType; + +export = callBoundIntrinsic; \ No newline at end of file diff --git a/3-asynchronous-JS/node_modules/call-bound/index.js b/3-asynchronous-JS/node_modules/call-bound/index.js new file mode 100644 index 0000000000..3bb40121a7 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bound/index.js @@ -0,0 +1,18 @@ +'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-disable-next-line no-extra-parens + var intrinsic = /** @type {Parameters[0][0]} */ (GetIntrinsic(name, !!allowMissing)); + if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) { + return callBindBasic([intrinsic]); + } + return intrinsic; +}; diff --git a/3-asynchronous-JS/node_modules/call-bound/package.json b/3-asynchronous-JS/node_modules/call-bound/package.json new file mode 100644 index 0000000000..2893ed11ab --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bound/package.json @@ -0,0 +1,99 @@ +{ + "name": "call-bound", + "version": "1.0.3", + "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.1", + "get-intrinsic": "^1.2.6" + }, + "devDependencies": { + "@arethetypeswrong/cli": "^0.17.1", + "@ljharb/eslint-config": "^21.1.1", + "@ljharb/tsconfig": "^0.2.2", + "@types/call-bind": "^1.0.5", + "@types/get-intrinsic": "^1.2.3", + "@types/tape": "^5.6.5", + "auto-changelog": "^2.5.0", + "encoding": "^0.1.13", + "es-value-fixtures": "^1.5.0", + "eslint": "=8.8.0", + "evalmd": "^0.0.19", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-strict-mode": "^1.0.1", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "object-inspect": "^1.13.3", + "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/3-asynchronous-JS/node_modules/call-bound/test/index.js b/3-asynchronous-JS/node_modules/call-bound/test/index.js new file mode 100644 index 0000000000..36f5f0b973 --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bound/test/index.js @@ -0,0 +1,54 @@ +'use strict'; + +var test = require('tape'); + +var callBound = require('../'); + +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'); + + // prototype function + t.notEqual(callBound('Object.prototype.toString'), Object.prototype.toString, 'Object.prototype.toString does not yield itself'); + t.notEqual(callBound('%Object.prototype.toString%'), Object.prototype.toString, '%Object.prototype.toString% does not yield itself'); + t.equal(callBound('Object.prototype.toString')(true), Object.prototype.toString.call(true), 'call-bound Object.prototype.toString calls into the original'); + t.equal(callBound('%Object.prototype.toString%')(true), Object.prototype.toString.call(true), 'call-bound %Object.prototype.toString% calls into the original'); + + t['throws']( + function () { callBound('does not exist'); }, + SyntaxError, + 'nonexistent intrinsic throws' + ); + t['throws']( + 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/3-asynchronous-JS/node_modules/call-bound/tsconfig.json b/3-asynchronous-JS/node_modules/call-bound/tsconfig.json new file mode 100644 index 0000000000..d9a6668c3a --- /dev/null +++ b/3-asynchronous-JS/node_modules/call-bound/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + "target": "es2021", + }, + "exclude": [ + "coverage", + ], +} diff --git a/3-asynchronous-JS/node_modules/combined-stream/License b/3-asynchronous-JS/node_modules/combined-stream/License new file mode 100644 index 0000000000..4804b7ab41 --- /dev/null +++ b/3-asynchronous-JS/node_modules/combined-stream/License @@ -0,0 +1,19 @@ +Copyright (c) 2011 Debuggable Limited + +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/3-asynchronous-JS/node_modules/combined-stream/Readme.md b/3-asynchronous-JS/node_modules/combined-stream/Readme.md new file mode 100644 index 0000000000..9e367b5bc5 --- /dev/null +++ b/3-asynchronous-JS/node_modules/combined-stream/Readme.md @@ -0,0 +1,138 @@ +# combined-stream + +A stream that emits multiple other streams one after another. + +**NB** Currently `combined-stream` works with streams version 1 only. There is ongoing effort to switch this library to streams version 2. Any help is welcome. :) Meanwhile you can explore other libraries that provide streams2 support with more or less compatibility with `combined-stream`. + +- [combined-stream2](https://www.npmjs.com/package/combined-stream2): A drop-in streams2-compatible replacement for the combined-stream module. + +- [multistream](https://www.npmjs.com/package/multistream): A stream that emits multiple other streams one after another. + +## Installation + +``` bash +npm install combined-stream +``` + +## Usage + +Here is a simple example that shows how you can use combined-stream to combine +two files into one: + +``` javascript +var CombinedStream = require('combined-stream'); +var fs = require('fs'); + +var combinedStream = CombinedStream.create(); +combinedStream.append(fs.createReadStream('file1.txt')); +combinedStream.append(fs.createReadStream('file2.txt')); + +combinedStream.pipe(fs.createWriteStream('combined.txt')); +``` + +While the example above works great, it will pause all source streams until +they are needed. If you don't want that to happen, you can set `pauseStreams` +to `false`: + +``` javascript +var CombinedStream = require('combined-stream'); +var fs = require('fs'); + +var combinedStream = CombinedStream.create({pauseStreams: false}); +combinedStream.append(fs.createReadStream('file1.txt')); +combinedStream.append(fs.createReadStream('file2.txt')); + +combinedStream.pipe(fs.createWriteStream('combined.txt')); +``` + +However, what if you don't have all the source streams yet, or you don't want +to allocate the resources (file descriptors, memory, etc.) for them right away? +Well, in that case you can simply provide a callback that supplies the stream +by calling a `next()` function: + +``` javascript +var CombinedStream = require('combined-stream'); +var fs = require('fs'); + +var combinedStream = CombinedStream.create(); +combinedStream.append(function(next) { + next(fs.createReadStream('file1.txt')); +}); +combinedStream.append(function(next) { + next(fs.createReadStream('file2.txt')); +}); + +combinedStream.pipe(fs.createWriteStream('combined.txt')); +``` + +## API + +### CombinedStream.create([options]) + +Returns a new combined stream object. Available options are: + +* `maxDataSize` +* `pauseStreams` + +The effect of those options is described below. + +### combinedStream.pauseStreams = `true` + +Whether to apply back pressure to the underlaying streams. If set to `false`, +the underlaying streams will never be paused. If set to `true`, the +underlaying streams will be paused right after being appended, as well as when +`delayedStream.pipe()` wants to throttle. + +### combinedStream.maxDataSize = `2 * 1024 * 1024` + +The maximum amount of bytes (or characters) to buffer for all source streams. +If this value is exceeded, `combinedStream` emits an `'error'` event. + +### combinedStream.dataSize = `0` + +The amount of bytes (or characters) currently buffered by `combinedStream`. + +### combinedStream.append(stream) + +Appends the given `stream` to the combinedStream object. If `pauseStreams` is +set to `true, this stream will also be paused right away. + +`streams` can also be a function that takes one parameter called `next`. `next` +is a function that must be invoked in order to provide the `next` stream, see +example above. + +Regardless of how the `stream` is appended, combined-stream always attaches an +`'error'` listener to it, so you don't have to do that manually. + +Special case: `stream` can also be a String or Buffer. + +### combinedStream.write(data) + +You should not call this, `combinedStream` takes care of piping the appended +streams into itself for you. + +### combinedStream.resume() + +Causes `combinedStream` to start drain the streams it manages. The function is +idempotent, and also emits a `'resume'` event each time which usually goes to +the stream that is currently being drained. + +### combinedStream.pause(); + +If `combinedStream.pauseStreams` is set to `false`, this does nothing. +Otherwise a `'pause'` event is emitted, this goes to the stream that is +currently being drained, so you can use it to apply back pressure. + +### combinedStream.end(); + +Sets `combinedStream.writable` to false, emits an `'end'` event, and removes +all streams from the queue. + +### combinedStream.destroy(); + +Same as `combinedStream.end()`, except it emits a `'close'` event instead of +`'end'`. + +## License + +combined-stream is licensed under the MIT license. diff --git a/3-asynchronous-JS/node_modules/combined-stream/lib/combined_stream.js b/3-asynchronous-JS/node_modules/combined-stream/lib/combined_stream.js new file mode 100644 index 0000000000..125f097f35 --- /dev/null +++ b/3-asynchronous-JS/node_modules/combined-stream/lib/combined_stream.js @@ -0,0 +1,208 @@ +var util = require('util'); +var Stream = require('stream').Stream; +var DelayedStream = require('delayed-stream'); + +module.exports = CombinedStream; +function CombinedStream() { + this.writable = false; + this.readable = true; + this.dataSize = 0; + this.maxDataSize = 2 * 1024 * 1024; + this.pauseStreams = true; + + this._released = false; + this._streams = []; + this._currentStream = null; + this._insideLoop = false; + this._pendingNext = false; +} +util.inherits(CombinedStream, Stream); + +CombinedStream.create = function(options) { + var combinedStream = new this(); + + options = options || {}; + for (var option in options) { + combinedStream[option] = options[option]; + } + + return combinedStream; +}; + +CombinedStream.isStreamLike = function(stream) { + return (typeof stream !== 'function') + && (typeof stream !== 'string') + && (typeof stream !== 'boolean') + && (typeof stream !== 'number') + && (!Buffer.isBuffer(stream)); +}; + +CombinedStream.prototype.append = function(stream) { + var isStreamLike = CombinedStream.isStreamLike(stream); + + if (isStreamLike) { + if (!(stream instanceof DelayedStream)) { + var newStream = DelayedStream.create(stream, { + maxDataSize: Infinity, + pauseStream: this.pauseStreams, + }); + stream.on('data', this._checkDataSize.bind(this)); + stream = newStream; + } + + this._handleErrors(stream); + + if (this.pauseStreams) { + stream.pause(); + } + } + + this._streams.push(stream); + return this; +}; + +CombinedStream.prototype.pipe = function(dest, options) { + Stream.prototype.pipe.call(this, dest, options); + this.resume(); + return dest; +}; + +CombinedStream.prototype._getNext = function() { + this._currentStream = null; + + if (this._insideLoop) { + this._pendingNext = true; + return; // defer call + } + + this._insideLoop = true; + try { + do { + this._pendingNext = false; + this._realGetNext(); + } while (this._pendingNext); + } finally { + this._insideLoop = false; + } +}; + +CombinedStream.prototype._realGetNext = function() { + var stream = this._streams.shift(); + + + if (typeof stream == 'undefined') { + this.end(); + return; + } + + if (typeof stream !== 'function') { + this._pipeNext(stream); + return; + } + + var getStream = stream; + getStream(function(stream) { + var isStreamLike = CombinedStream.isStreamLike(stream); + if (isStreamLike) { + stream.on('data', this._checkDataSize.bind(this)); + this._handleErrors(stream); + } + + this._pipeNext(stream); + }.bind(this)); +}; + +CombinedStream.prototype._pipeNext = function(stream) { + this._currentStream = stream; + + var isStreamLike = CombinedStream.isStreamLike(stream); + if (isStreamLike) { + stream.on('end', this._getNext.bind(this)); + stream.pipe(this, {end: false}); + return; + } + + var value = stream; + this.write(value); + this._getNext(); +}; + +CombinedStream.prototype._handleErrors = function(stream) { + var self = this; + stream.on('error', function(err) { + self._emitError(err); + }); +}; + +CombinedStream.prototype.write = function(data) { + this.emit('data', data); +}; + +CombinedStream.prototype.pause = function() { + if (!this.pauseStreams) { + return; + } + + if(this.pauseStreams && this._currentStream && typeof(this._currentStream.pause) == 'function') this._currentStream.pause(); + this.emit('pause'); +}; + +CombinedStream.prototype.resume = function() { + if (!this._released) { + this._released = true; + this.writable = true; + this._getNext(); + } + + if(this.pauseStreams && this._currentStream && typeof(this._currentStream.resume) == 'function') this._currentStream.resume(); + this.emit('resume'); +}; + +CombinedStream.prototype.end = function() { + this._reset(); + this.emit('end'); +}; + +CombinedStream.prototype.destroy = function() { + this._reset(); + this.emit('close'); +}; + +CombinedStream.prototype._reset = function() { + this.writable = false; + this._streams = []; + this._currentStream = null; +}; + +CombinedStream.prototype._checkDataSize = function() { + this._updateDataSize(); + if (this.dataSize <= this.maxDataSize) { + return; + } + + var message = + 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'; + this._emitError(new Error(message)); +}; + +CombinedStream.prototype._updateDataSize = function() { + this.dataSize = 0; + + var self = this; + this._streams.forEach(function(stream) { + if (!stream.dataSize) { + return; + } + + self.dataSize += stream.dataSize; + }); + + if (this._currentStream && this._currentStream.dataSize) { + this.dataSize += this._currentStream.dataSize; + } +}; + +CombinedStream.prototype._emitError = function(err) { + this._reset(); + this.emit('error', err); +}; diff --git a/3-asynchronous-JS/node_modules/combined-stream/package.json b/3-asynchronous-JS/node_modules/combined-stream/package.json new file mode 100644 index 0000000000..6982b6da17 --- /dev/null +++ b/3-asynchronous-JS/node_modules/combined-stream/package.json @@ -0,0 +1,25 @@ +{ + "author": "Felix Geisendörfer (http://debuggable.com/)", + "name": "combined-stream", + "description": "A stream that emits multiple other streams one after another.", + "version": "1.0.8", + "homepage": "https://github.com/felixge/node-combined-stream", + "repository": { + "type": "git", + "url": "git://github.com/felixge/node-combined-stream.git" + }, + "main": "./lib/combined_stream", + "scripts": { + "test": "node test/run.js" + }, + "engines": { + "node": ">= 0.8" + }, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "devDependencies": { + "far": "~0.0.7" + }, + "license": "MIT" +} diff --git a/3-asynchronous-JS/node_modules/combined-stream/yarn.lock b/3-asynchronous-JS/node_modules/combined-stream/yarn.lock new file mode 100644 index 0000000000..7edf41840c --- /dev/null +++ b/3-asynchronous-JS/node_modules/combined-stream/yarn.lock @@ -0,0 +1,17 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +far@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/far/-/far-0.0.7.tgz#01c1fd362bcd26ce9cf161af3938aa34619f79a7" + dependencies: + oop "0.0.3" + +oop@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/oop/-/oop-0.0.3.tgz#70fa405a5650891a194fdc82ca68dad6dabf4401" diff --git a/3-asynchronous-JS/node_modules/component-emitter/LICENSE b/3-asynchronous-JS/node_modules/component-emitter/LICENSE new file mode 100644 index 0000000000..de51692732 --- /dev/null +++ b/3-asynchronous-JS/node_modules/component-emitter/LICENSE @@ -0,0 +1,24 @@ +(The MIT License) + +Copyright (c) 2014 Component contributors + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/3-asynchronous-JS/node_modules/component-emitter/Readme.md b/3-asynchronous-JS/node_modules/component-emitter/Readme.md new file mode 100644 index 0000000000..0f3f9b9fc3 --- /dev/null +++ b/3-asynchronous-JS/node_modules/component-emitter/Readme.md @@ -0,0 +1,74 @@ +# Emitter [![Build Status](https://travis-ci.org/component/emitter.png)](https://travis-ci.org/component/emitter) + + Event emitter component. + +## Installation + +``` +$ component install component/emitter +``` + +## API + +### Emitter(obj) + + The `Emitter` may also be used as a mixin. For example + a "plain" object may become an emitter, or you may + extend an existing prototype. + + As an `Emitter` instance: + +```js +var Emitter = require('emitter'); +var emitter = new Emitter; +emitter.emit('something'); +``` + + As a mixin: + +```js +var Emitter = require('emitter'); +var user = { name: 'tobi' }; +Emitter(user); + +user.emit('im a user'); +``` + + As a prototype mixin: + +```js +var Emitter = require('emitter'); +Emitter(User.prototype); +``` + +### Emitter#on(event, fn) + + Register an `event` handler `fn`. + +### Emitter#once(event, fn) + + Register a single-shot `event` handler `fn`, + removed immediately after it is invoked the + first time. + +### Emitter#off(event, fn) + + * Pass `event` and `fn` to remove a listener. + * Pass `event` to remove all listeners on that event. + * Pass nothing to remove all listeners on all events. + +### Emitter#emit(event, ...) + + Emit an `event` with variable option args. + +### Emitter#listeners(event) + + Return an array of callbacks, or an empty array. + +### Emitter#hasListeners(event) + + Check if this emitter has `event` handlers. + +## License + +MIT diff --git a/3-asynchronous-JS/node_modules/component-emitter/index.js b/3-asynchronous-JS/node_modules/component-emitter/index.js new file mode 100644 index 0000000000..6d7ed0ab3c --- /dev/null +++ b/3-asynchronous-JS/node_modules/component-emitter/index.js @@ -0,0 +1,175 @@ + +/** + * Expose `Emitter`. + */ + +if (typeof module !== 'undefined') { + module.exports = Emitter; +} + +/** + * Initialize a new `Emitter`. + * + * @api public + */ + +function Emitter(obj) { + if (obj) return mixin(obj); +}; + +/** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; +} + +/** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.on = +Emitter.prototype.addEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks['$' + event] = this._callbacks['$' + event] || []) + .push(fn); + return this; +}; + +/** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.once = function(event, fn){ + function on() { + this.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; +}; + +/** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.off = +Emitter.prototype.removeListener = +Emitter.prototype.removeAllListeners = +Emitter.prototype.removeEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + + // specific event + var callbacks = this._callbacks['$' + event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks['$' + event]; + return this; + } + + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + + // Remove event specific arrays for event types that no + // one is subscribed for to avoid memory leak. + if (callbacks.length === 0) { + delete this._callbacks['$' + event]; + } + + return this; +}; + +/** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + +Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + + var args = new Array(arguments.length - 1) + , callbacks = this._callbacks['$' + event]; + + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; +}; + +/** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + +Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks['$' + event] || []; +}; + +/** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + +Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; +}; diff --git a/3-asynchronous-JS/node_modules/component-emitter/package.json b/3-asynchronous-JS/node_modules/component-emitter/package.json new file mode 100644 index 0000000000..0b8eca979c --- /dev/null +++ b/3-asynchronous-JS/node_modules/component-emitter/package.json @@ -0,0 +1,28 @@ +{ + "name": "component-emitter", + "description": "Event emitter", + "version": "1.3.1", + "license": "MIT", + "funding": "https://github.com/sponsors/sindresorhus", + "devDependencies": { + "mocha": "*", + "should": "*" + }, + "component": { + "scripts": { + "emitter/index.js": "index.js" + } + }, + "main": "index.js", + "repository": { + "type": "git", + "url": "https://github.com/sindresorhus/component-emitter.git" + }, + "scripts": { + "test": "make test" + }, + "files": [ + "index.js", + "LICENSE" + ] +} diff --git a/3-asynchronous-JS/node_modules/cookiejar/LICENSE b/3-asynchronous-JS/node_modules/cookiejar/LICENSE new file mode 100644 index 0000000000..58a23ecee6 --- /dev/null +++ b/3-asynchronous-JS/node_modules/cookiejar/LICENSE @@ -0,0 +1,9 @@ +The MIT License (MIT) +Copyright (c) 2013 Bradley Meck + +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/3-asynchronous-JS/node_modules/cookiejar/cookiejar.js b/3-asynchronous-JS/node_modules/cookiejar/cookiejar.js new file mode 100644 index 0000000000..df2925cdbc --- /dev/null +++ b/3-asynchronous-JS/node_modules/cookiejar/cookiejar.js @@ -0,0 +1,281 @@ +/* jshint node: true */ +(function () { + "use strict"; + + function CookieAccessInfo(domain, path, secure, script) { + if (this instanceof CookieAccessInfo) { + this.domain = domain || undefined; + this.path = path || "/"; + this.secure = !!secure; + this.script = !!script; + return this; + } + return new CookieAccessInfo(domain, path, secure, script); + } + CookieAccessInfo.All = Object.freeze(Object.create(null)); + exports.CookieAccessInfo = CookieAccessInfo; + + function Cookie(cookiestr, request_domain, request_path) { + if (cookiestr instanceof Cookie) { + return cookiestr; + } + if (this instanceof Cookie) { + this.name = null; + this.value = null; + this.expiration_date = Infinity; + this.path = String(request_path || "/"); + this.explicit_path = false; + this.domain = request_domain || null; + this.explicit_domain = false; + this.secure = false; //how to define default? + this.noscript = false; //httponly + if (cookiestr) { + this.parse(cookiestr, request_domain, request_path); + } + return this; + } + return new Cookie(cookiestr, request_domain, request_path); + } + exports.Cookie = Cookie; + + Cookie.prototype.toString = function toString() { + var str = [this.name + "=" + this.value]; + if (this.expiration_date !== Infinity) { + str.push("expires=" + (new Date(this.expiration_date)).toGMTString()); + } + if (this.domain) { + str.push("domain=" + this.domain); + } + if (this.path) { + str.push("path=" + this.path); + } + if (this.secure) { + str.push("secure"); + } + if (this.noscript) { + str.push("httponly"); + } + return str.join("; "); + }; + + Cookie.prototype.toValueString = function toValueString() { + return this.name + "=" + this.value; + }; + + var cookie_str_splitter = /[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g; + Cookie.prototype.parse = function parse(str, request_domain, request_path) { + if (this instanceof Cookie) { + if ( str.length > 32768 ) { + console.warn("Cookie too long for parsing (>32768 characters)"); + return; + } + + var parts = str.split(";").filter(function (value) { + return !!value; + }); + var i; + + var pair = parts[0].match(/([^=]+)=([\s\S]*)/); + if (!pair) { + console.warn("Invalid cookie header encountered. Header: '"+str+"'"); + return; + } + + var key = pair[1]; + var value = pair[2]; + if ( typeof key !== 'string' || key.length === 0 || typeof value !== 'string' ) { + console.warn("Unable to extract values from cookie header. Cookie: '"+str+"'"); + return; + } + + this.name = key; + this.value = value; + + for (i = 1; i < parts.length; i += 1) { + pair = parts[i].match(/([^=]+)(?:=([\s\S]*))?/); + key = pair[1].trim().toLowerCase(); + value = pair[2]; + switch (key) { + case "httponly": + this.noscript = true; + break; + case "expires": + this.expiration_date = value ? + Number(Date.parse(value)) : + Infinity; + break; + case "path": + this.path = value ? + value.trim() : + ""; + this.explicit_path = true; + break; + case "domain": + this.domain = value ? + value.trim() : + ""; + this.explicit_domain = !!this.domain; + break; + case "secure": + this.secure = true; + break; + } + } + + if (!this.explicit_path) { + this.path = request_path || "/"; + } + if (!this.explicit_domain) { + this.domain = request_domain; + } + + return this; + } + return new Cookie().parse(str, request_domain, request_path); + }; + + Cookie.prototype.matches = function matches(access_info) { + if (access_info === CookieAccessInfo.All) { + return true; + } + if (this.noscript && access_info.script || + this.secure && !access_info.secure || + !this.collidesWith(access_info)) { + return false; + } + return true; + }; + + Cookie.prototype.collidesWith = function collidesWith(access_info) { + if ((this.path && !access_info.path) || (this.domain && !access_info.domain)) { + return false; + } + if (this.path && access_info.path.indexOf(this.path) !== 0) { + return false; + } + if (this.explicit_path && access_info.path.indexOf( this.path ) !== 0) { + return false; + } + var access_domain = access_info.domain && access_info.domain.replace(/^[\.]/,''); + var cookie_domain = this.domain && this.domain.replace(/^[\.]/,''); + if (cookie_domain === access_domain) { + return true; + } + if (cookie_domain) { + if (!this.explicit_domain) { + return false; // we already checked if the domains were exactly the same + } + var wildcard = access_domain.indexOf(cookie_domain); + if (wildcard === -1 || wildcard !== access_domain.length - cookie_domain.length) { + return false; + } + return true; + } + return true; + }; + + function CookieJar() { + var cookies, cookies_list, collidable_cookie; + if (this instanceof CookieJar) { + cookies = Object.create(null); //name: [Cookie] + + this.setCookie = function setCookie(cookie, request_domain, request_path) { + var remove, i; + cookie = new Cookie(cookie, request_domain, request_path); + //Delete the cookie if the set is past the current time + remove = cookie.expiration_date <= Date.now(); + if (cookies[cookie.name] !== undefined) { + cookies_list = cookies[cookie.name]; + for (i = 0; i < cookies_list.length; i += 1) { + collidable_cookie = cookies_list[i]; + if (collidable_cookie.collidesWith(cookie)) { + if (remove) { + cookies_list.splice(i, 1); + if (cookies_list.length === 0) { + delete cookies[cookie.name]; + } + return false; + } + cookies_list[i] = cookie; + return cookie; + } + } + if (remove) { + return false; + } + cookies_list.push(cookie); + return cookie; + } + if (remove) { + return false; + } + cookies[cookie.name] = [cookie]; + return cookies[cookie.name]; + }; + //returns a cookie + this.getCookie = function getCookie(cookie_name, access_info) { + var cookie, i; + cookies_list = cookies[cookie_name]; + if (!cookies_list) { + return; + } + for (i = 0; i < cookies_list.length; i += 1) { + cookie = cookies_list[i]; + if (cookie.expiration_date <= Date.now()) { + if (cookies_list.length === 0) { + delete cookies[cookie.name]; + } + continue; + } + + if (cookie.matches(access_info)) { + return cookie; + } + } + }; + //returns a list of cookies + this.getCookies = function getCookies(access_info) { + var matches = [], cookie_name, cookie; + for (cookie_name in cookies) { + cookie = this.getCookie(cookie_name, access_info); + if (cookie) { + matches.push(cookie); + } + } + matches.toString = function toString() { + return matches.join(":"); + }; + matches.toValueString = function toValueString() { + return matches.map(function (c) { + return c.toValueString(); + }).join('; '); + }; + return matches; + }; + + return this; + } + return new CookieJar(); + } + exports.CookieJar = CookieJar; + + //returns list of cookies that were set correctly. Cookies that are expired and removed are not returned. + CookieJar.prototype.setCookies = function setCookies(cookies, request_domain, request_path) { + cookies = Array.isArray(cookies) ? + cookies : + cookies.split(cookie_str_splitter); + var successful = [], + i, + cookie; + cookies = cookies.map(function(item){ + return new Cookie(item, request_domain, request_path); + }); + for (i = 0; i < cookies.length; i += 1) { + cookie = cookies[i]; + if (this.setCookie(cookie, request_domain, request_path)) { + successful.push(cookie); + } + } + return successful; + }; +}()); diff --git a/3-asynchronous-JS/node_modules/cookiejar/package.json b/3-asynchronous-JS/node_modules/cookiejar/package.json new file mode 100644 index 0000000000..be1316f925 --- /dev/null +++ b/3-asynchronous-JS/node_modules/cookiejar/package.json @@ -0,0 +1,26 @@ +{ + "name": "cookiejar", + "version": "2.1.4", + "author": { + "name": "bradleymeck" + }, + "main": "cookiejar.js", + "description": "simple persistent cookiejar system", + "files": [ + "cookiejar.js" + ], + "license": "MIT", + "jshintConfig": { + "node": true + }, + "scripts": { + "test": "node tests/test.js" + }, + "repository": { + "type": "git", + "url": "https://github.com/bmeck/node-cookiejar.git" + }, + "devDependencies": { + "jshint": "^2.9.4" + } +} diff --git a/3-asynchronous-JS/node_modules/cookiejar/readme.md b/3-asynchronous-JS/node_modules/cookiejar/readme.md new file mode 100644 index 0000000000..71a9f233bd --- /dev/null +++ b/3-asynchronous-JS/node_modules/cookiejar/readme.md @@ -0,0 +1,60 @@ +# CookieJar + +[![NPM version](http://img.shields.io/npm/v/cookiejar.svg)](https://www.npmjs.org/package/cookiejar) +[![devDependency Status](https://david-dm.org/bmeck/node-cookiejar/dev-status.svg)](https://david-dm.org/bmeck/node-cookiejar?type=dev) + +Simple robust cookie library + +## Exports + +### CookieAccessInfo(domain,path,secure,script) + +class to determine matching qualities of a cookie + +##### Properties + +* String domain - domain to match +* String path - path to match +* Boolean secure - access is secure (ssl generally) +* Boolean script - access is from a script + + +### Cookie(cookiestr_or_cookie, request_domain, request_path) + +It turns input into a Cookie (singleton if given a Cookie), +the `request_domain` argument is used to default the domain if it is not explicit in the cookie string, +the `request_path` argument is used to set the path if it is not explicit in a cookie String. + +Explicit domains/paths will cascade, implied domains/paths must *exactly* match (see http://en.wikipedia.org/wiki/HTTP_cookie#Domain_and_Pat). + +##### Properties + +* String name - name of the cookie +* String value - string associated with the cookie +* String domain - domain to match (on a cookie a '.' at the start means a wildcard matching anything ending in the rest) +* Boolean explicit_domain - if the domain was explicitly set via the cookie string +* String path - base path to match (matches any path starting with this '/' is root) +* Boolean explicit_path - if the path was explicitly set via the cookie string +* Boolean noscript - if it should be kept from scripts +* Boolean secure - should it only be transmitted over secure means +* Number expiration_date - number of millis since 1970 at which this should be removed + +##### Methods + +* `String toString()` - the __set-cookie:__ string for this cookie +* `String toValueString()` - the __cookie:__ string for this cookie +* `Cookie parse(cookiestr, request_domain, request_path)` - parses the string onto this cookie or a new one if called directly +* `Boolean matches(access_info)` - returns true if the access_info allows retrieval of this cookie +* `Boolean collidesWith(cookie)` - returns true if the cookies cannot exist in the same space (domain and path match) + + +### CookieJar() + +class to hold numerous cookies from multiple domains correctly + +##### Methods + +* `Cookie setCookie(cookie, request_domain, request_path)` - modify (or add if not already-existing) a cookie to the jar +* `Cookie[] setCookies(cookiestr_or_list, request_domain, request_path)` - modify (or add if not already-existing) a large number of cookies to the jar +* `Cookie getCookie(cookie_name,access_info)` - get a cookie with the name and access_info matching +* `Cookie[] getCookies(access_info)` - grab all cookies matching this access_info diff --git a/3-asynchronous-JS/node_modules/debug/LICENSE b/3-asynchronous-JS/node_modules/debug/LICENSE new file mode 100644 index 0000000000..1a9820e262 --- /dev/null +++ b/3-asynchronous-JS/node_modules/debug/LICENSE @@ -0,0 +1,20 @@ +(The MIT License) + +Copyright (c) 2014-2017 TJ Holowaychuk +Copyright (c) 2018-2021 Josh Junon + +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/3-asynchronous-JS/node_modules/debug/README.md b/3-asynchronous-JS/node_modules/debug/README.md new file mode 100644 index 0000000000..9ebdfbf149 --- /dev/null +++ b/3-asynchronous-JS/node_modules/debug/README.md @@ -0,0 +1,481 @@ +# debug +[![OpenCollective](https://opencollective.com/debug/backers/badge.svg)](#backers) +[![OpenCollective](https://opencollective.com/debug/sponsors/badge.svg)](#sponsors) + + + +A tiny JavaScript debugging utility modelled after Node.js core's debugging +technique. Works in Node.js and web browsers. + +## Installation + +```bash +$ npm install debug +``` + +## Usage + +`debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole. + +Example [_app.js_](./examples/node/app.js): + +```js +var debug = require('debug')('http') + , http = require('http') + , name = 'My App'; + +// fake app + +debug('booting %o', name); + +http.createServer(function(req, res){ + debug(req.method + ' ' + req.url); + res.end('hello\n'); +}).listen(3000, function(){ + debug('listening'); +}); + +// fake worker of some kind + +require('./worker'); +``` + +Example [_worker.js_](./examples/node/worker.js): + +```js +var a = require('debug')('worker:a') + , b = require('debug')('worker:b'); + +function work() { + a('doing lots of uninteresting work'); + setTimeout(work, Math.random() * 1000); +} + +work(); + +function workb() { + b('doing some work'); + setTimeout(workb, Math.random() * 2000); +} + +workb(); +``` + +The `DEBUG` environment variable is then used to enable these based on space or +comma-delimited names. + +Here are some examples: + +screen shot 2017-08-08 at 12 53 04 pm +screen shot 2017-08-08 at 12 53 38 pm +screen shot 2017-08-08 at 12 53 25 pm + +#### Windows command prompt notes + +##### CMD + +On Windows the environment variable is set using the `set` command. + +```cmd +set DEBUG=*,-not_this +``` + +Example: + +```cmd +set DEBUG=* & node app.js +``` + +##### PowerShell (VS Code default) + +PowerShell uses different syntax to set environment variables. + +```cmd +$env:DEBUG = "*,-not_this" +``` + +Example: + +```cmd +$env:DEBUG='app';node app.js +``` + +Then, run the program to be debugged as usual. + +npm script example: +```js + "windowsDebug": "@powershell -Command $env:DEBUG='*';node app.js", +``` + +## Namespace Colors + +Every debug instance has a color generated for it based on its namespace name. +This helps when visually parsing the debug output to identify which debug instance +a debug line belongs to. + +#### Node.js + +In Node.js, colors are enabled when stderr is a TTY. You also _should_ install +the [`supports-color`](https://npmjs.org/supports-color) module alongside debug, +otherwise debug will only use a small handful of basic colors. + + + +#### Web Browser + +Colors are also enabled on "Web Inspectors" that understand the `%c` formatting +option. These are WebKit web inspectors, Firefox ([since version +31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/)) +and the Firebug plugin for Firefox (any version). + + + + +## Millisecond diff + +When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls. + + + +When stdout is not a TTY, `Date#toISOString()` is used, making it more useful for logging the debug information as shown below: + + + + +## Conventions + +If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser". If you append a "*" to the end of your name, it will always be enabled regardless of the setting of the DEBUG environment variable. You can then use it for normal output as well as debug output. + +## Wildcards + +The `*` character may be used as a wildcard. Suppose for example your library has +debuggers named "connect:bodyParser", "connect:compress", "connect:session", +instead of listing all three with +`DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do +`DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`. + +You can also exclude specific debuggers by prefixing them with a "-" character. +For example, `DEBUG=*,-connect:*` would include all debuggers except those +starting with "connect:". + +## Environment Variables + +When running through Node.js, you can set a few environment variables that will +change the behavior of the debug logging: + +| Name | Purpose | +|-----------|-------------------------------------------------| +| `DEBUG` | Enables/disables specific debugging namespaces. | +| `DEBUG_HIDE_DATE` | Hide date from debug output (non-TTY). | +| `DEBUG_COLORS`| Whether or not to use colors in the debug output. | +| `DEBUG_DEPTH` | Object inspection depth. | +| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. | + + +__Note:__ The environment variables beginning with `DEBUG_` end up being +converted into an Options object that gets used with `%o`/`%O` formatters. +See the Node.js documentation for +[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options) +for the complete list. + +## Formatters + +Debug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting. +Below are the officially supported formatters: + +| Formatter | Representation | +|-----------|----------------| +| `%O` | Pretty-print an Object on multiple lines. | +| `%o` | Pretty-print an Object all on a single line. | +| `%s` | String. | +| `%d` | Number (both integer and float). | +| `%j` | JSON. Replaced with the string '[Circular]' if the argument contains circular references. | +| `%%` | Single percent sign ('%'). This does not consume an argument. | + + +### Custom formatters + +You can add custom formatters by extending the `debug.formatters` object. +For example, if you wanted to add support for rendering a Buffer as hex with +`%h`, you could do something like: + +```js +const createDebug = require('debug') +createDebug.formatters.h = (v) => { + return v.toString('hex') +} + +// …elsewhere +const debug = createDebug('foo') +debug('this is hex: %h', new Buffer('hello world')) +// foo this is hex: 68656c6c6f20776f726c6421 +0ms +``` + + +## Browser Support + +You can build a browser-ready script using [browserify](https://github.com/substack/node-browserify), +or just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest), +if you don't want to build it yourself. + +Debug's enable state is currently persisted by `localStorage`. +Consider the situation shown below where you have `worker:a` and `worker:b`, +and wish to debug both. You can enable this using `localStorage.debug`: + +```js +localStorage.debug = 'worker:*' +``` + +And then refresh the page. + +```js +a = debug('worker:a'); +b = debug('worker:b'); + +setInterval(function(){ + a('doing some work'); +}, 1000); + +setInterval(function(){ + b('doing some work'); +}, 1200); +``` + +In Chromium-based web browsers (e.g. Brave, Chrome, and Electron), the JavaScript console will—by default—only show messages logged by `debug` if the "Verbose" log level is _enabled_. + + + +## Output streams + + By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method: + +Example [_stdout.js_](./examples/node/stdout.js): + +```js +var debug = require('debug'); +var error = debug('app:error'); + +// by default stderr is used +error('goes to stderr!'); + +var log = debug('app:log'); +// set this namespace to log via console.log +log.log = console.log.bind(console); // don't forget to bind to console! +log('goes to stdout'); +error('still goes to stderr!'); + +// set all output to go via console.info +// overrides all per-namespace log settings +debug.log = console.info.bind(console); +error('now goes to stdout via console.info'); +log('still goes to stdout, but via console.info now'); +``` + +## Extend +You can simply extend debugger +```js +const log = require('debug')('auth'); + +//creates new debug instance with extended namespace +const logSign = log.extend('sign'); +const logLogin = log.extend('login'); + +log('hello'); // auth hello +logSign('hello'); //auth:sign hello +logLogin('hello'); //auth:login hello +``` + +## Set dynamically + +You can also enable debug dynamically by calling the `enable()` method : + +```js +let debug = require('debug'); + +console.log(1, debug.enabled('test')); + +debug.enable('test'); +console.log(2, debug.enabled('test')); + +debug.disable(); +console.log(3, debug.enabled('test')); + +``` + +print : +``` +1 false +2 true +3 false +``` + +Usage : +`enable(namespaces)` +`namespaces` can include modes separated by a colon and wildcards. + +Note that calling `enable()` completely overrides previously set DEBUG variable : + +``` +$ DEBUG=foo node -e 'var dbg = require("debug"); dbg.enable("bar"); console.log(dbg.enabled("foo"))' +=> false +``` + +`disable()` + +Will disable all namespaces. The functions returns the namespaces currently +enabled (and skipped). This can be useful if you want to disable debugging +temporarily without knowing what was enabled to begin with. + +For example: + +```js +let debug = require('debug'); +debug.enable('foo:*,-foo:bar'); +let namespaces = debug.disable(); +debug.enable(namespaces); +``` + +Note: There is no guarantee that the string will be identical to the initial +enable string, but semantically they will be identical. + +## Checking whether a debug target is enabled + +After you've created a debug instance, you can determine whether or not it is +enabled by checking the `enabled` property: + +```javascript +const debug = require('debug')('http'); + +if (debug.enabled) { + // do stuff... +} +``` + +You can also manually toggle this property to force the debug instance to be +enabled or disabled. + +## Usage in child processes + +Due to the way `debug` detects if the output is a TTY or not, colors are not shown in child processes when `stderr` is piped. A solution is to pass the `DEBUG_COLORS=1` environment variable to the child process. +For example: + +```javascript +worker = fork(WORKER_WRAP_PATH, [workerPath], { + stdio: [ + /* stdin: */ 0, + /* stdout: */ 'pipe', + /* stderr: */ 'pipe', + 'ipc', + ], + env: Object.assign({}, process.env, { + DEBUG_COLORS: 1 // without this settings, colors won't be shown + }), +}); + +worker.stderr.pipe(process.stderr, { end: false }); +``` + + +## Authors + + - TJ Holowaychuk + - Nathan Rajlich + - Andrew Rhyne + - Josh Junon + +## Backers + +Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/debug#backer)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Sponsors + +Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/debug#sponsor)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## License + +(The MIT License) + +Copyright (c) 2014-2017 TJ Holowaychuk <tj@vision-media.ca> +Copyright (c) 2018-2021 Josh Junon + +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/3-asynchronous-JS/node_modules/debug/package.json b/3-asynchronous-JS/node_modules/debug/package.json new file mode 100644 index 0000000000..60dfcf57ca --- /dev/null +++ b/3-asynchronous-JS/node_modules/debug/package.json @@ -0,0 +1,65 @@ +{ + "name": "debug", + "version": "4.4.0", + "repository": { + "type": "git", + "url": "git://github.com/debug-js/debug.git" + }, + "description": "Lightweight debugging utility for Node.js and the browser", + "keywords": [ + "debug", + "log", + "debugger" + ], + "files": [ + "src", + "LICENSE", + "README.md" + ], + "author": "Josh Junon (https://github.com/qix-)", + "contributors": [ + "TJ Holowaychuk ", + "Nathan Rajlich (http://n8.io)", + "Andrew Rhyne " + ], + "license": "MIT", + "scripts": { + "lint": "xo", + "test": "npm run test:node && npm run test:browser && npm run lint", + "test:node": "istanbul cover _mocha -- test.js test.node.js", + "test:browser": "karma start --single-run", + "test:coverage": "cat ./coverage/lcov.info | coveralls" + }, + "dependencies": { + "ms": "^2.1.3" + }, + "devDependencies": { + "brfs": "^2.0.1", + "browserify": "^16.2.3", + "coveralls": "^3.0.2", + "istanbul": "^0.4.5", + "karma": "^3.1.4", + "karma-browserify": "^6.0.0", + "karma-chrome-launcher": "^2.2.0", + "karma-mocha": "^1.3.0", + "mocha": "^5.2.0", + "mocha-lcov-reporter": "^1.2.0", + "sinon": "^14.0.0", + "xo": "^0.23.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + }, + "main": "./src/index.js", + "browser": "./src/browser.js", + "engines": { + "node": ">=6.0" + }, + "xo": { + "rules": { + "import/extensions": "off" + } + } +} diff --git a/3-asynchronous-JS/node_modules/debug/src/browser.js b/3-asynchronous-JS/node_modules/debug/src/browser.js new file mode 100644 index 0000000000..df8e179e8b --- /dev/null +++ b/3-asynchronous-JS/node_modules/debug/src/browser.js @@ -0,0 +1,272 @@ +/* eslint-env browser */ + +/** + * This is the web browser implementation of `debug()`. + */ + +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +exports.storage = localstorage(); +exports.destroy = (() => { + let warned = false; + + return () => { + if (!warned) { + warned = true; + console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); + } + }; +})(); + +/** + * Colors. + */ + +exports.colors = [ + '#0000CC', + '#0000FF', + '#0033CC', + '#0033FF', + '#0066CC', + '#0066FF', + '#0099CC', + '#0099FF', + '#00CC00', + '#00CC33', + '#00CC66', + '#00CC99', + '#00CCCC', + '#00CCFF', + '#3300CC', + '#3300FF', + '#3333CC', + '#3333FF', + '#3366CC', + '#3366FF', + '#3399CC', + '#3399FF', + '#33CC00', + '#33CC33', + '#33CC66', + '#33CC99', + '#33CCCC', + '#33CCFF', + '#6600CC', + '#6600FF', + '#6633CC', + '#6633FF', + '#66CC00', + '#66CC33', + '#9900CC', + '#9900FF', + '#9933CC', + '#9933FF', + '#99CC00', + '#99CC33', + '#CC0000', + '#CC0033', + '#CC0066', + '#CC0099', + '#CC00CC', + '#CC00FF', + '#CC3300', + '#CC3333', + '#CC3366', + '#CC3399', + '#CC33CC', + '#CC33FF', + '#CC6600', + '#CC6633', + '#CC9900', + '#CC9933', + '#CCCC00', + '#CCCC33', + '#FF0000', + '#FF0033', + '#FF0066', + '#FF0099', + '#FF00CC', + '#FF00FF', + '#FF3300', + '#FF3333', + '#FF3366', + '#FF3399', + '#FF33CC', + '#FF33FF', + '#FF6600', + '#FF6633', + '#FF9900', + '#FF9933', + '#FFCC00', + '#FFCC33' +]; + +/** + * Currently only WebKit-based Web Inspectors, Firefox >= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ + +// eslint-disable-next-line complexity +function useColors() { + // NB: In an Electron preload script, document will be defined but not fully + // initialized. Since we know we're in Chrome, we'll just detect this case + // explicitly + if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { + return true; + } + + // Internet Explorer and Edge do not support colors. + if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { + return false; + } + + let m; + + // Is webkit? http://stackoverflow.com/a/16459606/376773 + // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + // eslint-disable-next-line no-return-assign + return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || + // Is firebug? http://stackoverflow.com/a/398120/376773 + (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || + // Is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + (typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) || + // Double check webkit in userAgent just in case we are in a worker + (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); +} + +/** + * Colorize log arguments if enabled. + * + * @api public + */ + +function formatArgs(args) { + args[0] = (this.useColors ? '%c' : '') + + this.namespace + + (this.useColors ? ' %c' : ' ') + + args[0] + + (this.useColors ? '%c ' : ' ') + + '+' + module.exports.humanize(this.diff); + + if (!this.useColors) { + return; + } + + const c = 'color: ' + this.color; + args.splice(1, 0, c, 'color: inherit'); + + // The final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + let index = 0; + let lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, match => { + if (match === '%%') { + return; + } + index++; + if (match === '%c') { + // We only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); + + args.splice(lastC, 0, c); +} + +/** + * Invokes `console.debug()` when available. + * No-op when `console.debug` is not a "function". + * If `console.debug` is not available, falls back + * to `console.log`. + * + * @api public + */ +exports.log = console.debug || console.log || (() => {}); + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ +function save(namespaces) { + try { + if (namespaces) { + exports.storage.setItem('debug', namespaces); + } else { + exports.storage.removeItem('debug'); + } + } catch (error) { + // Swallow + // XXX (@Qix-) should we be logging these? + } +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ +function load() { + let r; + try { + r = exports.storage.getItem('debug'); + } catch (error) { + // Swallow + // XXX (@Qix-) should we be logging these? + } + + // If debug isn't set in LS, and we're in Electron, try to load $DEBUG + if (!r && typeof process !== 'undefined' && 'env' in process) { + r = process.env.DEBUG; + } + + return r; +} + +/** + * Localstorage attempts to return the localstorage. + * + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. + * + * @return {LocalStorage} + * @api private + */ + +function localstorage() { + try { + // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context + // The Browser also has localStorage in the global context. + return localStorage; + } catch (error) { + // Swallow + // XXX (@Qix-) should we be logging these? + } +} + +module.exports = require('./common')(exports); + +const {formatters} = module.exports; + +/** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ + +formatters.j = function (v) { + try { + return JSON.stringify(v); + } catch (error) { + return '[UnexpectedJSONParseError]: ' + error.message; + } +}; diff --git a/3-asynchronous-JS/node_modules/debug/src/common.js b/3-asynchronous-JS/node_modules/debug/src/common.js new file mode 100644 index 0000000000..528c7ecf41 --- /dev/null +++ b/3-asynchronous-JS/node_modules/debug/src/common.js @@ -0,0 +1,292 @@ + +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + */ + +function setup(env) { + createDebug.debug = createDebug; + createDebug.default = createDebug; + createDebug.coerce = coerce; + createDebug.disable = disable; + createDebug.enable = enable; + createDebug.enabled = enabled; + createDebug.humanize = require('ms'); + createDebug.destroy = destroy; + + Object.keys(env).forEach(key => { + createDebug[key] = env[key]; + }); + + /** + * The currently active debug mode names, and names to skip. + */ + + createDebug.names = []; + createDebug.skips = []; + + /** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". + */ + createDebug.formatters = {}; + + /** + * Selects a color for a debug namespace + * @param {String} namespace The namespace string for the debug instance to be colored + * @return {Number|String} An ANSI color code for the given namespace + * @api private + */ + function selectColor(namespace) { + let hash = 0; + + for (let i = 0; i < namespace.length; i++) { + hash = ((hash << 5) - hash) + namespace.charCodeAt(i); + hash |= 0; // Convert to 32bit integer + } + + return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; + } + createDebug.selectColor = selectColor; + + /** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ + function createDebug(namespace) { + let prevTime; + let enableOverride = null; + let namespacesCache; + let enabledCache; + + function debug(...args) { + // Disabled? + if (!debug.enabled) { + return; + } + + const self = debug; + + // Set `diff` timestamp + const curr = Number(new Date()); + const ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + + args[0] = createDebug.coerce(args[0]); + + if (typeof args[0] !== 'string') { + // Anything else let's inspect with %O + args.unshift('%O'); + } + + // Apply any `formatters` transformations + let index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { + // If we encounter an escaped % then don't increase the array index + if (match === '%%') { + return '%'; + } + index++; + const formatter = createDebug.formatters[format]; + if (typeof formatter === 'function') { + const val = args[index]; + match = formatter.call(self, val); + + // Now we need to remove `args[index]` since it's inlined in the `format` + args.splice(index, 1); + index--; + } + return match; + }); + + // Apply env-specific formatting (colors, etc.) + createDebug.formatArgs.call(self, args); + + const logFn = self.log || createDebug.log; + logFn.apply(self, args); + } + + debug.namespace = namespace; + debug.useColors = createDebug.useColors(); + debug.color = createDebug.selectColor(namespace); + debug.extend = extend; + debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release. + + Object.defineProperty(debug, 'enabled', { + enumerable: true, + configurable: false, + get: () => { + if (enableOverride !== null) { + return enableOverride; + } + if (namespacesCache !== createDebug.namespaces) { + namespacesCache = createDebug.namespaces; + enabledCache = createDebug.enabled(namespace); + } + + return enabledCache; + }, + set: v => { + enableOverride = v; + } + }); + + // Env-specific initialization logic for debug instances + if (typeof createDebug.init === 'function') { + createDebug.init(debug); + } + + return debug; + } + + function extend(namespace, delimiter) { + const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); + newDebug.log = this.log; + return newDebug; + } + + /** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ + function enable(namespaces) { + createDebug.save(namespaces); + createDebug.namespaces = namespaces; + + createDebug.names = []; + createDebug.skips = []; + + const split = (typeof namespaces === 'string' ? namespaces : '') + .trim() + .replace(' ', ',') + .split(',') + .filter(Boolean); + + for (const ns of split) { + if (ns[0] === '-') { + createDebug.skips.push(ns.slice(1)); + } else { + createDebug.names.push(ns); + } + } + } + + /** + * Checks if the given string matches a namespace template, honoring + * asterisks as wildcards. + * + * @param {String} search + * @param {String} template + * @return {Boolean} + */ + function matchesTemplate(search, template) { + let searchIndex = 0; + let templateIndex = 0; + let starIndex = -1; + let matchIndex = 0; + + while (searchIndex < search.length) { + if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) { + // Match character or proceed with wildcard + if (template[templateIndex] === '*') { + starIndex = templateIndex; + matchIndex = searchIndex; + templateIndex++; // Skip the '*' + } else { + searchIndex++; + templateIndex++; + } + } else if (starIndex !== -1) { // eslint-disable-line no-negated-condition + // Backtrack to the last '*' and try to match more characters + templateIndex = starIndex + 1; + matchIndex++; + searchIndex = matchIndex; + } else { + return false; // No match + } + } + + // Handle trailing '*' in template + while (templateIndex < template.length && template[templateIndex] === '*') { + templateIndex++; + } + + return templateIndex === template.length; + } + + /** + * Disable debug output. + * + * @return {String} namespaces + * @api public + */ + function disable() { + const namespaces = [ + ...createDebug.names, + ...createDebug.skips.map(namespace => '-' + namespace) + ].join(','); + createDebug.enable(''); + return namespaces; + } + + /** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + function enabled(name) { + for (const skip of createDebug.skips) { + if (matchesTemplate(name, skip)) { + return false; + } + } + + for (const ns of createDebug.names) { + if (matchesTemplate(name, ns)) { + return true; + } + } + + return false; + } + + /** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + function coerce(val) { + if (val instanceof Error) { + return val.stack || val.message; + } + return val; + } + + /** + * XXX DO NOT USE. This is a temporary stub function. + * XXX It WILL be removed in the next major release. + */ + function destroy() { + console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); + } + + createDebug.enable(createDebug.load()); + + return createDebug; +} + +module.exports = setup; diff --git a/3-asynchronous-JS/node_modules/debug/src/index.js b/3-asynchronous-JS/node_modules/debug/src/index.js new file mode 100644 index 0000000000..bf4c57f259 --- /dev/null +++ b/3-asynchronous-JS/node_modules/debug/src/index.js @@ -0,0 +1,10 @@ +/** + * Detect Electron renderer / nwjs process, which is node, but we should + * treat as a browser. + */ + +if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) { + module.exports = require('./browser.js'); +} else { + module.exports = require('./node.js'); +} diff --git a/3-asynchronous-JS/node_modules/debug/src/node.js b/3-asynchronous-JS/node_modules/debug/src/node.js new file mode 100644 index 0000000000..715560a4ca --- /dev/null +++ b/3-asynchronous-JS/node_modules/debug/src/node.js @@ -0,0 +1,263 @@ +/** + * Module dependencies. + */ + +const tty = require('tty'); +const util = require('util'); + +/** + * This is the Node.js implementation of `debug()`. + */ + +exports.init = init; +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +exports.destroy = util.deprecate( + () => {}, + 'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.' +); + +/** + * Colors. + */ + +exports.colors = [6, 2, 3, 4, 5, 1]; + +try { + // Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json) + // eslint-disable-next-line import/no-extraneous-dependencies + const supportsColor = require('supports-color'); + + if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) { + exports.colors = [ + 20, + 21, + 26, + 27, + 32, + 33, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 56, + 57, + 62, + 63, + 68, + 69, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 92, + 93, + 98, + 99, + 112, + 113, + 128, + 129, + 134, + 135, + 148, + 149, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 178, + 179, + 184, + 185, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 214, + 215, + 220, + 221 + ]; + } +} catch (error) { + // Swallow - we only care if `supports-color` is available; it doesn't have to be. +} + +/** + * Build up the default `inspectOpts` object from the environment variables. + * + * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js + */ + +exports.inspectOpts = Object.keys(process.env).filter(key => { + return /^debug_/i.test(key); +}).reduce((obj, key) => { + // Camel-case + const prop = key + .substring(6) + .toLowerCase() + .replace(/_([a-z])/g, (_, k) => { + return k.toUpperCase(); + }); + + // Coerce string value into JS value + let val = process.env[key]; + if (/^(yes|on|true|enabled)$/i.test(val)) { + val = true; + } else if (/^(no|off|false|disabled)$/i.test(val)) { + val = false; + } else if (val === 'null') { + val = null; + } else { + val = Number(val); + } + + obj[prop] = val; + return obj; +}, {}); + +/** + * Is stdout a TTY? Colored output is enabled when `true`. + */ + +function useColors() { + return 'colors' in exports.inspectOpts ? + Boolean(exports.inspectOpts.colors) : + tty.isatty(process.stderr.fd); +} + +/** + * Adds ANSI color escape codes if enabled. + * + * @api public + */ + +function formatArgs(args) { + const {namespace: name, useColors} = this; + + if (useColors) { + const c = this.color; + const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c); + const prefix = ` ${colorCode};1m${name} \u001B[0m`; + + args[0] = prefix + args[0].split('\n').join('\n' + prefix); + args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m'); + } else { + args[0] = getDate() + name + ' ' + args[0]; + } +} + +function getDate() { + if (exports.inspectOpts.hideDate) { + return ''; + } + return new Date().toISOString() + ' '; +} + +/** + * Invokes `util.formatWithOptions()` with the specified arguments and writes to stderr. + */ + +function log(...args) { + return process.stderr.write(util.formatWithOptions(exports.inspectOpts, ...args) + '\n'); +} + +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ +function save(namespaces) { + if (namespaces) { + process.env.DEBUG = namespaces; + } else { + // If you set a process.env field to null or undefined, it gets cast to the + // string 'null' or 'undefined'. Just delete instead. + delete process.env.DEBUG; + } +} + +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + +function load() { + return process.env.DEBUG; +} + +/** + * Init logic for `debug` instances. + * + * Create a new `inspectOpts` object in case `useColors` is set + * differently for a particular `debug` instance. + */ + +function init(debug) { + debug.inspectOpts = {}; + + const keys = Object.keys(exports.inspectOpts); + for (let i = 0; i < keys.length; i++) { + debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; + } +} + +module.exports = require('./common')(exports); + +const {formatters} = module.exports; + +/** + * Map %o to `util.inspect()`, all on a single line. + */ + +formatters.o = function (v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts) + .split('\n') + .map(str => str.trim()) + .join(' '); +}; + +/** + * Map %O to `util.inspect()`, allowing multiple lines if needed. + */ + +formatters.O = function (v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts); +}; diff --git a/3-asynchronous-JS/node_modules/delayed-stream/.npmignore b/3-asynchronous-JS/node_modules/delayed-stream/.npmignore new file mode 100644 index 0000000000..9daeafb986 --- /dev/null +++ b/3-asynchronous-JS/node_modules/delayed-stream/.npmignore @@ -0,0 +1 @@ +test diff --git a/3-asynchronous-JS/node_modules/delayed-stream/License b/3-asynchronous-JS/node_modules/delayed-stream/License new file mode 100644 index 0000000000..4804b7ab41 --- /dev/null +++ b/3-asynchronous-JS/node_modules/delayed-stream/License @@ -0,0 +1,19 @@ +Copyright (c) 2011 Debuggable Limited + +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/3-asynchronous-JS/node_modules/delayed-stream/Makefile b/3-asynchronous-JS/node_modules/delayed-stream/Makefile new file mode 100644 index 0000000000..b4ff85a33b --- /dev/null +++ b/3-asynchronous-JS/node_modules/delayed-stream/Makefile @@ -0,0 +1,7 @@ +SHELL := /bin/bash + +test: + @./test/run.js + +.PHONY: test + diff --git a/3-asynchronous-JS/node_modules/delayed-stream/Readme.md b/3-asynchronous-JS/node_modules/delayed-stream/Readme.md new file mode 100644 index 0000000000..aca36f9f0b --- /dev/null +++ b/3-asynchronous-JS/node_modules/delayed-stream/Readme.md @@ -0,0 +1,141 @@ +# delayed-stream + +Buffers events from a stream until you are ready to handle them. + +## Installation + +``` bash +npm install delayed-stream +``` + +## Usage + +The following example shows how to write a http echo server that delays its +response by 1000 ms. + +``` javascript +var DelayedStream = require('delayed-stream'); +var http = require('http'); + +http.createServer(function(req, res) { + var delayed = DelayedStream.create(req); + + setTimeout(function() { + res.writeHead(200); + delayed.pipe(res); + }, 1000); +}); +``` + +If you are not using `Stream#pipe`, you can also manually release the buffered +events by calling `delayedStream.resume()`: + +``` javascript +var delayed = DelayedStream.create(req); + +setTimeout(function() { + // Emit all buffered events and resume underlaying source + delayed.resume(); +}, 1000); +``` + +## Implementation + +In order to use this meta stream properly, here are a few things you should +know about the implementation. + +### Event Buffering / Proxying + +All events of the `source` stream are hijacked by overwriting the `source.emit` +method. Until node implements a catch-all event listener, this is the only way. + +However, delayed-stream still continues to emit all events it captures on the +`source`, regardless of whether you have released the delayed stream yet or +not. + +Upon creation, delayed-stream captures all `source` events and stores them in +an internal event buffer. Once `delayedStream.release()` is called, all +buffered events are emitted on the `delayedStream`, and the event buffer is +cleared. After that, delayed-stream merely acts as a proxy for the underlaying +source. + +### Error handling + +Error events on `source` are buffered / proxied just like any other events. +However, `delayedStream.create` attaches a no-op `'error'` listener to the +`source`. This way you only have to handle errors on the `delayedStream` +object, rather than in two places. + +### Buffer limits + +delayed-stream provides a `maxDataSize` property that can be used to limit +the amount of data being buffered. In order to protect you from bad `source` +streams that don't react to `source.pause()`, this feature is enabled by +default. + +## API + +### DelayedStream.create(source, [options]) + +Returns a new `delayedStream`. Available options are: + +* `pauseStream` +* `maxDataSize` + +The description for those properties can be found below. + +### delayedStream.source + +The `source` stream managed by this object. This is useful if you are +passing your `delayedStream` around, and you still want to access properties +on the `source` object. + +### delayedStream.pauseStream = true + +Whether to pause the underlaying `source` when calling +`DelayedStream.create()`. Modifying this property afterwards has no effect. + +### delayedStream.maxDataSize = 1024 * 1024 + +The amount of data to buffer before emitting an `error`. + +If the underlaying source is emitting `Buffer` objects, the `maxDataSize` +refers to bytes. + +If the underlaying source is emitting JavaScript strings, the size refers to +characters. + +If you know what you are doing, you can set this property to `Infinity` to +disable this feature. You can also modify this property during runtime. + +### delayedStream.dataSize = 0 + +The amount of data buffered so far. + +### delayedStream.readable + +An ECMA5 getter that returns the value of `source.readable`. + +### delayedStream.resume() + +If the `delayedStream` has not been released so far, `delayedStream.release()` +is called. + +In either case, `source.resume()` is called. + +### delayedStream.pause() + +Calls `source.pause()`. + +### delayedStream.pipe(dest) + +Calls `delayedStream.resume()` and then proxies the arguments to `source.pipe`. + +### delayedStream.release() + +Emits and clears all events that have been buffered up so far. This does not +resume the underlaying source, use `delayedStream.resume()` instead. + +## License + +delayed-stream is licensed under the MIT license. diff --git a/3-asynchronous-JS/node_modules/delayed-stream/lib/delayed_stream.js b/3-asynchronous-JS/node_modules/delayed-stream/lib/delayed_stream.js new file mode 100644 index 0000000000..b38fc85ff4 --- /dev/null +++ b/3-asynchronous-JS/node_modules/delayed-stream/lib/delayed_stream.js @@ -0,0 +1,107 @@ +var Stream = require('stream').Stream; +var util = require('util'); + +module.exports = DelayedStream; +function DelayedStream() { + this.source = null; + this.dataSize = 0; + this.maxDataSize = 1024 * 1024; + this.pauseStream = true; + + this._maxDataSizeExceeded = false; + this._released = false; + this._bufferedEvents = []; +} +util.inherits(DelayedStream, Stream); + +DelayedStream.create = function(source, options) { + var delayedStream = new this(); + + options = options || {}; + for (var option in options) { + delayedStream[option] = options[option]; + } + + delayedStream.source = source; + + var realEmit = source.emit; + source.emit = function() { + delayedStream._handleEmit(arguments); + return realEmit.apply(source, arguments); + }; + + source.on('error', function() {}); + if (delayedStream.pauseStream) { + source.pause(); + } + + return delayedStream; +}; + +Object.defineProperty(DelayedStream.prototype, 'readable', { + configurable: true, + enumerable: true, + get: function() { + return this.source.readable; + } +}); + +DelayedStream.prototype.setEncoding = function() { + return this.source.setEncoding.apply(this.source, arguments); +}; + +DelayedStream.prototype.resume = function() { + if (!this._released) { + this.release(); + } + + this.source.resume(); +}; + +DelayedStream.prototype.pause = function() { + this.source.pause(); +}; + +DelayedStream.prototype.release = function() { + this._released = true; + + this._bufferedEvents.forEach(function(args) { + this.emit.apply(this, args); + }.bind(this)); + this._bufferedEvents = []; +}; + +DelayedStream.prototype.pipe = function() { + var r = Stream.prototype.pipe.apply(this, arguments); + this.resume(); + return r; +}; + +DelayedStream.prototype._handleEmit = function(args) { + if (this._released) { + this.emit.apply(this, args); + return; + } + + if (args[0] === 'data') { + this.dataSize += args[1].length; + this._checkIfMaxDataSizeExceeded(); + } + + this._bufferedEvents.push(args); +}; + +DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() { + if (this._maxDataSizeExceeded) { + return; + } + + if (this.dataSize <= this.maxDataSize) { + return; + } + + this._maxDataSizeExceeded = true; + var message = + 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.' + this.emit('error', new Error(message)); +}; diff --git a/3-asynchronous-JS/node_modules/delayed-stream/package.json b/3-asynchronous-JS/node_modules/delayed-stream/package.json new file mode 100644 index 0000000000..eea3291c54 --- /dev/null +++ b/3-asynchronous-JS/node_modules/delayed-stream/package.json @@ -0,0 +1,27 @@ +{ + "author": "Felix Geisendörfer (http://debuggable.com/)", + "contributors": [ + "Mike Atkins " + ], + "name": "delayed-stream", + "description": "Buffers events from a stream until you are ready to handle them.", + "license": "MIT", + "version": "1.0.0", + "homepage": "https://github.com/felixge/node-delayed-stream", + "repository": { + "type": "git", + "url": "git://github.com/felixge/node-delayed-stream.git" + }, + "main": "./lib/delayed_stream", + "engines": { + "node": ">=0.4.0" + }, + "scripts": { + "test": "make test" + }, + "dependencies": {}, + "devDependencies": { + "fake": "0.2.0", + "far": "0.0.1" + } +} diff --git a/3-asynchronous-JS/node_modules/dezalgo/LICENSE b/3-asynchronous-JS/node_modules/dezalgo/LICENSE new file mode 100644 index 0000000000..19129e315f --- /dev/null +++ b/3-asynchronous-JS/node_modules/dezalgo/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/3-asynchronous-JS/node_modules/dezalgo/README.md b/3-asynchronous-JS/node_modules/dezalgo/README.md new file mode 100644 index 0000000000..bdfc8ba80d --- /dev/null +++ b/3-asynchronous-JS/node_modules/dezalgo/README.md @@ -0,0 +1,29 @@ +# dezalgo + +Contain async insanity so that the dark pony lord doesn't eat souls + +See [this blog +post](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony). + +## USAGE + +Pass a callback to `dezalgo` and it will ensure that it is *always* +called in a future tick, and never in this tick. + +```javascript +var dz = require('dezalgo') + +var cache = {} +function maybeSync(arg, cb) { + cb = dz(cb) + + // this will actually defer to nextTick + if (cache[arg]) cb(null, cache[arg]) + + fs.readFile(arg, function (er, data) { + // since this is *already* defered, it will call immediately + if (er) cb(er) + cb(null, cache[arg] = data) + }) +} +``` diff --git a/3-asynchronous-JS/node_modules/dezalgo/dezalgo.js b/3-asynchronous-JS/node_modules/dezalgo/dezalgo.js new file mode 100644 index 0000000000..04fd3ba781 --- /dev/null +++ b/3-asynchronous-JS/node_modules/dezalgo/dezalgo.js @@ -0,0 +1,22 @@ +var wrappy = require('wrappy') +module.exports = wrappy(dezalgo) + +var asap = require('asap') + +function dezalgo (cb) { + var sync = true + asap(function () { + sync = false + }) + + return function zalgoSafe() { + var args = arguments + var me = this + if (sync) + asap(function() { + cb.apply(me, args) + }) + else + cb.apply(me, args) + } +} diff --git a/3-asynchronous-JS/node_modules/dezalgo/package.json b/3-asynchronous-JS/node_modules/dezalgo/package.json new file mode 100644 index 0000000000..f8ba8ec2b6 --- /dev/null +++ b/3-asynchronous-JS/node_modules/dezalgo/package.json @@ -0,0 +1,46 @@ +{ + "name": "dezalgo", + "version": "1.0.4", + "description": "Contain async insanity so that the dark pony lord doesn't eat souls", + "main": "dezalgo.js", + "files": [ + "dezalgo.js" + ], + "directories": { + "test": "test" + }, + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + }, + "devDependencies": { + "tap": "^12.4.0" + }, + "scripts": { + "test": "tap test/*.js" + }, + "repository": { + "type": "git", + "url": "https://github.com/npm/dezalgo" + }, + "keywords": [ + "async", + "zalgo", + "the dark pony", + "he comes", + "asynchrony of all holy and good", + "To invoke the hive mind representing chaos", + "Invoking the feeling of chaos. /Without order", + "The Nezperdian Hive Mind of Chaos, (zalgo………………)", + "He who waits beyond the wall", + "ZALGO", + "HE COMES", + "there used to be some funky unicode keywords here, but it broke the npm website on chrome, so they were removed, sorry" + ], + "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "license": "ISC", + "bugs": { + "url": "https://github.com/npm/dezalgo/issues" + }, + "homepage": "https://github.com/npm/dezalgo" +} diff --git a/3-asynchronous-JS/node_modules/dunder-proto/.eslintrc b/3-asynchronous-JS/node_modules/dunder-proto/.eslintrc new file mode 100644 index 0000000000..3b5d9e90ec --- /dev/null +++ b/3-asynchronous-JS/node_modules/dunder-proto/.eslintrc @@ -0,0 +1,5 @@ +{ + "root": true, + + "extends": "@ljharb", +} diff --git a/3-asynchronous-JS/node_modules/dunder-proto/.github/FUNDING.yml b/3-asynchronous-JS/node_modules/dunder-proto/.github/FUNDING.yml new file mode 100644 index 0000000000..8a1d7b0e9e --- /dev/null +++ b/3-asynchronous-JS/node_modules/dunder-proto/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# 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/dunder-proto +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/3-asynchronous-JS/node_modules/dunder-proto/.nycrc b/3-asynchronous-JS/node_modules/dunder-proto/.nycrc new file mode 100644 index 0000000000..1826526e09 --- /dev/null +++ b/3-asynchronous-JS/node_modules/dunder-proto/.nycrc @@ -0,0 +1,13 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "lines": 86, + "statements": 85.93, + "functions": 82.43, + "branches": 76.06, + "exclude": [ + "coverage", + "test" + ] +} diff --git a/3-asynchronous-JS/node_modules/dunder-proto/CHANGELOG.md b/3-asynchronous-JS/node_modules/dunder-proto/CHANGELOG.md new file mode 100644 index 0000000000..9b8b2f82ae --- /dev/null +++ b/3-asynchronous-JS/node_modules/dunder-proto/CHANGELOG.md @@ -0,0 +1,24 @@ +# 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.1](https://github.com/es-shims/dunder-proto/compare/v1.0.0...v1.0.1) - 2024-12-16 + +### Commits + +- [Fix] do not crash when `--disable-proto=throw` [`6c367d9`](https://github.com/es-shims/dunder-proto/commit/6c367d919bc1604778689a297bbdbfea65752847) +- [Tests] ensure noproto tests only use the current version of dunder-proto [`b02365b`](https://github.com/es-shims/dunder-proto/commit/b02365b9cf889c4a2cac7be0c3cfc90a789af36c) +- [Dev Deps] update `@arethetypeswrong/cli`, `@types/tape` [`e3c5c3b`](https://github.com/es-shims/dunder-proto/commit/e3c5c3bd81cf8cef7dff2eca19e558f0e307f666) +- [Deps] update `call-bind-apply-helpers` [`19f1da0`](https://github.com/es-shims/dunder-proto/commit/19f1da028b8dd0d05c85bfd8f7eed2819b686450) + +## v1.0.0 - 2024-12-06 + +### Commits + +- Initial implementation, tests, readme, types [`a5b74b0`](https://github.com/es-shims/dunder-proto/commit/a5b74b0082f5270cb0905cd9a2e533cee7498373) +- Initial commit [`73fb5a3`](https://github.com/es-shims/dunder-proto/commit/73fb5a353b51ac2ab00c9fdeb0114daffd4c07a8) +- npm init [`80152dc`](https://github.com/es-shims/dunder-proto/commit/80152dc98155da4eb046d9f67a87ed96e8280a1d) +- Only apps should have lockfiles [`03e6660`](https://github.com/es-shims/dunder-proto/commit/03e6660a1d70dc401f3e217a031475ec537243dd) diff --git a/3-asynchronous-JS/node_modules/dunder-proto/LICENSE b/3-asynchronous-JS/node_modules/dunder-proto/LICENSE new file mode 100644 index 0000000000..34995e79d1 --- /dev/null +++ b/3-asynchronous-JS/node_modules/dunder-proto/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 ECMAScript Shims + +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/3-asynchronous-JS/node_modules/dunder-proto/README.md b/3-asynchronous-JS/node_modules/dunder-proto/README.md new file mode 100644 index 0000000000..44b80a2d4f --- /dev/null +++ b/3-asynchronous-JS/node_modules/dunder-proto/README.md @@ -0,0 +1,54 @@ +# dunder-proto [![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] + +[![npm badge][npm-badge-png]][package-url] + +If available, the `Object.prototype.__proto__` accessor and mutator, call-bound. + +## Getting started + +```sh +npm install --save dunder-proto +``` + +## Usage/Examples + +```js +const assert = require('assert'); +const getDunder = require('dunder-proto/get'); +const setDunder = require('dunder-proto/set'); + +const obj = {}; + +assert.equal('toString' in obj, true); +assert.equal(getDunder(obj), Object.prototype); + +setDunder(obj, null); + +assert.equal('toString' in obj, false); +assert.equal(getDunder(obj), null); +``` + +## Tests + +Clone the repo, `npm install`, and run `npm test` + +[package-url]: https://npmjs.org/package/dunder-proto +[npm-version-svg]: https://versionbadg.es/es-shims/dunder-proto.svg +[deps-svg]: https://david-dm.org/es-shims/dunder-proto.svg +[deps-url]: https://david-dm.org/es-shims/dunder-proto +[dev-deps-svg]: https://david-dm.org/es-shims/dunder-proto/dev-status.svg +[dev-deps-url]: https://david-dm.org/es-shims/dunder-proto#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/dunder-proto.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/dunder-proto.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/dunder-proto.svg +[downloads-url]: https://npm-stat.com/charts.html?package=dunder-proto +[codecov-image]: https://codecov.io/gh/es-shims/dunder-proto/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/es-shims/dunder-proto/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/es-shims/dunder-proto +[actions-url]: https://github.com/es-shims/dunder-proto/actions diff --git a/3-asynchronous-JS/node_modules/dunder-proto/get.d.ts b/3-asynchronous-JS/node_modules/dunder-proto/get.d.ts new file mode 100644 index 0000000000..c7e14d25e5 --- /dev/null +++ b/3-asynchronous-JS/node_modules/dunder-proto/get.d.ts @@ -0,0 +1,5 @@ +declare function getDunderProto(target: {}): object | null; + +declare const x: false | typeof getDunderProto; + +export = x; \ No newline at end of file diff --git a/3-asynchronous-JS/node_modules/dunder-proto/get.js b/3-asynchronous-JS/node_modules/dunder-proto/get.js new file mode 100644 index 0000000000..45093df984 --- /dev/null +++ b/3-asynchronous-JS/node_modules/dunder-proto/get.js @@ -0,0 +1,30 @@ +'use strict'; + +var callBind = require('call-bind-apply-helpers'); +var gOPD = require('gopd'); + +var hasProtoAccessor; +try { + // eslint-disable-next-line no-extra-parens, no-proto + hasProtoAccessor = /** @type {{ __proto__?: typeof Array.prototype }} */ ([]).__proto__ === Array.prototype; +} catch (e) { + if (!e || typeof e !== 'object' || !('code' in e) || e.code !== 'ERR_PROTO_ACCESS') { + throw e; + } +} + +// eslint-disable-next-line no-extra-parens +var desc = !!hasProtoAccessor && gOPD && gOPD(Object.prototype, /** @type {keyof typeof Object.prototype} */ ('__proto__')); + +var $Object = Object; +var $getPrototypeOf = $Object.getPrototypeOf; + +/** @type {import('./get')} */ +module.exports = desc && typeof desc.get === 'function' + ? callBind([desc.get]) + : typeof $getPrototypeOf === 'function' + ? /** @type {import('./get')} */ function getDunder(value) { + // eslint-disable-next-line eqeqeq + return $getPrototypeOf(value == null ? value : $Object(value)); + } + : false; diff --git a/3-asynchronous-JS/node_modules/dunder-proto/package.json b/3-asynchronous-JS/node_modules/dunder-proto/package.json new file mode 100644 index 0000000000..04a4036775 --- /dev/null +++ b/3-asynchronous-JS/node_modules/dunder-proto/package.json @@ -0,0 +1,76 @@ +{ + "name": "dunder-proto", + "version": "1.0.1", + "description": "If available, the `Object.prototype.__proto__` accessor and mutator, call-bound", + "main": false, + "exports": { + "./get": "./get.js", + "./set": "./set.js", + "./package.json": "./package.json" + }, + "sideEffects": false, + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "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/es-shims/dunder-proto.git" + }, + "author": "Jordan Harband ", + "license": "MIT", + "bugs": { + "url": "https://github.com/es-shims/dunder-proto/issues" + }, + "homepage": "https://github.com/es-shims/dunder-proto#readme", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "devDependencies": { + "@arethetypeswrong/cli": "^0.17.1", + "@ljharb/eslint-config": "^21.1.1", + "@ljharb/tsconfig": "^0.2.2", + "@types/tape": "^5.7.0", + "auto-changelog": "^2.5.0", + "encoding": "^0.1.13", + "eslint": "=8.8.0", + "evalmd": "^0.0.19", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.9.0", + "typescript": "next" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "testling": { + "files": "test/index.js" + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + }, + "engines": { + "node": ">= 0.4" + } +} diff --git a/3-asynchronous-JS/node_modules/dunder-proto/set.d.ts b/3-asynchronous-JS/node_modules/dunder-proto/set.d.ts new file mode 100644 index 0000000000..16bfdfe2bb --- /dev/null +++ b/3-asynchronous-JS/node_modules/dunder-proto/set.d.ts @@ -0,0 +1,5 @@ +declare function setDunderProto

(target: {}, proto: P): P; + +declare const x: false | typeof setDunderProto; + +export = x; \ No newline at end of file diff --git a/3-asynchronous-JS/node_modules/dunder-proto/set.js b/3-asynchronous-JS/node_modules/dunder-proto/set.js new file mode 100644 index 0000000000..6085b6e84d --- /dev/null +++ b/3-asynchronous-JS/node_modules/dunder-proto/set.js @@ -0,0 +1,35 @@ +'use strict'; + +var callBind = require('call-bind-apply-helpers'); +var gOPD = require('gopd'); +var $TypeError = require('es-errors/type'); + +/** @type {{ __proto__?: object | null }} */ +var obj = {}; +try { + obj.__proto__ = null; // eslint-disable-line no-proto +} catch (e) { + if (!e || typeof e !== 'object' || !('code' in e) || e.code !== 'ERR_PROTO_ACCESS') { + throw e; + } +} + +var hasProtoMutator = !('toString' in obj); + +// eslint-disable-next-line no-extra-parens +var desc = gOPD && gOPD(Object.prototype, /** @type {keyof typeof Object.prototype} */ ('__proto__')); + +/** @type {import('./set')} */ +module.exports = hasProtoMutator && ( +// eslint-disable-next-line no-extra-parens + (!!desc && typeof desc.set === 'function' && /** @type {import('./set')} */ (callBind([desc.set]))) + || /** @type {import('./set')} */ function setDunder(object, proto) { + // this is node v0.10 or older, which doesn't have Object.setPrototypeOf and has undeniable __proto__ + if (object == null) { // eslint-disable-line eqeqeq + throw new $TypeError('set Object.prototype.__proto__ called on null or undefined'); + } + // eslint-disable-next-line no-proto, no-param-reassign, no-extra-parens + /** @type {{ __proto__?: object | null }} */ (object).__proto__ = proto; + return proto; + } +); diff --git a/3-asynchronous-JS/node_modules/dunder-proto/test/get.js b/3-asynchronous-JS/node_modules/dunder-proto/test/get.js new file mode 100644 index 0000000000..253f1838ef --- /dev/null +++ b/3-asynchronous-JS/node_modules/dunder-proto/test/get.js @@ -0,0 +1,34 @@ +'use strict'; + +var test = require('tape'); + +var getDunderProto = require('../get'); + +test('getDunderProto', { skip: !getDunderProto }, function (t) { + if (!getDunderProto) { + throw 'should never happen; this is just for type narrowing'; // eslint-disable-line no-throw-literal + } + + // @ts-expect-error + t['throws'](function () { getDunderProto(); }, TypeError, 'throws if no argument'); + // @ts-expect-error + t['throws'](function () { getDunderProto(undefined); }, TypeError, 'throws with undefined'); + // @ts-expect-error + t['throws'](function () { getDunderProto(null); }, TypeError, 'throws with null'); + + t.equal(getDunderProto({}), Object.prototype); + t.equal(getDunderProto([]), Array.prototype); + t.equal(getDunderProto(function () {}), Function.prototype); + t.equal(getDunderProto(/./g), RegExp.prototype); + t.equal(getDunderProto(42), Number.prototype); + t.equal(getDunderProto(true), Boolean.prototype); + t.equal(getDunderProto('foo'), String.prototype); + + t.end(); +}); + +test('no dunder proto', { skip: !!getDunderProto }, function (t) { + t.notOk('__proto__' in Object.prototype, 'no __proto__ in Object.prototype'); + + t.end(); +}); diff --git a/3-asynchronous-JS/node_modules/dunder-proto/test/index.js b/3-asynchronous-JS/node_modules/dunder-proto/test/index.js new file mode 100644 index 0000000000..08ff36f7dc --- /dev/null +++ b/3-asynchronous-JS/node_modules/dunder-proto/test/index.js @@ -0,0 +1,4 @@ +'use strict'; + +require('./get'); +require('./set'); diff --git a/3-asynchronous-JS/node_modules/dunder-proto/test/set.js b/3-asynchronous-JS/node_modules/dunder-proto/test/set.js new file mode 100644 index 0000000000..c3bfe4d4fe --- /dev/null +++ b/3-asynchronous-JS/node_modules/dunder-proto/test/set.js @@ -0,0 +1,50 @@ +'use strict'; + +var test = require('tape'); + +var setDunderProto = require('../set'); + +test('setDunderProto', { skip: !setDunderProto }, function (t) { + if (!setDunderProto) { + throw 'should never happen; this is just for type narrowing'; // eslint-disable-line no-throw-literal + } + + // @ts-expect-error + t['throws'](function () { setDunderProto(); }, TypeError, 'throws if no arguments'); + // @ts-expect-error + t['throws'](function () { setDunderProto(undefined); }, TypeError, 'throws with undefined and nothing'); + // @ts-expect-error + t['throws'](function () { setDunderProto(undefined, undefined); }, TypeError, 'throws with undefined and undefined'); + // @ts-expect-error + t['throws'](function () { setDunderProto(null); }, TypeError, 'throws with null and undefined'); + // @ts-expect-error + t['throws'](function () { setDunderProto(null, undefined); }, TypeError, 'throws with null and undefined'); + + /** @type {{ inherited?: boolean }} */ + var obj = {}; + t.ok('toString' in obj, 'object initially has toString'); + + setDunderProto(obj, null); + t.notOk('toString' in obj, 'object no longer has toString'); + + t.notOk('inherited' in obj, 'object lacks inherited property'); + setDunderProto(obj, { inherited: true }); + t.equal(obj.inherited, true, 'object has inherited property'); + + t.end(); +}); + +test('no dunder proto', { skip: !!setDunderProto }, function (t) { + if ('__proto__' in Object.prototype) { + t['throws']( + // @ts-expect-error + function () { ({}).__proto__ = null; }, // eslint-disable-line no-proto + Error, + 'throws when setting Object.prototype.__proto__' + ); + } else { + t.notOk('__proto__' in Object.prototype, 'no __proto__ in Object.prototype'); + } + + t.end(); +}); diff --git a/3-asynchronous-JS/node_modules/dunder-proto/tsconfig.json b/3-asynchronous-JS/node_modules/dunder-proto/tsconfig.json new file mode 100644 index 0000000000..dabbe230d7 --- /dev/null +++ b/3-asynchronous-JS/node_modules/dunder-proto/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + "target": "ES2021", + }, + "exclude": [ + "coverage", + ], +} diff --git a/3-asynchronous-JS/node_modules/es-define-property/.eslintrc b/3-asynchronous-JS/node_modules/es-define-property/.eslintrc new file mode 100644 index 0000000000..46f3b120b8 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-define-property/.eslintrc @@ -0,0 +1,13 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "new-cap": ["error", { + "capIsNewExceptions": [ + "GetIntrinsic", + ], + }], + }, +} diff --git a/3-asynchronous-JS/node_modules/es-define-property/.github/FUNDING.yml b/3-asynchronous-JS/node_modules/es-define-property/.github/FUNDING.yml new file mode 100644 index 0000000000..4445451fbe --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-define-property/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# 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/es-define-property +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/3-asynchronous-JS/node_modules/es-define-property/.nycrc b/3-asynchronous-JS/node_modules/es-define-property/.nycrc new file mode 100644 index 0000000000..bdd626ce91 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-define-property/.nycrc @@ -0,0 +1,9 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "exclude": [ + "coverage", + "test" + ] +} diff --git a/3-asynchronous-JS/node_modules/es-define-property/CHANGELOG.md b/3-asynchronous-JS/node_modules/es-define-property/CHANGELOG.md new file mode 100644 index 0000000000..5f60cc0992 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-define-property/CHANGELOG.md @@ -0,0 +1,29 @@ +# 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.1](https://github.com/ljharb/es-define-property/compare/v1.0.0...v1.0.1) - 2024-12-06 + +### Commits + +- [types] use shared tsconfig [`954a663`](https://github.com/ljharb/es-define-property/commit/954a66360326e508a0e5daa4b07493d58f5e110e) +- [actions] split out node 10-20, and 20+ [`3a8e84b`](https://github.com/ljharb/es-define-property/commit/3a8e84b23883f26ff37b3e82ff283834228e18c6) +- [Dev Deps] update `@ljharb/eslint-config`, `@ljharb/tsconfig`, `@types/get-intrinsic`, `@types/tape`, `auto-changelog`, `gopd`, `tape` [`86ae27b`](https://github.com/ljharb/es-define-property/commit/86ae27bb8cc857b23885136fad9cbe965ae36612) +- [Refactor] avoid using `get-intrinsic` [`02480c0`](https://github.com/ljharb/es-define-property/commit/02480c0353ef6118965282977c3864aff53d98b1) +- [Tests] replace `aud` with `npm audit` [`f6093ff`](https://github.com/ljharb/es-define-property/commit/f6093ff74ab51c98015c2592cd393bd42478e773) +- [Tests] configure testling [`7139e66`](https://github.com/ljharb/es-define-property/commit/7139e66959247a56086d9977359caef27c6849e7) +- [Dev Deps] update `tape` [`b901b51`](https://github.com/ljharb/es-define-property/commit/b901b511a75e001a40ce1a59fef7d9ffcfc87482) +- [Tests] fix types in tests [`469d269`](https://github.com/ljharb/es-define-property/commit/469d269fd141b1e773ec053a9fa35843493583e0) +- [Dev Deps] add missing peer dep [`733acfb`](https://github.com/ljharb/es-define-property/commit/733acfb0c4c96edf337e470b89a25a5b3724c352) + +## v1.0.0 - 2024-02-12 + +### Commits + +- Initial implementation, tests, readme, types [`3e154e1`](https://github.com/ljharb/es-define-property/commit/3e154e11a2fee09127220f5e503bf2c0a31dd480) +- Initial commit [`07d98de`](https://github.com/ljharb/es-define-property/commit/07d98de34a4dc31ff5e83a37c0c3f49e0d85cd50) +- npm init [`c4eb634`](https://github.com/ljharb/es-define-property/commit/c4eb6348b0d3886aac36cef34ad2ee0665ea6f3e) +- Only apps should have lockfiles [`7af86ec`](https://github.com/ljharb/es-define-property/commit/7af86ec1d311ec0b17fdfe616a25f64276903856) diff --git a/3-asynchronous-JS/node_modules/es-define-property/LICENSE b/3-asynchronous-JS/node_modules/es-define-property/LICENSE new file mode 100644 index 0000000000..f82f38963b --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-define-property/LICENSE @@ -0,0 +1,21 @@ +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/3-asynchronous-JS/node_modules/es-define-property/README.md b/3-asynchronous-JS/node_modules/es-define-property/README.md new file mode 100644 index 0000000000..9b291bddb2 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-define-property/README.md @@ -0,0 +1,49 @@ +# es-define-property [![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] + +[![npm badge][npm-badge-png]][package-url] + +`Object.defineProperty`, but not IE 8's broken one. + +## Example + +```js +const assert = require('assert'); + +const $defineProperty = require('es-define-property'); + +if ($defineProperty) { + assert.equal($defineProperty, Object.defineProperty); +} else if (Object.defineProperty) { + assert.equal($defineProperty, false, 'this is IE 8'); +} else { + assert.equal($defineProperty, false, 'this is an ES3 engine'); +} +``` + +## Tests +Simply clone the repo, `npm install`, and run `npm test` + +## Security + +Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report. + +[package-url]: https://npmjs.org/package/es-define-property +[npm-version-svg]: https://versionbadg.es/ljharb/es-define-property.svg +[deps-svg]: https://david-dm.org/ljharb/es-define-property.svg +[deps-url]: https://david-dm.org/ljharb/es-define-property +[dev-deps-svg]: https://david-dm.org/ljharb/es-define-property/dev-status.svg +[dev-deps-url]: https://david-dm.org/ljharb/es-define-property#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/es-define-property.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/es-define-property.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/es-define-property.svg +[downloads-url]: https://npm-stat.com/charts.html?package=es-define-property +[codecov-image]: https://codecov.io/gh/ljharb/es-define-property/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/ljharb/es-define-property/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/es-define-property +[actions-url]: https://github.com/ljharb/es-define-property/actions diff --git a/3-asynchronous-JS/node_modules/es-define-property/index.d.ts b/3-asynchronous-JS/node_modules/es-define-property/index.d.ts new file mode 100644 index 0000000000..6012247c46 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-define-property/index.d.ts @@ -0,0 +1,3 @@ +declare const defineProperty: false | typeof Object.defineProperty; + +export = defineProperty; \ No newline at end of file diff --git a/3-asynchronous-JS/node_modules/es-define-property/index.js b/3-asynchronous-JS/node_modules/es-define-property/index.js new file mode 100644 index 0000000000..e0a2925164 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-define-property/index.js @@ -0,0 +1,14 @@ +'use strict'; + +/** @type {import('.')} */ +var $defineProperty = Object.defineProperty || false; +if ($defineProperty) { + try { + $defineProperty({}, 'a', { value: 1 }); + } catch (e) { + // IE 8 has a broken defineProperty + $defineProperty = false; + } +} + +module.exports = $defineProperty; diff --git a/3-asynchronous-JS/node_modules/es-define-property/package.json b/3-asynchronous-JS/node_modules/es-define-property/package.json new file mode 100644 index 0000000000..fbed187879 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-define-property/package.json @@ -0,0 +1,81 @@ +{ + "name": "es-define-property", + "version": "1.0.1", + "description": "`Object.defineProperty`, but not IE 8's broken one.", + "main": "index.js", + "types": "./index.d.ts", + "exports": { + ".": "./index.js", + "./package.json": "./package.json" + }, + "sideEffects": false, + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublish": "not-in-publish || npm run prepublishOnly", + "prepublishOnly": "safe-publish-latest", + "prelint": "evalmd README.md", + "lint": "eslint --ext=js,mjs .", + "postlint": "tsc -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/es-define-property.git" + }, + "keywords": [ + "javascript", + "ecmascript", + "object", + "define", + "property", + "defineProperty", + "Object.defineProperty" + ], + "author": "Jordan Harband ", + "license": "MIT", + "bugs": { + "url": "https://github.com/ljharb/es-define-property/issues" + }, + "homepage": "https://github.com/ljharb/es-define-property#readme", + "devDependencies": { + "@ljharb/eslint-config": "^21.1.1", + "@ljharb/tsconfig": "^0.2.2", + "@types/gopd": "^1.0.3", + "@types/tape": "^5.6.5", + "auto-changelog": "^2.5.0", + "encoding": "^0.1.13", + "eslint": "^8.8.0", + "evalmd": "^0.0.19", + "gopd": "^1.2.0", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.9.0", + "typescript": "next" + }, + "engines": { + "node": ">= 0.4" + }, + "testling": { + "files": "test/index.js" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + } +} diff --git a/3-asynchronous-JS/node_modules/es-define-property/test/index.js b/3-asynchronous-JS/node_modules/es-define-property/test/index.js new file mode 100644 index 0000000000..b4b4688fbe --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-define-property/test/index.js @@ -0,0 +1,56 @@ +'use strict'; + +var $defineProperty = require('../'); + +var test = require('tape'); +var gOPD = require('gopd'); + +test('defineProperty: supported', { skip: !$defineProperty }, function (t) { + t.plan(4); + + t.equal(typeof $defineProperty, 'function', 'defineProperty is supported'); + if ($defineProperty && gOPD) { // this `if` check is just to shut TS up + /** @type {{ a: number, b?: number, c?: number }} */ + var o = { a: 1 }; + + $defineProperty(o, 'b', { enumerable: true, value: 2 }); + t.deepEqual( + gOPD(o, 'b'), + { + configurable: false, + enumerable: true, + value: 2, + writable: false + }, + 'property descriptor is as expected' + ); + + $defineProperty(o, 'c', { enumerable: false, value: 3, writable: true }); + t.deepEqual( + gOPD(o, 'c'), + { + configurable: false, + enumerable: false, + value: 3, + writable: true + }, + 'property descriptor is as expected' + ); + } + + t.equal($defineProperty, Object.defineProperty, 'defineProperty is Object.defineProperty'); + + t.end(); +}); + +test('defineProperty: not supported', { skip: !!$defineProperty }, function (t) { + t.notOk($defineProperty, 'defineProperty is not supported'); + + t.match( + typeof $defineProperty, + /^(?:undefined|boolean)$/, + '`typeof defineProperty` is `undefined` or `boolean`' + ); + + t.end(); +}); diff --git a/3-asynchronous-JS/node_modules/es-define-property/tsconfig.json b/3-asynchronous-JS/node_modules/es-define-property/tsconfig.json new file mode 100644 index 0000000000..5a49992eaf --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-define-property/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + "target": "es2022", + }, + "exclude": [ + "coverage", + "test/list-exports" + ], +} diff --git a/3-asynchronous-JS/node_modules/es-errors/.eslintrc b/3-asynchronous-JS/node_modules/es-errors/.eslintrc new file mode 100644 index 0000000000..3b5d9e90ec --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/.eslintrc @@ -0,0 +1,5 @@ +{ + "root": true, + + "extends": "@ljharb", +} diff --git a/3-asynchronous-JS/node_modules/es-errors/.github/FUNDING.yml b/3-asynchronous-JS/node_modules/es-errors/.github/FUNDING.yml new file mode 100644 index 0000000000..f1b880554a --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# 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/es-errors +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/3-asynchronous-JS/node_modules/es-errors/CHANGELOG.md b/3-asynchronous-JS/node_modules/es-errors/CHANGELOG.md new file mode 100644 index 0000000000..204a9e904b --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/CHANGELOG.md @@ -0,0 +1,40 @@ +# 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.3.0](https://github.com/ljharb/es-errors/compare/v1.2.1...v1.3.0) - 2024-02-05 + +### Commits + +- [New] add `EvalError` and `URIError` [`1927627`](https://github.com/ljharb/es-errors/commit/1927627ba68cb6c829d307231376c967db53acdf) + +## [v1.2.1](https://github.com/ljharb/es-errors/compare/v1.2.0...v1.2.1) - 2024-02-04 + +### Commits + +- [Fix] add missing `exports` entry [`5bb5f28`](https://github.com/ljharb/es-errors/commit/5bb5f280f98922701109d6ebb82eea2257cecc7e) + +## [v1.2.0](https://github.com/ljharb/es-errors/compare/v1.1.0...v1.2.0) - 2024-02-04 + +### Commits + +- [New] add `ReferenceError` [`6d8cf5b`](https://github.com/ljharb/es-errors/commit/6d8cf5bbb6f3f598d02cf6f30e468ba2caa8e143) + +## [v1.1.0](https://github.com/ljharb/es-errors/compare/v1.0.0...v1.1.0) - 2024-02-04 + +### Commits + +- [New] add base Error [`2983ab6`](https://github.com/ljharb/es-errors/commit/2983ab65f7bc5441276cb021dc3aa03c78881698) + +## v1.0.0 - 2024-02-03 + +### Commits + +- Initial implementation, tests, readme, type [`8f47631`](https://github.com/ljharb/es-errors/commit/8f476317e9ad76f40ad648081829b1a1a3a1288b) +- Initial commit [`ea5d099`](https://github.com/ljharb/es-errors/commit/ea5d099ef18e550509ab9e2be000526afd81c385) +- npm init [`6f5ebf9`](https://github.com/ljharb/es-errors/commit/6f5ebf9cead474dadd72b9e63dad315820a089ae) +- Only apps should have lockfiles [`e1a0aeb`](https://github.com/ljharb/es-errors/commit/e1a0aeb7b80f5cfc56be54d6b2100e915d47def8) +- [meta] add `sideEffects` flag [`a9c7d46`](https://github.com/ljharb/es-errors/commit/a9c7d460a492f1d8a241c836bc25a322a19cc043) diff --git a/3-asynchronous-JS/node_modules/es-errors/LICENSE b/3-asynchronous-JS/node_modules/es-errors/LICENSE new file mode 100644 index 0000000000..f82f38963b --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/LICENSE @@ -0,0 +1,21 @@ +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/3-asynchronous-JS/node_modules/es-errors/README.md b/3-asynchronous-JS/node_modules/es-errors/README.md new file mode 100644 index 0000000000..8dbfacfea7 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/README.md @@ -0,0 +1,55 @@ +# es-errors [![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] + +[![npm badge][npm-badge-png]][package-url] + +A simple cache for a few of the JS Error constructors. + +## Example + +```js +const assert = require('assert'); + +const Base = require('es-errors'); +const Eval = require('es-errors/eval'); +const Range = require('es-errors/range'); +const Ref = require('es-errors/ref'); +const Syntax = require('es-errors/syntax'); +const Type = require('es-errors/type'); +const URI = require('es-errors/uri'); + +assert.equal(Base, Error); +assert.equal(Eval, EvalError); +assert.equal(Range, RangeError); +assert.equal(Ref, ReferenceError); +assert.equal(Syntax, SyntaxError); +assert.equal(Type, TypeError); +assert.equal(URI, URIError); +``` + +## Tests +Simply clone the repo, `npm install`, and run `npm test` + +## Security + +Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report. + +[package-url]: https://npmjs.org/package/es-errors +[npm-version-svg]: https://versionbadg.es/ljharb/es-errors.svg +[deps-svg]: https://david-dm.org/ljharb/es-errors.svg +[deps-url]: https://david-dm.org/ljharb/es-errors +[dev-deps-svg]: https://david-dm.org/ljharb/es-errors/dev-status.svg +[dev-deps-url]: https://david-dm.org/ljharb/es-errors#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/es-errors.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/es-errors.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/es-errors.svg +[downloads-url]: https://npm-stat.com/charts.html?package=es-errors +[codecov-image]: https://codecov.io/gh/ljharb/es-errors/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/ljharb/es-errors/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/es-errors +[actions-url]: https://github.com/ljharb/es-errors/actions diff --git a/3-asynchronous-JS/node_modules/es-errors/eval.d.ts b/3-asynchronous-JS/node_modules/es-errors/eval.d.ts new file mode 100644 index 0000000000..e4210e01ea --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/eval.d.ts @@ -0,0 +1,3 @@ +declare const EvalError: EvalErrorConstructor; + +export = EvalError; diff --git a/3-asynchronous-JS/node_modules/es-errors/eval.js b/3-asynchronous-JS/node_modules/es-errors/eval.js new file mode 100644 index 0000000000..725ccb61a9 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/eval.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./eval')} */ +module.exports = EvalError; diff --git a/3-asynchronous-JS/node_modules/es-errors/index.d.ts b/3-asynchronous-JS/node_modules/es-errors/index.d.ts new file mode 100644 index 0000000000..69bdbc92ee --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/index.d.ts @@ -0,0 +1,3 @@ +declare const Error: ErrorConstructor; + +export = Error; diff --git a/3-asynchronous-JS/node_modules/es-errors/index.js b/3-asynchronous-JS/node_modules/es-errors/index.js new file mode 100644 index 0000000000..cc0c52124b --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/index.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('.')} */ +module.exports = Error; diff --git a/3-asynchronous-JS/node_modules/es-errors/package.json b/3-asynchronous-JS/node_modules/es-errors/package.json new file mode 100644 index 0000000000..ff8c2a531b --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/package.json @@ -0,0 +1,80 @@ +{ + "name": "es-errors", + "version": "1.3.0", + "description": "A simple cache for a few of the JS Error constructors.", + "main": "index.js", + "exports": { + ".": "./index.js", + "./eval": "./eval.js", + "./range": "./range.js", + "./ref": "./ref.js", + "./syntax": "./syntax.js", + "./type": "./type.js", + "./uri": "./uri.js", + "./package.json": "./package.json" + }, + "sideEffects": false, + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublishOnly": "safe-publish-latest", + "prepublish": "not-in-publish || npm run prepublishOnly", + "pretest": "npm run lint", + "test": "npm run tests-only", + "tests-only": "nyc tape 'test/**/*.js'", + "posttest": "aud --production", + "prelint": "evalmd README.md", + "lint": "eslint --ext=js,mjs .", + "postlint": "tsc -p . && eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git' | grep -v dist/)", + "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/es-errors.git" + }, + "keywords": [ + "javascript", + "ecmascript", + "error", + "typeerror", + "syntaxerror", + "rangeerror" + ], + "author": "Jordan Harband ", + "license": "MIT", + "bugs": { + "url": "https://github.com/ljharb/es-errors/issues" + }, + "homepage": "https://github.com/ljharb/es-errors#readme", + "devDependencies": { + "@ljharb/eslint-config": "^21.1.0", + "@types/tape": "^5.6.4", + "aud": "^2.0.4", + "auto-changelog": "^2.4.0", + "eclint": "^2.8.1", + "eslint": "^8.8.0", + "evalmd": "^0.0.19", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.7.4", + "typescript": "next" + }, + "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/3-asynchronous-JS/node_modules/es-errors/range.d.ts b/3-asynchronous-JS/node_modules/es-errors/range.d.ts new file mode 100644 index 0000000000..3a12e86426 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/range.d.ts @@ -0,0 +1,3 @@ +declare const RangeError: RangeErrorConstructor; + +export = RangeError; diff --git a/3-asynchronous-JS/node_modules/es-errors/range.js b/3-asynchronous-JS/node_modules/es-errors/range.js new file mode 100644 index 0000000000..2044fe0364 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/range.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./range')} */ +module.exports = RangeError; diff --git a/3-asynchronous-JS/node_modules/es-errors/ref.d.ts b/3-asynchronous-JS/node_modules/es-errors/ref.d.ts new file mode 100644 index 0000000000..a13107e249 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/ref.d.ts @@ -0,0 +1,3 @@ +declare const ReferenceError: ReferenceErrorConstructor; + +export = ReferenceError; diff --git a/3-asynchronous-JS/node_modules/es-errors/ref.js b/3-asynchronous-JS/node_modules/es-errors/ref.js new file mode 100644 index 0000000000..d7c430fdb3 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/ref.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./ref')} */ +module.exports = ReferenceError; diff --git a/3-asynchronous-JS/node_modules/es-errors/syntax.d.ts b/3-asynchronous-JS/node_modules/es-errors/syntax.d.ts new file mode 100644 index 0000000000..6a0c53c5b9 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/syntax.d.ts @@ -0,0 +1,3 @@ +declare const SyntaxError: SyntaxErrorConstructor; + +export = SyntaxError; diff --git a/3-asynchronous-JS/node_modules/es-errors/syntax.js b/3-asynchronous-JS/node_modules/es-errors/syntax.js new file mode 100644 index 0000000000..5f5fddeec5 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/syntax.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./syntax')} */ +module.exports = SyntaxError; diff --git a/3-asynchronous-JS/node_modules/es-errors/test/index.js b/3-asynchronous-JS/node_modules/es-errors/test/index.js new file mode 100644 index 0000000000..1ff027721a --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/test/index.js @@ -0,0 +1,19 @@ +'use strict'; + +var test = require('tape'); + +var E = require('../'); +var R = require('../range'); +var Ref = require('../ref'); +var S = require('../syntax'); +var T = require('../type'); + +test('errors', function (t) { + t.equal(E, Error); + t.equal(R, RangeError); + t.equal(Ref, ReferenceError); + t.equal(S, SyntaxError); + t.equal(T, TypeError); + + t.end(); +}); diff --git a/3-asynchronous-JS/node_modules/es-errors/tsconfig.json b/3-asynchronous-JS/node_modules/es-errors/tsconfig.json new file mode 100644 index 0000000000..99dfeb6c80 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/tsconfig.json @@ -0,0 +1,49 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Projects */ + + /* Language and Environment */ + "target": "es5", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": ["types"], /* Specify multiple folders that act like `./node_modules/@types`. */ + "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + + /* JavaScript Support */ + "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ + "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ + + /* Emit */ + "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + "declarationMap": true, /* Create sourcemaps for d.ts files. */ + "noEmit": true, /* Disable emitting files from a compilation. */ + + /* Interop Constraints */ + "allowSyntheticDefaultImports": true, /* Allow `import x from y` when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + + /* Completeness */ + // "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "exclude": [ + "coverage", + ], +} diff --git a/3-asynchronous-JS/node_modules/es-errors/type.d.ts b/3-asynchronous-JS/node_modules/es-errors/type.d.ts new file mode 100644 index 0000000000..576fb51617 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/type.d.ts @@ -0,0 +1,3 @@ +declare const TypeError: TypeErrorConstructor + +export = TypeError; diff --git a/3-asynchronous-JS/node_modules/es-errors/type.js b/3-asynchronous-JS/node_modules/es-errors/type.js new file mode 100644 index 0000000000..9769e44e39 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/type.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./type')} */ +module.exports = TypeError; diff --git a/3-asynchronous-JS/node_modules/es-errors/uri.d.ts b/3-asynchronous-JS/node_modules/es-errors/uri.d.ts new file mode 100644 index 0000000000..c3261c91e0 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/uri.d.ts @@ -0,0 +1,3 @@ +declare const URIError: URIErrorConstructor; + +export = URIError; diff --git a/3-asynchronous-JS/node_modules/es-errors/uri.js b/3-asynchronous-JS/node_modules/es-errors/uri.js new file mode 100644 index 0000000000..e9cd1c7870 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-errors/uri.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./uri')} */ +module.exports = URIError; diff --git a/3-asynchronous-JS/node_modules/es-object-atoms/.eslintrc b/3-asynchronous-JS/node_modules/es-object-atoms/.eslintrc new file mode 100644 index 0000000000..d90a1bc657 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-object-atoms/.eslintrc @@ -0,0 +1,16 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "eqeqeq": ["error", "allow-null"], + "id-length": "off", + "new-cap": ["error", { + "capIsNewExceptions": [ + "RequireObjectCoercible", + "ToObject", + ], + }], + }, +} diff --git a/3-asynchronous-JS/node_modules/es-object-atoms/.github/FUNDING.yml b/3-asynchronous-JS/node_modules/es-object-atoms/.github/FUNDING.yml new file mode 100644 index 0000000000..352bfdabd2 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-object-atoms/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# 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/es-object +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/3-asynchronous-JS/node_modules/es-object-atoms/CHANGELOG.md b/3-asynchronous-JS/node_modules/es-object-atoms/CHANGELOG.md new file mode 100644 index 0000000000..ac141be39f --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-object-atoms/CHANGELOG.md @@ -0,0 +1,16 @@ +# 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.0 - 2024-03-16 + +### Commits + +- Initial implementation, tests, readme, types [`f1499db`](https://github.com/ljharb/es-object-atoms/commit/f1499db7d3e1741e64979c61d645ab3137705e82) +- Initial commit [`99eedc7`](https://github.com/ljharb/es-object-atoms/commit/99eedc7b5fde38a50a28d3c8b724706e3e4c5f6a) +- [meta] rename repo [`fc851fa`](https://github.com/ljharb/es-object-atoms/commit/fc851fa70616d2d182aaf0bd02c2ed7084dea8fa) +- npm init [`b909377`](https://github.com/ljharb/es-object-atoms/commit/b909377c50049bd0ec575562d20b0f9ebae8947f) +- Only apps should have lockfiles [`7249edd`](https://github.com/ljharb/es-object-atoms/commit/7249edd2178c1b9ddfc66ffcc6d07fdf0d28efc1) diff --git a/3-asynchronous-JS/node_modules/es-object-atoms/LICENSE b/3-asynchronous-JS/node_modules/es-object-atoms/LICENSE new file mode 100644 index 0000000000..f82f38963b --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-object-atoms/LICENSE @@ -0,0 +1,21 @@ +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/3-asynchronous-JS/node_modules/es-object-atoms/README.md b/3-asynchronous-JS/node_modules/es-object-atoms/README.md new file mode 100644 index 0000000000..ed30025a9c --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-object-atoms/README.md @@ -0,0 +1,56 @@ +# es-object-atoms [![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] + +[![npm badge][npm-badge-png]][package-url] + +ES Object-related atoms: Object, ToObject, RequireObjectCoercible. + +## Example + +```js +const assert = require('assert'); + +const $Object = require('es-object-atoms'); +const ToObject = require('es-object-atoms/ToObject'); +const RequireObjectCoercible = require('es-object-atoms/RequireObjectCoercible'); + +assert.equal($Object, Object); +assert.throws(() => ToObject(null), TypeError); +assert.throws(() => ToObject(undefined), TypeError); +assert.throws(() => RequireObjectCoercible(null), TypeError); +assert.throws(() => RequireObjectCoercible(undefined), TypeError); + +assert.deepEqual(RequireObjectCoercible(true), true); +assert.deepEqual(ToObject(true), Object(true)); + +const obj = {}; +assert.equal(RequireObjectCoercible(obj), obj); +assert.equal(ToObject(obj), obj); +``` + +## Tests +Simply clone the repo, `npm install`, and run `npm test` + +## Security + +Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report. + +[package-url]: https://npmjs.org/package/es-object-atoms +[npm-version-svg]: https://versionbadg.es/ljharb/es-object-atoms.svg +[deps-svg]: https://david-dm.org/ljharb/es-object-atoms.svg +[deps-url]: https://david-dm.org/ljharb/es-object-atoms +[dev-deps-svg]: https://david-dm.org/ljharb/es-object-atoms/dev-status.svg +[dev-deps-url]: https://david-dm.org/ljharb/es-object-atoms#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/es-object-atoms.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/es-object-atoms.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/es-object.svg +[downloads-url]: https://npm-stat.com/charts.html?package=es-object-atoms +[codecov-image]: https://codecov.io/gh/ljharb/es-object-atoms/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/ljharb/es-object-atoms/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/es-object-atoms +[actions-url]: https://github.com/ljharb/es-object-atoms/actions diff --git a/3-asynchronous-JS/node_modules/es-object-atoms/RequireObjectCoercible.d.ts b/3-asynchronous-JS/node_modules/es-object-atoms/RequireObjectCoercible.d.ts new file mode 100644 index 0000000000..f988390e49 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-object-atoms/RequireObjectCoercible.d.ts @@ -0,0 +1,3 @@ +declare function RequireObjectCoercible(value: T, optMessage?: string): T; + +export = RequireObjectCoercible; \ No newline at end of file diff --git a/3-asynchronous-JS/node_modules/es-object-atoms/RequireObjectCoercible.js b/3-asynchronous-JS/node_modules/es-object-atoms/RequireObjectCoercible.js new file mode 100644 index 0000000000..8e191c6ef1 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-object-atoms/RequireObjectCoercible.js @@ -0,0 +1,11 @@ +'use strict'; + +var $TypeError = require('es-errors/type'); + +/** @type {import('./RequireObjectCoercible')} */ +module.exports = function RequireObjectCoercible(value) { + if (value == null) { + throw new $TypeError((arguments.length > 0 && arguments[1]) || ('Cannot call method on ' + value)); + } + return value; +}; diff --git a/3-asynchronous-JS/node_modules/es-object-atoms/ToObject.d.ts b/3-asynchronous-JS/node_modules/es-object-atoms/ToObject.d.ts new file mode 100644 index 0000000000..32acea72b0 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-object-atoms/ToObject.d.ts @@ -0,0 +1,3 @@ +declare function ToObject(value: T extends object ? T : {}): T extends object ? T : object; + +export = ToObject; \ No newline at end of file diff --git a/3-asynchronous-JS/node_modules/es-object-atoms/ToObject.js b/3-asynchronous-JS/node_modules/es-object-atoms/ToObject.js new file mode 100644 index 0000000000..2b99a7da02 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-object-atoms/ToObject.js @@ -0,0 +1,10 @@ +'use strict'; + +var $Object = require('./'); +var RequireObjectCoercible = require('./RequireObjectCoercible'); + +/** @type {import('./ToObject')} */ +module.exports = function ToObject(value) { + RequireObjectCoercible(value); + return $Object(value); +}; diff --git a/3-asynchronous-JS/node_modules/es-object-atoms/index.d.ts b/3-asynchronous-JS/node_modules/es-object-atoms/index.d.ts new file mode 100644 index 0000000000..8bdbfc8154 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-object-atoms/index.d.ts @@ -0,0 +1,3 @@ +declare const Object: ObjectConstructor; + +export = Object; diff --git a/3-asynchronous-JS/node_modules/es-object-atoms/index.js b/3-asynchronous-JS/node_modules/es-object-atoms/index.js new file mode 100644 index 0000000000..1d33cef45a --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-object-atoms/index.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('.')} */ +module.exports = Object; diff --git a/3-asynchronous-JS/node_modules/es-object-atoms/package.json b/3-asynchronous-JS/node_modules/es-object-atoms/package.json new file mode 100644 index 0000000000..3f144c62ad --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-object-atoms/package.json @@ -0,0 +1,79 @@ +{ + "name": "es-object-atoms", + "version": "1.0.0", + "description": "ES Object-related atoms: Object, ToObject, RequireObjectCoercible", + "main": "index.js", + "exports": { + ".": "./index.js", + "./RequireObjectCoercible": "./RequireObjectCoercible.js", + "./ToObject": "./ToObject.js", + "./package.json": "./package.json" + }, + "sideEffects": false, + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublishOnly": "safe-publish-latest", + "prepublish": "not-in-publish || npm run prepublishOnly", + "pretest": "npm run lint", + "test": "npm run tests-only", + "tests-only": "nyc tape 'test/**/*.js'", + "posttest": "aud --production", + "prelint": "evalmd README.md", + "lint": "eslint --ext=js,mjs .", + "postlint": "tsc -p . && eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git' | grep -v dist/)", + "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/es-object-atoms.git" + }, + "keywords": [ + "javascript", + "ecmascript", + "object", + "toobject", + "coercible" + ], + "author": "Jordan Harband ", + "license": "MIT", + "bugs": { + "url": "https://github.com/ljharb/es-object-atoms/issues" + }, + "homepage": "https://github.com/ljharb/es-object-atoms#readme", + "dependencies": { + "es-errors": "^1.3.0" + }, + "devDependencies": { + "@ljharb/eslint-config": "^21.1.0", + "@ljharb/tsconfig": "^0.2.0", + "@types/tape": "^5.6.4", + "aud": "^2.0.4", + "auto-changelog": "^2.4.0", + "eclint": "^2.8.1", + "eslint": "^8.8.0", + "evalmd": "^0.0.19", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.7.5", + "typescript": "next" + }, + "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/3-asynchronous-JS/node_modules/es-object-atoms/test/index.js b/3-asynchronous-JS/node_modules/es-object-atoms/test/index.js new file mode 100644 index 0000000000..c3e412c602 --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-object-atoms/test/index.js @@ -0,0 +1,28 @@ +'use strict'; + +var test = require('tape'); + +var $Object = require('../'); +var ToObject = require('..//ToObject'); +var RequireObjectCoercible = require('..//RequireObjectCoercible'); + +test('errors', function (t) { + t.equal($Object, Object); + // @ts-expect-error + t['throws'](function () { ToObject(null); }, TypeError); + // @ts-expect-error + t['throws'](function () { ToObject(undefined); }, TypeError); + // @ts-expect-error + t['throws'](function () { RequireObjectCoercible(null); }, TypeError); + // @ts-expect-error + t['throws'](function () { RequireObjectCoercible(undefined); }, TypeError); + + t.deepEqual(RequireObjectCoercible(true), true); + t.deepEqual(ToObject(true), Object(true)); + + var obj = {}; + t.equal(RequireObjectCoercible(obj), obj); + t.equal(ToObject(obj), obj); + + t.end(); +}); diff --git a/3-asynchronous-JS/node_modules/es-object-atoms/tsconfig.json b/3-asynchronous-JS/node_modules/es-object-atoms/tsconfig.json new file mode 100644 index 0000000000..1f73cb725d --- /dev/null +++ b/3-asynchronous-JS/node_modules/es-object-atoms/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + "target": "es5", + }, +} diff --git a/3-asynchronous-JS/node_modules/fast-safe-stringify/.travis.yml b/3-asynchronous-JS/node_modules/fast-safe-stringify/.travis.yml new file mode 100644 index 0000000000..2b06d253e8 --- /dev/null +++ b/3-asynchronous-JS/node_modules/fast-safe-stringify/.travis.yml @@ -0,0 +1,8 @@ +language: node_js +sudo: false +node_js: +- '4' +- '6' +- '8' +- '9' +- '10' diff --git a/3-asynchronous-JS/node_modules/fast-safe-stringify/CHANGELOG.md b/3-asynchronous-JS/node_modules/fast-safe-stringify/CHANGELOG.md new file mode 100644 index 0000000000..55f2d082fd --- /dev/null +++ b/3-asynchronous-JS/node_modules/fast-safe-stringify/CHANGELOG.md @@ -0,0 +1,17 @@ +# Changelog + +## v.2.0.0 + +Features + +- Added stable-stringify (see documentation) +- Support replacer +- Support spacer +- toJSON support without forceDecirc property +- Improved performance + +Breaking changes + +- Manipulating the input value in a `toJSON` function is not possible anymore in + all cases (see documentation) +- Dropped support for e.g. IE8 and Node.js < 4 diff --git a/3-asynchronous-JS/node_modules/fast-safe-stringify/LICENSE b/3-asynchronous-JS/node_modules/fast-safe-stringify/LICENSE new file mode 100644 index 0000000000..d310c2d179 --- /dev/null +++ b/3-asynchronous-JS/node_modules/fast-safe-stringify/LICENSE @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright (c) 2016 David Mark Clements +Copyright (c) 2017 David Mark Clements & Matteo Collina +Copyright (c) 2018 David Mark Clements, Matteo Collina & Ruben Bridgewater + +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/3-asynchronous-JS/node_modules/fast-safe-stringify/benchmark.js b/3-asynchronous-JS/node_modules/fast-safe-stringify/benchmark.js new file mode 100644 index 0000000000..7ba5e9f549 --- /dev/null +++ b/3-asynchronous-JS/node_modules/fast-safe-stringify/benchmark.js @@ -0,0 +1,137 @@ +const Benchmark = require('benchmark') +const suite = new Benchmark.Suite() +const { inspect } = require('util') +const jsonStringifySafe = require('json-stringify-safe') +const fastSafeStringify = require('./') + +const array = new Array(10).fill(0).map((_, i) => i) +const obj = { foo: array } +const circ = JSON.parse(JSON.stringify(obj)) +circ.o = { obj: circ, array } +const circGetters = JSON.parse(JSON.stringify(obj)) +Object.assign(circGetters, { get o () { return { obj: circGetters, array } } }) + +const deep = require('./package.json') +deep.deep = JSON.parse(JSON.stringify(deep)) +deep.deep.deep = JSON.parse(JSON.stringify(deep)) +deep.deep.deep.deep = JSON.parse(JSON.stringify(deep)) +deep.array = array + +const deepCirc = JSON.parse(JSON.stringify(deep)) +deepCirc.deep.deep.deep.circ = deepCirc +deepCirc.deep.deep.circ = deepCirc +deepCirc.deep.circ = deepCirc +deepCirc.array = array + +const deepCircGetters = JSON.parse(JSON.stringify(deep)) +for (let i = 0; i < 10; i++) { + deepCircGetters[i.toString()] = { + deep: { + deep: { + get circ () { return deep.deep }, + deep: { get circ () { return deep.deep.deep } } + }, + get circ () { return deep } + }, + get array () { return array } + } +} + +const deepCircNonCongifurableGetters = JSON.parse(JSON.stringify(deep)) +Object.defineProperty(deepCircNonCongifurableGetters.deep.deep.deep, 'circ', { + get: () => deepCircNonCongifurableGetters, + enumerable: true, + configurable: false +}) +Object.defineProperty(deepCircNonCongifurableGetters.deep.deep, 'circ', { + get: () => deepCircNonCongifurableGetters, + enumerable: true, + configurable: false +}) +Object.defineProperty(deepCircNonCongifurableGetters.deep, 'circ', { + get: () => deepCircNonCongifurableGetters, + enumerable: true, + configurable: false +}) +Object.defineProperty(deepCircNonCongifurableGetters, 'array', { + get: () => array, + enumerable: true, + configurable: false +}) + +suite.add('util.inspect: simple object ', function () { + inspect(obj, { showHidden: false, depth: null }) +}) +suite.add('util.inspect: circular ', function () { + inspect(circ, { showHidden: false, depth: null }) +}) +suite.add('util.inspect: circular getters ', function () { + inspect(circGetters, { showHidden: false, depth: null }) +}) +suite.add('util.inspect: deep ', function () { + inspect(deep, { showHidden: false, depth: null }) +}) +suite.add('util.inspect: deep circular ', function () { + inspect(deepCirc, { showHidden: false, depth: null }) +}) +suite.add('util.inspect: large deep circular getters ', function () { + inspect(deepCircGetters, { showHidden: false, depth: null }) +}) +suite.add('util.inspect: deep non-conf circular getters', function () { + inspect(deepCircNonCongifurableGetters, { showHidden: false, depth: null }) +}) + +suite.add('\njson-stringify-safe: simple object ', function () { + jsonStringifySafe(obj) +}) +suite.add('json-stringify-safe: circular ', function () { + jsonStringifySafe(circ) +}) +suite.add('json-stringify-safe: circular getters ', function () { + jsonStringifySafe(circGetters) +}) +suite.add('json-stringify-safe: deep ', function () { + jsonStringifySafe(deep) +}) +suite.add('json-stringify-safe: deep circular ', function () { + jsonStringifySafe(deepCirc) +}) +suite.add('json-stringify-safe: large deep circular getters ', function () { + jsonStringifySafe(deepCircGetters) +}) +suite.add('json-stringify-safe: deep non-conf circular getters', function () { + jsonStringifySafe(deepCircNonCongifurableGetters) +}) + +suite.add('\nfast-safe-stringify: simple object ', function () { + fastSafeStringify(obj) +}) +suite.add('fast-safe-stringify: circular ', function () { + fastSafeStringify(circ) +}) +suite.add('fast-safe-stringify: circular getters ', function () { + fastSafeStringify(circGetters) +}) +suite.add('fast-safe-stringify: deep ', function () { + fastSafeStringify(deep) +}) +suite.add('fast-safe-stringify: deep circular ', function () { + fastSafeStringify(deepCirc) +}) +suite.add('fast-safe-stringify: large deep circular getters ', function () { + fastSafeStringify(deepCircGetters) +}) +suite.add('fast-safe-stringify: deep non-conf circular getters', function () { + fastSafeStringify(deepCircNonCongifurableGetters) +}) + +// add listeners +suite.on('cycle', function (event) { + console.log(String(event.target)) +}) + +suite.on('complete', function () { + console.log('\nFastest is ' + this.filter('fastest').map('name')) +}) + +suite.run({ delay: 1, minSamples: 150 }) diff --git a/3-asynchronous-JS/node_modules/fast-safe-stringify/index.d.ts b/3-asynchronous-JS/node_modules/fast-safe-stringify/index.d.ts new file mode 100644 index 0000000000..9a9b1f00e0 --- /dev/null +++ b/3-asynchronous-JS/node_modules/fast-safe-stringify/index.d.ts @@ -0,0 +1,23 @@ +declare function stringify( + value: any, + replacer?: (key: string, value: any) => any, + space?: string | number, + options?: { depthLimit: number | undefined; edgesLimit: number | undefined } +): string; + +declare namespace stringify { + export function stable( + value: any, + replacer?: (key: string, value: any) => any, + space?: string | number, + options?: { depthLimit: number | undefined; edgesLimit: number | undefined } + ): string; + export function stableStringify( + value: any, + replacer?: (key: string, value: any) => any, + space?: string | number, + options?: { depthLimit: number | undefined; edgesLimit: number | undefined } + ): string; +} + +export default stringify; diff --git a/3-asynchronous-JS/node_modules/fast-safe-stringify/index.js b/3-asynchronous-JS/node_modules/fast-safe-stringify/index.js new file mode 100644 index 0000000000..ecf7e51905 --- /dev/null +++ b/3-asynchronous-JS/node_modules/fast-safe-stringify/index.js @@ -0,0 +1,229 @@ +module.exports = stringify +stringify.default = stringify +stringify.stable = deterministicStringify +stringify.stableStringify = deterministicStringify + +var LIMIT_REPLACE_NODE = '[...]' +var CIRCULAR_REPLACE_NODE = '[Circular]' + +var arr = [] +var replacerStack = [] + +function defaultOptions () { + return { + depthLimit: Number.MAX_SAFE_INTEGER, + edgesLimit: Number.MAX_SAFE_INTEGER + } +} + +// Regular stringify +function stringify (obj, replacer, spacer, options) { + if (typeof options === 'undefined') { + options = defaultOptions() + } + + decirc(obj, '', 0, [], undefined, 0, options) + var res + try { + if (replacerStack.length === 0) { + res = JSON.stringify(obj, replacer, spacer) + } else { + res = JSON.stringify(obj, replaceGetterValues(replacer), spacer) + } + } catch (_) { + return JSON.stringify('[unable to serialize, circular reference is too complex to analyze]') + } finally { + while (arr.length !== 0) { + var part = arr.pop() + if (part.length === 4) { + Object.defineProperty(part[0], part[1], part[3]) + } else { + part[0][part[1]] = part[2] + } + } + } + return res +} + +function setReplace (replace, val, k, parent) { + var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k) + if (propertyDescriptor.get !== undefined) { + if (propertyDescriptor.configurable) { + Object.defineProperty(parent, k, { value: replace }) + arr.push([parent, k, val, propertyDescriptor]) + } else { + replacerStack.push([val, k, replace]) + } + } else { + parent[k] = replace + arr.push([parent, k, val]) + } +} + +function decirc (val, k, edgeIndex, stack, parent, depth, options) { + depth += 1 + var i + if (typeof val === 'object' && val !== null) { + for (i = 0; i < stack.length; i++) { + if (stack[i] === val) { + setReplace(CIRCULAR_REPLACE_NODE, val, k, parent) + return + } + } + + if ( + typeof options.depthLimit !== 'undefined' && + depth > options.depthLimit + ) { + setReplace(LIMIT_REPLACE_NODE, val, k, parent) + return + } + + if ( + typeof options.edgesLimit !== 'undefined' && + edgeIndex + 1 > options.edgesLimit + ) { + setReplace(LIMIT_REPLACE_NODE, val, k, parent) + return + } + + stack.push(val) + // Optimize for Arrays. Big arrays could kill the performance otherwise! + if (Array.isArray(val)) { + for (i = 0; i < val.length; i++) { + decirc(val[i], i, i, stack, val, depth, options) + } + } else { + var keys = Object.keys(val) + for (i = 0; i < keys.length; i++) { + var key = keys[i] + decirc(val[key], key, i, stack, val, depth, options) + } + } + stack.pop() + } +} + +// Stable-stringify +function compareFunction (a, b) { + if (a < b) { + return -1 + } + if (a > b) { + return 1 + } + return 0 +} + +function deterministicStringify (obj, replacer, spacer, options) { + if (typeof options === 'undefined') { + options = defaultOptions() + } + + var tmp = deterministicDecirc(obj, '', 0, [], undefined, 0, options) || obj + var res + try { + if (replacerStack.length === 0) { + res = JSON.stringify(tmp, replacer, spacer) + } else { + res = JSON.stringify(tmp, replaceGetterValues(replacer), spacer) + } + } catch (_) { + return JSON.stringify('[unable to serialize, circular reference is too complex to analyze]') + } finally { + // Ensure that we restore the object as it was. + while (arr.length !== 0) { + var part = arr.pop() + if (part.length === 4) { + Object.defineProperty(part[0], part[1], part[3]) + } else { + part[0][part[1]] = part[2] + } + } + } + return res +} + +function deterministicDecirc (val, k, edgeIndex, stack, parent, depth, options) { + depth += 1 + var i + if (typeof val === 'object' && val !== null) { + for (i = 0; i < stack.length; i++) { + if (stack[i] === val) { + setReplace(CIRCULAR_REPLACE_NODE, val, k, parent) + return + } + } + try { + if (typeof val.toJSON === 'function') { + return + } + } catch (_) { + return + } + + if ( + typeof options.depthLimit !== 'undefined' && + depth > options.depthLimit + ) { + setReplace(LIMIT_REPLACE_NODE, val, k, parent) + return + } + + if ( + typeof options.edgesLimit !== 'undefined' && + edgeIndex + 1 > options.edgesLimit + ) { + setReplace(LIMIT_REPLACE_NODE, val, k, parent) + return + } + + stack.push(val) + // Optimize for Arrays. Big arrays could kill the performance otherwise! + if (Array.isArray(val)) { + for (i = 0; i < val.length; i++) { + deterministicDecirc(val[i], i, i, stack, val, depth, options) + } + } else { + // Create a temporary object in the required way + var tmp = {} + var keys = Object.keys(val).sort(compareFunction) + for (i = 0; i < keys.length; i++) { + var key = keys[i] + deterministicDecirc(val[key], key, i, stack, val, depth, options) + tmp[key] = val[key] + } + if (typeof parent !== 'undefined') { + arr.push([parent, k, val]) + parent[k] = tmp + } else { + return tmp + } + } + stack.pop() + } +} + +// wraps replacer function to handle values we couldn't replace +// and mark them as replaced value +function replaceGetterValues (replacer) { + replacer = + typeof replacer !== 'undefined' + ? replacer + : function (k, v) { + return v + } + return function (key, val) { + if (replacerStack.length > 0) { + for (var i = 0; i < replacerStack.length; i++) { + var part = replacerStack[i] + if (part[1] === key && part[0] === val) { + val = part[2] + replacerStack.splice(i, 1) + break + } + } + } + return replacer.call(this, key, val) + } +} diff --git a/3-asynchronous-JS/node_modules/fast-safe-stringify/package.json b/3-asynchronous-JS/node_modules/fast-safe-stringify/package.json new file mode 100644 index 0000000000..206a591981 --- /dev/null +++ b/3-asynchronous-JS/node_modules/fast-safe-stringify/package.json @@ -0,0 +1,46 @@ +{ + "name": "fast-safe-stringify", + "version": "2.1.1", + "description": "Safely and quickly serialize JavaScript objects", + "keywords": [ + "stable", + "stringify", + "JSON", + "JSON.stringify", + "safe", + "serialize" + ], + "main": "index.js", + "scripts": { + "test": "standard && tap --no-esm test.js test-stable.js", + "benchmark": "node benchmark.js" + }, + "author": "David Mark Clements", + "contributors": [ + "Ruben Bridgewater", + "Matteo Collina", + "Ben Gourley", + "Gabriel Lesperance", + "Alex Liu", + "Christoph Walcher", + "Nicholas Young" + ], + "license": "MIT", + "typings": "index", + "devDependencies": { + "benchmark": "^2.1.4", + "clone": "^2.1.0", + "json-stringify-safe": "^5.0.1", + "standard": "^11.0.0", + "tap": "^12.0.0" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/davidmarkclements/fast-safe-stringify.git" + }, + "bugs": { + "url": "https://github.com/davidmarkclements/fast-safe-stringify/issues" + }, + "homepage": "https://github.com/davidmarkclements/fast-safe-stringify#readme", + "dependencies": {} +} diff --git a/3-asynchronous-JS/node_modules/fast-safe-stringify/readme.md b/3-asynchronous-JS/node_modules/fast-safe-stringify/readme.md new file mode 100644 index 0000000000..47179c94a7 --- /dev/null +++ b/3-asynchronous-JS/node_modules/fast-safe-stringify/readme.md @@ -0,0 +1,170 @@ +# fast-safe-stringify + +Safe and fast serialization alternative to [JSON.stringify][]. + +Gracefully handles circular structures instead of throwing in most cases. +It could return an error string if the circular object is too complex to analyze, +e.g. in case there are proxies involved. + +Provides a deterministic ("stable") version as well that will also gracefully +handle circular structures. See the example below for further information. + +## Usage + +The same as [JSON.stringify][]. + +`stringify(value[, replacer[, space[, options]]])` + +```js +const safeStringify = require('fast-safe-stringify') +const o = { a: 1 } +o.o = o + +console.log(safeStringify(o)) +// '{"a":1,"o":"[Circular]"}' +console.log(JSON.stringify(o)) +// TypeError: Converting circular structure to JSON + +function replacer(key, value) { + console.log('Key:', JSON.stringify(key), 'Value:', JSON.stringify(value)) + // Remove the circular structure + if (value === '[Circular]') { + return + } + return value +} + +// those are also defaults limits when no options object is passed into safeStringify +// configure it to lower the limit. +const options = { + depthLimit: Number.MAX_SAFE_INTEGER, + edgesLimit: Number.MAX_SAFE_INTEGER +}; + +const serialized = safeStringify(o, replacer, 2, options) +// Key: "" Value: {"a":1,"o":"[Circular]"} +// Key: "a" Value: 1 +// Key: "o" Value: "[Circular]" +console.log(serialized) +// { +// "a": 1 +// } +``` + + +Using the deterministic version also works the same: + +```js +const safeStringify = require('fast-safe-stringify') +const o = { b: 1, a: 0 } +o.o = o + +console.log(safeStringify(o)) +// '{"b":1,"a":0,"o":"[Circular]"}' +console.log(safeStringify.stableStringify(o)) +// '{"a":0,"b":1,"o":"[Circular]"}' +console.log(JSON.stringify(o)) +// TypeError: Converting circular structure to JSON +``` + +A faster and side-effect free implementation is available in the +[safe-stable-stringify][] module. However it is still considered experimental +due to a new and more complex implementation. + +### Replace strings constants + +- `[Circular]` - when same reference is found +- `[...]` - when some limit from options object is reached + +## Differences to JSON.stringify + +In general the behavior is identical to [JSON.stringify][]. The [`replacer`][] +and [`space`][] options are also available. + +A few exceptions exist to [JSON.stringify][] while using [`toJSON`][] or +[`replacer`][]: + +### Regular safe stringify + +- Manipulating a circular structure of the passed in value in a `toJSON` or the + `replacer` is not possible! It is possible for any other value and property. + +- In case a circular structure is detected and the [`replacer`][] is used it + will receive the string `[Circular]` as the argument instead of the circular + object itself. + +### Deterministic ("stable") safe stringify + +- Manipulating the input object either in a [`toJSON`][] or the [`replacer`][] + function will not have any effect on the output. The output entirely relies on + the shape the input value had at the point passed to the stringify function! + +- In case a circular structure is detected and the [`replacer`][] is used it + will receive the string `[Circular]` as the argument instead of the circular + object itself. + +A side effect free variation without these limitations can be found as well +([`safe-stable-stringify`][]). It is also faster than the current +implementation. It is still considered experimental due to a new and more +complex implementation. + +## Benchmarks + +Although not JSON, the Node.js `util.inspect` method can be used for similar +purposes (e.g. logging) and also handles circular references. + +Here we compare `fast-safe-stringify` with some alternatives: +(Lenovo T450s with a i7-5600U CPU using Node.js 8.9.4) + +```md +fast-safe-stringify: simple object x 1,121,497 ops/sec ±0.75% (97 runs sampled) +fast-safe-stringify: circular x 560,126 ops/sec ±0.64% (96 runs sampled) +fast-safe-stringify: deep x 32,472 ops/sec ±0.57% (95 runs sampled) +fast-safe-stringify: deep circular x 32,513 ops/sec ±0.80% (92 runs sampled) + +util.inspect: simple object x 272,837 ops/sec ±1.48% (90 runs sampled) +util.inspect: circular x 116,896 ops/sec ±1.19% (95 runs sampled) +util.inspect: deep x 19,382 ops/sec ±0.66% (92 runs sampled) +util.inspect: deep circular x 18,717 ops/sec ±0.63% (96 runs sampled) + +json-stringify-safe: simple object x 233,621 ops/sec ±0.97% (94 runs sampled) +json-stringify-safe: circular x 110,409 ops/sec ±1.85% (95 runs sampled) +json-stringify-safe: deep x 8,705 ops/sec ±0.87% (96 runs sampled) +json-stringify-safe: deep circular x 8,336 ops/sec ±2.20% (93 runs sampled) +``` + +For stable stringify comparisons, see the performance benchmarks in the +[`safe-stable-stringify`][] readme. + +## Protip + +Whether `fast-safe-stringify` or alternatives are used: if the use case +consists of deeply nested objects without circular references the following +pattern will give best results. +Shallow or one level nested objects on the other hand will slow down with it. +It is entirely dependant on the use case. + +```js +const stringify = require('fast-safe-stringify') + +function tryJSONStringify (obj) { + try { return JSON.stringify(obj) } catch (_) {} +} + +const serializedString = tryJSONStringify(deep) || stringify(deep) +``` + +## Acknowledgements + +Sponsored by [nearForm](http://nearform.com) + +## License + +MIT + +[`replacer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The%20replacer%20parameter +[`safe-stable-stringify`]: https://github.com/BridgeAR/safe-stable-stringify +[`space`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The%20space%20argument +[`toJSON`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior +[benchmark]: https://github.com/epoberezkin/fast-json-stable-stringify/blob/67f688f7441010cfef91a6147280cc501701e83b/benchmark +[JSON.stringify]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify diff --git a/3-asynchronous-JS/node_modules/fast-safe-stringify/test-stable.js b/3-asynchronous-JS/node_modules/fast-safe-stringify/test-stable.js new file mode 100644 index 0000000000..c55b95ca1e --- /dev/null +++ b/3-asynchronous-JS/node_modules/fast-safe-stringify/test-stable.js @@ -0,0 +1,404 @@ +const test = require('tap').test +const fss = require('./').stable +const clone = require('clone') +const s = JSON.stringify +const stream = require('stream') + +test('circular reference to root', function (assert) { + const fixture = { name: 'Tywin Lannister' } + fixture.circle = fixture + const expected = s({ circle: '[Circular]', name: 'Tywin Lannister' }) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('circular getter reference to root', function (assert) { + const fixture = { + name: 'Tywin Lannister', + get circle () { + return fixture + } + } + + const expected = s({ circle: '[Circular]', name: 'Tywin Lannister' }) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('nested circular reference to root', function (assert) { + const fixture = { name: 'Tywin Lannister' } + fixture.id = { circle: fixture } + const expected = s({ id: { circle: '[Circular]' }, name: 'Tywin Lannister' }) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('child circular reference', function (assert) { + const fixture = { + name: 'Tywin Lannister', + child: { name: 'Tyrion Lannister' } + } + fixture.child.dinklage = fixture.child + const expected = s({ + child: { + dinklage: '[Circular]', + name: 'Tyrion Lannister' + }, + name: 'Tywin Lannister' + }) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('nested child circular reference', function (assert) { + const fixture = { + name: 'Tywin Lannister', + child: { name: 'Tyrion Lannister' } + } + fixture.child.actor = { dinklage: fixture.child } + const expected = s({ + child: { + actor: { dinklage: '[Circular]' }, + name: 'Tyrion Lannister' + }, + name: 'Tywin Lannister' + }) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('circular objects in an array', function (assert) { + const fixture = { name: 'Tywin Lannister' } + fixture.hand = [fixture, fixture] + const expected = s({ + hand: ['[Circular]', '[Circular]'], + name: 'Tywin Lannister' + }) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('nested circular references in an array', function (assert) { + const fixture = { + name: 'Tywin Lannister', + offspring: [{ name: 'Tyrion Lannister' }, { name: 'Cersei Lannister' }] + } + fixture.offspring[0].dinklage = fixture.offspring[0] + fixture.offspring[1].headey = fixture.offspring[1] + + const expected = s({ + name: 'Tywin Lannister', + offspring: [ + { dinklage: '[Circular]', name: 'Tyrion Lannister' }, + { headey: '[Circular]', name: 'Cersei Lannister' } + ] + }) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('circular arrays', function (assert) { + const fixture = [] + fixture.push(fixture, fixture) + const expected = s(['[Circular]', '[Circular]']) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('nested circular arrays', function (assert) { + const fixture = [] + fixture.push( + { name: 'Jon Snow', bastards: fixture }, + { name: 'Ramsay Bolton', bastards: fixture } + ) + const expected = s([ + { bastards: '[Circular]', name: 'Jon Snow' }, + { bastards: '[Circular]', name: 'Ramsay Bolton' } + ]) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('repeated non-circular references in objects', function (assert) { + const daenerys = { name: 'Daenerys Targaryen' } + const fixture = { + motherOfDragons: daenerys, + queenOfMeereen: daenerys + } + const expected = s(fixture) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('repeated non-circular references in arrays', function (assert) { + const daenerys = { name: 'Daenerys Targaryen' } + const fixture = [daenerys, daenerys] + const expected = s(fixture) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('double child circular reference', function (assert) { + // create circular reference + const child = { name: 'Tyrion Lannister' } + child.dinklage = child + + // include it twice in the fixture + const fixture = { name: 'Tywin Lannister', childA: child, childB: child } + const cloned = clone(fixture) + const expected = s({ + childA: { + dinklage: '[Circular]', + name: 'Tyrion Lannister' + }, + childB: { + dinklage: '[Circular]', + name: 'Tyrion Lannister' + }, + name: 'Tywin Lannister' + }) + const actual = fss(fixture) + assert.equal(actual, expected) + + // check if the fixture has not been modified + assert.same(fixture, cloned) + assert.end() +}) + +test('child circular reference with toJSON', function (assert) { + // Create a test object that has an overridden `toJSON` property + TestObject.prototype.toJSON = function () { + return { special: 'case' } + } + function TestObject (content) {} + + // Creating a simple circular object structure + const parentObject = {} + parentObject.childObject = new TestObject() + parentObject.childObject.parentObject = parentObject + + // Creating a simple circular object structure + const otherParentObject = new TestObject() + otherParentObject.otherChildObject = {} + otherParentObject.otherChildObject.otherParentObject = otherParentObject + + // Making sure our original tests work + assert.same(parentObject.childObject.parentObject, parentObject) + assert.same( + otherParentObject.otherChildObject.otherParentObject, + otherParentObject + ) + + // Should both be idempotent + assert.equal(fss(parentObject), '{"childObject":{"special":"case"}}') + assert.equal(fss(otherParentObject), '{"special":"case"}') + + // Therefore the following assertion should be `true` + assert.same(parentObject.childObject.parentObject, parentObject) + assert.same( + otherParentObject.otherChildObject.otherParentObject, + otherParentObject + ) + + assert.end() +}) + +test('null object', function (assert) { + const expected = s(null) + const actual = fss(null) + assert.equal(actual, expected) + assert.end() +}) + +test('null property', function (assert) { + const expected = s({ f: null }) + const actual = fss({ f: null }) + assert.equal(actual, expected) + assert.end() +}) + +test('nested child circular reference in toJSON', function (assert) { + var circle = { some: 'data' } + circle.circle = circle + var a = { + b: { + toJSON: function () { + a.b = 2 + return '[Redacted]' + } + }, + baz: { + circle, + toJSON: function () { + a.baz = circle + return '[Redacted]' + } + } + } + var o = { + a, + bar: a + } + + const expected = s({ + a: { + b: '[Redacted]', + baz: '[Redacted]' + }, + bar: { + // TODO: This is a known limitation of the current implementation. + // The ideal result would be: + // + // b: 2, + // baz: { + // circle: '[Circular]', + // some: 'data' + // } + // + b: '[Redacted]', + baz: '[Redacted]' + } + }) + const actual = fss(o) + assert.equal(actual, expected) + assert.end() +}) + +test('circular getters are restored when stringified', function (assert) { + const fixture = { + name: 'Tywin Lannister', + get circle () { + return fixture + } + } + fss(fixture) + + assert.equal(fixture.circle, fixture) + assert.end() +}) + +test('non-configurable circular getters use a replacer instead of markers', function (assert) { + const fixture = { name: 'Tywin Lannister' } + Object.defineProperty(fixture, 'circle', { + configurable: false, + get: function () { + return fixture + }, + enumerable: true + }) + + fss(fixture) + + assert.equal(fixture.circle, fixture) + assert.end() +}) + +test('getter child circular reference', function (assert) { + const fixture = { + name: 'Tywin Lannister', + child: { + name: 'Tyrion Lannister', + get dinklage () { + return fixture.child + } + }, + get self () { + return fixture + } + } + + const expected = s({ + child: { + dinklage: '[Circular]', + name: 'Tyrion Lannister' + }, + name: 'Tywin Lannister', + self: '[Circular]' + }) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('Proxy throwing', function (assert) { + assert.plan(1) + const s = new stream.PassThrough() + s.resume() + s.write('', () => { + assert.end() + }) + const actual = fss({ s, p: new Proxy({}, { get () { throw new Error('kaboom') } }) }) + assert.equal(actual, '"[unable to serialize, circular reference is too complex to analyze]"') +}) + +test('depthLimit option - will replace deep objects', function (assert) { + const fixture = { + name: 'Tywin Lannister', + child: { + name: 'Tyrion Lannister' + }, + get self () { + return fixture + } + } + + const expected = s({ + child: '[...]', + name: 'Tywin Lannister', + self: '[Circular]' + }) + const actual = fss(fixture, undefined, undefined, { + depthLimit: 1, + edgesLimit: 1 + }) + assert.equal(actual, expected) + assert.end() +}) + +test('edgesLimit option - will replace deep objects', function (assert) { + const fixture = { + object: { + 1: { test: 'test' }, + 2: { test: 'test' }, + 3: { test: 'test' }, + 4: { test: 'test' } + }, + array: [ + { test: 'test' }, + { test: 'test' }, + { test: 'test' }, + { test: 'test' } + ], + get self () { + return fixture + } + } + + const expected = s({ + array: [{ test: 'test' }, { test: 'test' }, { test: 'test' }, '[...]'], + object: { + 1: { test: 'test' }, + 2: { test: 'test' }, + 3: { test: 'test' }, + 4: '[...]' + }, + self: '[Circular]' + }) + const actual = fss(fixture, undefined, undefined, { + depthLimit: 3, + edgesLimit: 3 + }) + assert.equal(actual, expected) + assert.end() +}) diff --git a/3-asynchronous-JS/node_modules/fast-safe-stringify/test.js b/3-asynchronous-JS/node_modules/fast-safe-stringify/test.js new file mode 100644 index 0000000000..a4170e96cf --- /dev/null +++ b/3-asynchronous-JS/node_modules/fast-safe-stringify/test.js @@ -0,0 +1,397 @@ +const test = require('tap').test +const fss = require('./') +const clone = require('clone') +const s = JSON.stringify +const stream = require('stream') + +test('circular reference to root', function (assert) { + const fixture = { name: 'Tywin Lannister' } + fixture.circle = fixture + const expected = s({ name: 'Tywin Lannister', circle: '[Circular]' }) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('circular getter reference to root', function (assert) { + const fixture = { + name: 'Tywin Lannister', + get circle () { + return fixture + } + } + const expected = s({ name: 'Tywin Lannister', circle: '[Circular]' }) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('nested circular reference to root', function (assert) { + const fixture = { name: 'Tywin Lannister' } + fixture.id = { circle: fixture } + const expected = s({ name: 'Tywin Lannister', id: { circle: '[Circular]' } }) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('child circular reference', function (assert) { + const fixture = { + name: 'Tywin Lannister', + child: { name: 'Tyrion Lannister' } + } + fixture.child.dinklage = fixture.child + const expected = s({ + name: 'Tywin Lannister', + child: { + name: 'Tyrion Lannister', + dinklage: '[Circular]' + } + }) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('nested child circular reference', function (assert) { + const fixture = { + name: 'Tywin Lannister', + child: { name: 'Tyrion Lannister' } + } + fixture.child.actor = { dinklage: fixture.child } + const expected = s({ + name: 'Tywin Lannister', + child: { + name: 'Tyrion Lannister', + actor: { dinklage: '[Circular]' } + } + }) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('circular objects in an array', function (assert) { + const fixture = { name: 'Tywin Lannister' } + fixture.hand = [fixture, fixture] + const expected = s({ + name: 'Tywin Lannister', + hand: ['[Circular]', '[Circular]'] + }) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('nested circular references in an array', function (assert) { + const fixture = { + name: 'Tywin Lannister', + offspring: [{ name: 'Tyrion Lannister' }, { name: 'Cersei Lannister' }] + } + fixture.offspring[0].dinklage = fixture.offspring[0] + fixture.offspring[1].headey = fixture.offspring[1] + + const expected = s({ + name: 'Tywin Lannister', + offspring: [ + { name: 'Tyrion Lannister', dinklage: '[Circular]' }, + { name: 'Cersei Lannister', headey: '[Circular]' } + ] + }) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('circular arrays', function (assert) { + const fixture = [] + fixture.push(fixture, fixture) + const expected = s(['[Circular]', '[Circular]']) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('nested circular arrays', function (assert) { + const fixture = [] + fixture.push( + { name: 'Jon Snow', bastards: fixture }, + { name: 'Ramsay Bolton', bastards: fixture } + ) + const expected = s([ + { name: 'Jon Snow', bastards: '[Circular]' }, + { name: 'Ramsay Bolton', bastards: '[Circular]' } + ]) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('repeated non-circular references in objects', function (assert) { + const daenerys = { name: 'Daenerys Targaryen' } + const fixture = { + motherOfDragons: daenerys, + queenOfMeereen: daenerys + } + const expected = s(fixture) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('repeated non-circular references in arrays', function (assert) { + const daenerys = { name: 'Daenerys Targaryen' } + const fixture = [daenerys, daenerys] + const expected = s(fixture) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('double child circular reference', function (assert) { + // create circular reference + const child = { name: 'Tyrion Lannister' } + child.dinklage = child + + // include it twice in the fixture + const fixture = { name: 'Tywin Lannister', childA: child, childB: child } + const cloned = clone(fixture) + const expected = s({ + name: 'Tywin Lannister', + childA: { + name: 'Tyrion Lannister', + dinklage: '[Circular]' + }, + childB: { + name: 'Tyrion Lannister', + dinklage: '[Circular]' + } + }) + const actual = fss(fixture) + assert.equal(actual, expected) + + // check if the fixture has not been modified + assert.same(fixture, cloned) + assert.end() +}) + +test('child circular reference with toJSON', function (assert) { + // Create a test object that has an overridden `toJSON` property + TestObject.prototype.toJSON = function () { + return { special: 'case' } + } + function TestObject (content) {} + + // Creating a simple circular object structure + const parentObject = {} + parentObject.childObject = new TestObject() + parentObject.childObject.parentObject = parentObject + + // Creating a simple circular object structure + const otherParentObject = new TestObject() + otherParentObject.otherChildObject = {} + otherParentObject.otherChildObject.otherParentObject = otherParentObject + + // Making sure our original tests work + assert.same(parentObject.childObject.parentObject, parentObject) + assert.same( + otherParentObject.otherChildObject.otherParentObject, + otherParentObject + ) + + // Should both be idempotent + assert.equal(fss(parentObject), '{"childObject":{"special":"case"}}') + assert.equal(fss(otherParentObject), '{"special":"case"}') + + // Therefore the following assertion should be `true` + assert.same(parentObject.childObject.parentObject, parentObject) + assert.same( + otherParentObject.otherChildObject.otherParentObject, + otherParentObject + ) + + assert.end() +}) + +test('null object', function (assert) { + const expected = s(null) + const actual = fss(null) + assert.equal(actual, expected) + assert.end() +}) + +test('null property', function (assert) { + const expected = s({ f: null }) + const actual = fss({ f: null }) + assert.equal(actual, expected) + assert.end() +}) + +test('nested child circular reference in toJSON', function (assert) { + const circle = { some: 'data' } + circle.circle = circle + const a = { + b: { + toJSON: function () { + a.b = 2 + return '[Redacted]' + } + }, + baz: { + circle, + toJSON: function () { + a.baz = circle + return '[Redacted]' + } + } + } + const o = { + a, + bar: a + } + + const expected = s({ + a: { + b: '[Redacted]', + baz: '[Redacted]' + }, + bar: { + b: 2, + baz: { + some: 'data', + circle: '[Circular]' + } + } + }) + const actual = fss(o) + assert.equal(actual, expected) + assert.end() +}) + +test('circular getters are restored when stringified', function (assert) { + const fixture = { + name: 'Tywin Lannister', + get circle () { + return fixture + } + } + fss(fixture) + + assert.equal(fixture.circle, fixture) + assert.end() +}) + +test('non-configurable circular getters use a replacer instead of markers', function (assert) { + const fixture = { name: 'Tywin Lannister' } + Object.defineProperty(fixture, 'circle', { + configurable: false, + get: function () { + return fixture + }, + enumerable: true + }) + + fss(fixture) + + assert.equal(fixture.circle, fixture) + assert.end() +}) + +test('getter child circular reference are replaced instead of marked', function (assert) { + const fixture = { + name: 'Tywin Lannister', + child: { + name: 'Tyrion Lannister', + get dinklage () { + return fixture.child + } + }, + get self () { + return fixture + } + } + + const expected = s({ + name: 'Tywin Lannister', + child: { + name: 'Tyrion Lannister', + dinklage: '[Circular]' + }, + self: '[Circular]' + }) + const actual = fss(fixture) + assert.equal(actual, expected) + assert.end() +}) + +test('Proxy throwing', function (assert) { + assert.plan(1) + const s = new stream.PassThrough() + s.resume() + s.write('', () => { + assert.end() + }) + const actual = fss({ s, p: new Proxy({}, { get () { throw new Error('kaboom') } }) }) + assert.equal(actual, '"[unable to serialize, circular reference is too complex to analyze]"') +}) + +test('depthLimit option - will replace deep objects', function (assert) { + const fixture = { + name: 'Tywin Lannister', + child: { + name: 'Tyrion Lannister' + }, + get self () { + return fixture + } + } + + const expected = s({ + name: 'Tywin Lannister', + child: '[...]', + self: '[Circular]' + }) + const actual = fss(fixture, undefined, undefined, { + depthLimit: 1, + edgesLimit: 1 + }) + assert.equal(actual, expected) + assert.end() +}) + +test('edgesLimit option - will replace deep objects', function (assert) { + const fixture = { + object: { + 1: { test: 'test' }, + 2: { test: 'test' }, + 3: { test: 'test' }, + 4: { test: 'test' } + }, + array: [ + { test: 'test' }, + { test: 'test' }, + { test: 'test' }, + { test: 'test' } + ], + get self () { + return fixture + } + } + + const expected = s({ + object: { + 1: { test: 'test' }, + 2: { test: 'test' }, + 3: { test: 'test' }, + 4: '[...]' + }, + array: [{ test: 'test' }, { test: 'test' }, { test: 'test' }, '[...]'], + self: '[Circular]' + }) + const actual = fss(fixture, undefined, undefined, { + depthLimit: 3, + edgesLimit: 3 + }) + assert.equal(actual, expected) + assert.end() +}) diff --git a/3-asynchronous-JS/node_modules/form-data/License b/3-asynchronous-JS/node_modules/form-data/License new file mode 100644 index 0000000000..c7ff12a2f8 --- /dev/null +++ b/3-asynchronous-JS/node_modules/form-data/License @@ -0,0 +1,19 @@ +Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. diff --git a/3-asynchronous-JS/node_modules/form-data/Readme.md b/3-asynchronous-JS/node_modules/form-data/Readme.md new file mode 100644 index 0000000000..b09df6a42b --- /dev/null +++ b/3-asynchronous-JS/node_modules/form-data/Readme.md @@ -0,0 +1,358 @@ +# Form-Data [![NPM Module](https://img.shields.io/npm/v/form-data.svg)](https://www.npmjs.com/package/form-data) [![Join the chat at https://gitter.im/form-data/form-data](http://form-data.github.io/images/gitterbadge.svg)](https://gitter.im/form-data/form-data) + +A library to create readable ```"multipart/form-data"``` streams. Can be used to submit forms and file uploads to other web applications. + +The API of this library is inspired by the [XMLHttpRequest-2 FormData Interface][xhr2-fd]. + +[xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface + +[![Linux Build](https://img.shields.io/travis/form-data/form-data/master.svg?label=linux:6.x-12.x)](https://travis-ci.org/form-data/form-data) +[![MacOS Build](https://img.shields.io/travis/form-data/form-data/master.svg?label=macos:6.x-12.x)](https://travis-ci.org/form-data/form-data) +[![Windows Build](https://img.shields.io/travis/form-data/form-data/master.svg?label=windows:6.x-12.x)](https://travis-ci.org/form-data/form-data) + +[![Coverage Status](https://img.shields.io/coveralls/form-data/form-data/master.svg?label=code+coverage)](https://coveralls.io/github/form-data/form-data?branch=master) +[![Dependency Status](https://img.shields.io/david/form-data/form-data.svg)](https://david-dm.org/form-data/form-data) + +## Install + +``` +npm install --save form-data +``` + +## Usage + +In this example we are constructing a form with 3 fields that contain a string, +a buffer and a file stream. + +``` javascript +var FormData = require('form-data'); +var fs = require('fs'); + +var form = new FormData(); +form.append('my_field', 'my value'); +form.append('my_buffer', new Buffer(10)); +form.append('my_file', fs.createReadStream('/foo/bar.jpg')); +``` + +Also you can use http-response stream: + +``` javascript +var FormData = require('form-data'); +var http = require('http'); + +var form = new FormData(); + +http.request('http://nodejs.org/images/logo.png', function(response) { + form.append('my_field', 'my value'); + form.append('my_buffer', new Buffer(10)); + form.append('my_logo', response); +}); +``` + +Or @mikeal's [request](https://github.com/request/request) stream: + +``` javascript +var FormData = require('form-data'); +var request = require('request'); + +var form = new FormData(); + +form.append('my_field', 'my value'); +form.append('my_buffer', new Buffer(10)); +form.append('my_logo', request('http://nodejs.org/images/logo.png')); +``` + +In order to submit this form to a web application, call ```submit(url, [callback])``` method: + +``` javascript +form.submit('http://example.org/', function(err, res) { + // res – response object (http.IncomingMessage) // + res.resume(); +}); + +``` + +For more advanced request manipulations ```submit()``` method returns ```http.ClientRequest``` object, or you can choose from one of the alternative submission methods. + +### Custom options + +You can provide custom options, such as `maxDataSize`: + +``` javascript +var FormData = require('form-data'); + +var form = new FormData({ maxDataSize: 20971520 }); +form.append('my_field', 'my value'); +form.append('my_buffer', /* something big */); +``` + +List of available options could be found in [combined-stream](https://github.com/felixge/node-combined-stream/blob/master/lib/combined_stream.js#L7-L15) + +### Alternative submission methods + +You can use node's http client interface: + +``` javascript +var http = require('http'); + +var request = http.request({ + method: 'post', + host: 'example.org', + path: '/upload', + headers: form.getHeaders() +}); + +form.pipe(request); + +request.on('response', function(res) { + console.log(res.statusCode); +}); +``` + +Or if you would prefer the `'Content-Length'` header to be set for you: + +``` javascript +form.submit('example.org/upload', function(err, res) { + console.log(res.statusCode); +}); +``` + +To use custom headers and pre-known length in parts: + +``` javascript +var CRLF = '\r\n'; +var form = new FormData(); + +var options = { + header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF, + knownLength: 1 +}; + +form.append('my_buffer', buffer, options); + +form.submit('http://example.com/', function(err, res) { + if (err) throw err; + console.log('Done'); +}); +``` + +Form-Data can recognize and fetch all the required information from common types of streams (```fs.readStream```, ```http.response``` and ```mikeal's request```), for some other types of streams you'd need to provide "file"-related information manually: + +``` javascript +someModule.stream(function(err, stdout, stderr) { + if (err) throw err; + + var form = new FormData(); + + form.append('file', stdout, { + filename: 'unicycle.jpg', // ... or: + filepath: 'photos/toys/unicycle.jpg', + contentType: 'image/jpeg', + knownLength: 19806 + }); + + form.submit('http://example.com/', function(err, res) { + if (err) throw err; + console.log('Done'); + }); +}); +``` + +The `filepath` property overrides `filename` and may contain a relative path. This is typically used when uploading [multiple files from a directory](https://wicg.github.io/entries-api/#dom-htmlinputelement-webkitdirectory). + +For edge cases, like POST request to URL with query string or to pass HTTP auth credentials, object can be passed to `form.submit()` as first parameter: + +``` javascript +form.submit({ + host: 'example.com', + path: '/probably.php?extra=params', + auth: 'username:password' +}, function(err, res) { + console.log(res.statusCode); +}); +``` + +In case you need to also send custom HTTP headers with the POST request, you can use the `headers` key in first parameter of `form.submit()`: + +``` javascript +form.submit({ + host: 'example.com', + path: '/surelynot.php', + headers: {'x-test-header': 'test-header-value'} +}, function(err, res) { + console.log(res.statusCode); +}); +``` + +### Methods + +- [_Void_ append( **String** _field_, **Mixed** _value_ [, **Mixed** _options_] )](https://github.com/form-data/form-data#void-append-string-field-mixed-value--mixed-options-). +- [_Headers_ getHeaders( [**Headers** _userHeaders_] )](https://github.com/form-data/form-data#array-getheaders-array-userheaders-) +- [_String_ getBoundary()](https://github.com/form-data/form-data#string-getboundary) +- [_Void_ setBoundary()](https://github.com/form-data/form-data#void-setboundary) +- [_Buffer_ getBuffer()](https://github.com/form-data/form-data#buffer-getbuffer) +- [_Integer_ getLengthSync()](https://github.com/form-data/form-data#integer-getlengthsync) +- [_Integer_ getLength( **function** _callback_ )](https://github.com/form-data/form-data#integer-getlength-function-callback-) +- [_Boolean_ hasKnownLength()](https://github.com/form-data/form-data#boolean-hasknownlength) +- [_Request_ submit( _params_, **function** _callback_ )](https://github.com/form-data/form-data#request-submit-params-function-callback-) +- [_String_ toString()](https://github.com/form-data/form-data#string-tostring) + +#### _Void_ append( **String** _field_, **Mixed** _value_ [, **Mixed** _options_] ) +Append data to the form. You can submit about any format (string, integer, boolean, buffer, etc.). However, Arrays are not supported and need to be turned into strings by the user. +```javascript +var form = new FormData(); +form.append( 'my_string', 'my value' ); +form.append( 'my_integer', 1 ); +form.append( 'my_boolean', true ); +form.append( 'my_buffer', new Buffer(10) ); +form.append( 'my_array_as_json', JSON.stringify( ['bird','cute'] ) ) +``` + +You may provide a string for options, or an object. +```javascript +// Set filename by providing a string for options +form.append( 'my_file', fs.createReadStream('/foo/bar.jpg'), 'bar.jpg' ); + +// provide an object. +form.append( 'my_file', fs.createReadStream('/foo/bar.jpg'), {filename: 'bar.jpg', contentType: 'image/jpeg', knownLength: 19806} ); +``` + +#### _Headers_ getHeaders( [**Headers** _userHeaders_] ) +This method adds the correct `content-type` header to the provided array of `userHeaders`. + +#### _String_ getBoundary() +Return the boundary of the formData. By default, the boundary consists of 26 `-` followed by 24 numbers +for example: +```javascript +--------------------------515890814546601021194782 +``` + +#### _Void_ setBoundary(String _boundary_) +Set the boundary string, overriding the default behavior described above. + +_Note: The boundary must be unique and may not appear in the data._ + +#### _Buffer_ getBuffer() +Return the full formdata request package, as a Buffer. You can insert this Buffer in e.g. Axios to send multipart data. +```javascript +var form = new FormData(); +form.append( 'my_buffer', Buffer.from([0x4a,0x42,0x20,0x52,0x6f,0x63,0x6b,0x73]) ); +form.append( 'my_file', fs.readFileSync('/foo/bar.jpg') ); + +axios.post( 'https://example.com/path/to/api', + form.getBuffer(), + form.getHeaders() + ) +``` +**Note:** Because the output is of type Buffer, you can only append types that are accepted by Buffer: *string, Buffer, ArrayBuffer, Array, or Array-like Object*. A ReadStream for example will result in an error. + +#### _Integer_ getLengthSync() +Same as `getLength` but synchronous. + +_Note: getLengthSync __doesn't__ calculate streams length._ + +#### _Integer_ getLength( **function** _callback_ ) +Returns the `Content-Length` async. The callback is used to handle errors and continue once the length has been calculated +```javascript +this.getLength(function(err, length) { + if (err) { + this._error(err); + return; + } + + // add content length + request.setHeader('Content-Length', length); + + ... +}.bind(this)); +``` + +#### _Boolean_ hasKnownLength() +Checks if the length of added values is known. + +#### _Request_ submit( _params_, **function** _callback_ ) +Submit the form to a web application. +```javascript +var form = new FormData(); +form.append( 'my_string', 'Hello World' ); + +form.submit( 'http://example.com/', function(err, res) { + // res – response object (http.IncomingMessage) // + res.resume(); +} ); +``` + +#### _String_ toString() +Returns the form data as a string. Don't use this if you are sending files or buffers, use `getBuffer()` instead. + +### Integration with other libraries + +#### Request + +Form submission using [request](https://github.com/request/request): + +```javascript +var formData = { + my_field: 'my_value', + my_file: fs.createReadStream(__dirname + '/unicycle.jpg'), +}; + +request.post({url:'http://service.com/upload', formData: formData}, function(err, httpResponse, body) { + if (err) { + return console.error('upload failed:', err); + } + console.log('Upload successful! Server responded with:', body); +}); +``` + +For more details see [request readme](https://github.com/request/request#multipartform-data-multipart-form-uploads). + +#### node-fetch + +You can also submit a form using [node-fetch](https://github.com/bitinn/node-fetch): + +```javascript +var form = new FormData(); + +form.append('a', 1); + +fetch('http://example.com', { method: 'POST', body: form }) + .then(function(res) { + return res.json(); + }).then(function(json) { + console.log(json); + }); +``` + +#### axios + +In Node.js you can post a file using [axios](https://github.com/axios/axios): +```javascript +const form = new FormData(); +const stream = fs.createReadStream(PATH_TO_FILE); + +form.append('image', stream); + +// In Node.js environment you need to set boundary in the header field 'Content-Type' by calling method `getHeaders` +const formHeaders = form.getHeaders(); + +axios.post('http://example.com', form, { + headers: { + ...formHeaders, + }, +}) +.then(response => response) +.catch(error => error) +``` + +## Notes + +- ```getLengthSync()``` method DOESN'T calculate length for streams, use ```knownLength``` options as workaround. +- ```getLength(cb)``` will send an error as first parameter of callback if stream length cannot be calculated (e.g. send in custom streams w/o using ```knownLength```). +- ```submit``` will not add `content-length` if form length is unknown or not calculable. +- Starting version `2.x` FormData has dropped support for `node@0.10.x`. +- Starting version `3.x` FormData has dropped support for `node@4.x`. + +## License + +Form-Data is released under the [MIT](License) license. diff --git a/3-asynchronous-JS/node_modules/form-data/index.d.ts b/3-asynchronous-JS/node_modules/form-data/index.d.ts new file mode 100644 index 0000000000..295e9e9bc5 --- /dev/null +++ b/3-asynchronous-JS/node_modules/form-data/index.d.ts @@ -0,0 +1,62 @@ +// Definitions by: Carlos Ballesteros Velasco +// Leon Yu +// BendingBender +// Maple Miao + +/// +import * as stream from 'stream'; +import * as http from 'http'; + +export = FormData; + +// Extracted because @types/node doesn't export interfaces. +interface ReadableOptions { + highWaterMark?: number; + encoding?: string; + objectMode?: boolean; + read?(this: stream.Readable, size: number): void; + destroy?(this: stream.Readable, error: Error | null, callback: (error: Error | null) => void): void; + autoDestroy?: boolean; +} + +interface Options extends ReadableOptions { + writable?: boolean; + readable?: boolean; + dataSize?: number; + maxDataSize?: number; + pauseStreams?: boolean; +} + +declare class FormData extends stream.Readable { + constructor(options?: Options); + append(key: string, value: any, options?: FormData.AppendOptions | string): void; + getHeaders(userHeaders?: FormData.Headers): FormData.Headers; + submit( + params: string | FormData.SubmitOptions, + callback?: (error: Error | null, response: http.IncomingMessage) => void + ): http.ClientRequest; + getBuffer(): Buffer; + setBoundary(boundary: string): void; + getBoundary(): string; + getLength(callback: (err: Error | null, length: number) => void): void; + getLengthSync(): number; + hasKnownLength(): boolean; +} + +declare namespace FormData { + interface Headers { + [key: string]: any; + } + + interface AppendOptions { + header?: string | Headers; + knownLength?: number; + filename?: string; + filepath?: string; + contentType?: string; + } + + interface SubmitOptions extends http.RequestOptions { + protocol?: 'https:' | 'http:'; + } +} diff --git a/3-asynchronous-JS/node_modules/form-data/lib/browser.js b/3-asynchronous-JS/node_modules/form-data/lib/browser.js new file mode 100644 index 0000000000..09e7c70e6e --- /dev/null +++ b/3-asynchronous-JS/node_modules/form-data/lib/browser.js @@ -0,0 +1,2 @@ +/* eslint-env browser */ +module.exports = typeof self == 'object' ? self.FormData : window.FormData; diff --git a/3-asynchronous-JS/node_modules/form-data/lib/form_data.js b/3-asynchronous-JS/node_modules/form-data/lib/form_data.js new file mode 100644 index 0000000000..e05c8f1ae2 --- /dev/null +++ b/3-asynchronous-JS/node_modules/form-data/lib/form_data.js @@ -0,0 +1,501 @@ +var CombinedStream = require('combined-stream'); +var util = require('util'); +var path = require('path'); +var http = require('http'); +var https = require('https'); +var parseUrl = require('url').parse; +var fs = require('fs'); +var Stream = require('stream').Stream; +var mime = require('mime-types'); +var asynckit = require('asynckit'); +var populate = require('./populate.js'); + +// Public API +module.exports = FormData; + +// make it a Stream +util.inherits(FormData, CombinedStream); + +/** + * Create readable "multipart/form-data" streams. + * Can be used to submit forms + * and file uploads to other web applications. + * + * @constructor + * @param {Object} options - Properties to be added/overriden for FormData and CombinedStream + */ +function FormData(options) { + if (!(this instanceof FormData)) { + return new FormData(options); + } + + this._overheadLength = 0; + this._valueLength = 0; + this._valuesToMeasure = []; + + CombinedStream.call(this); + + options = options || {}; + for (var option in options) { + this[option] = options[option]; + } +} + +FormData.LINE_BREAK = '\r\n'; +FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream'; + +FormData.prototype.append = function(field, value, options) { + + options = options || {}; + + // allow filename as single option + if (typeof options == 'string') { + options = {filename: options}; + } + + var append = CombinedStream.prototype.append.bind(this); + + // all that streamy business can't handle numbers + if (typeof value == 'number') { + value = '' + value; + } + + // https://github.com/felixge/node-form-data/issues/38 + if (Array.isArray(value)) { + // Please convert your array into string + // the way web server expects it + this._error(new Error('Arrays are not supported.')); + return; + } + + var header = this._multiPartHeader(field, value, options); + var footer = this._multiPartFooter(); + + append(header); + append(value); + append(footer); + + // pass along options.knownLength + this._trackLength(header, value, options); +}; + +FormData.prototype._trackLength = function(header, value, options) { + var valueLength = 0; + + // used w/ getLengthSync(), when length is known. + // e.g. for streaming directly from a remote server, + // w/ a known file a size, and not wanting to wait for + // incoming file to finish to get its size. + if (options.knownLength != null) { + valueLength += +options.knownLength; + } else if (Buffer.isBuffer(value)) { + valueLength = value.length; + } else if (typeof value === 'string') { + valueLength = Buffer.byteLength(value); + } + + this._valueLength += valueLength; + + // @check why add CRLF? does this account for custom/multiple CRLFs? + this._overheadLength += + Buffer.byteLength(header) + + FormData.LINE_BREAK.length; + + // empty or either doesn't have path or not an http response or not a stream + if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) && !(value instanceof Stream))) { + return; + } + + // no need to bother with the length + if (!options.knownLength) { + this._valuesToMeasure.push(value); + } +}; + +FormData.prototype._lengthRetriever = function(value, callback) { + + if (value.hasOwnProperty('fd')) { + + // take read range into a account + // `end` = Infinity –> read file till the end + // + // TODO: Looks like there is bug in Node fs.createReadStream + // it doesn't respect `end` options without `start` options + // Fix it when node fixes it. + // https://github.com/joyent/node/issues/7819 + if (value.end != undefined && value.end != Infinity && value.start != undefined) { + + // when end specified + // no need to calculate range + // inclusive, starts with 0 + callback(null, value.end + 1 - (value.start ? value.start : 0)); + + // not that fast snoopy + } else { + // still need to fetch file size from fs + fs.stat(value.path, function(err, stat) { + + var fileSize; + + if (err) { + callback(err); + return; + } + + // update final size based on the range options + fileSize = stat.size - (value.start ? value.start : 0); + callback(null, fileSize); + }); + } + + // or http response + } else if (value.hasOwnProperty('httpVersion')) { + callback(null, +value.headers['content-length']); + + // or request stream http://github.com/mikeal/request + } else if (value.hasOwnProperty('httpModule')) { + // wait till response come back + value.on('response', function(response) { + value.pause(); + callback(null, +response.headers['content-length']); + }); + value.resume(); + + // something else + } else { + callback('Unknown stream'); + } +}; + +FormData.prototype._multiPartHeader = function(field, value, options) { + // custom header specified (as string)? + // it becomes responsible for boundary + // (e.g. to handle extra CRLFs on .NET servers) + if (typeof options.header == 'string') { + return options.header; + } + + var contentDisposition = this._getContentDisposition(value, options); + var contentType = this._getContentType(value, options); + + var contents = ''; + var headers = { + // add custom disposition as third element or keep it two elements if not + 'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []), + // if no content type. allow it to be empty array + 'Content-Type': [].concat(contentType || []) + }; + + // allow custom headers. + if (typeof options.header == 'object') { + populate(headers, options.header); + } + + var header; + for (var prop in headers) { + if (!headers.hasOwnProperty(prop)) continue; + header = headers[prop]; + + // skip nullish headers. + if (header == null) { + continue; + } + + // convert all headers to arrays. + if (!Array.isArray(header)) { + header = [header]; + } + + // add non-empty headers. + if (header.length) { + contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK; + } + } + + return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK; +}; + +FormData.prototype._getContentDisposition = function(value, options) { + + var filename + , contentDisposition + ; + + if (typeof options.filepath === 'string') { + // custom filepath for relative paths + filename = path.normalize(options.filepath).replace(/\\/g, '/'); + } else if (options.filename || value.name || value.path) { + // custom filename take precedence + // formidable and the browser add a name property + // fs- and request- streams have path property + filename = path.basename(options.filename || value.name || value.path); + } else if (value.readable && value.hasOwnProperty('httpVersion')) { + // or try http response + filename = path.basename(value.client._httpMessage.path || ''); + } + + if (filename) { + contentDisposition = 'filename="' + filename + '"'; + } + + return contentDisposition; +}; + +FormData.prototype._getContentType = function(value, options) { + + // use custom content-type above all + var contentType = options.contentType; + + // or try `name` from formidable, browser + if (!contentType && value.name) { + contentType = mime.lookup(value.name); + } + + // or try `path` from fs-, request- streams + if (!contentType && value.path) { + contentType = mime.lookup(value.path); + } + + // or if it's http-reponse + if (!contentType && value.readable && value.hasOwnProperty('httpVersion')) { + contentType = value.headers['content-type']; + } + + // or guess it from the filepath or filename + if (!contentType && (options.filepath || options.filename)) { + contentType = mime.lookup(options.filepath || options.filename); + } + + // fallback to the default content type if `value` is not simple value + if (!contentType && typeof value == 'object') { + contentType = FormData.DEFAULT_CONTENT_TYPE; + } + + return contentType; +}; + +FormData.prototype._multiPartFooter = function() { + return function(next) { + var footer = FormData.LINE_BREAK; + + var lastPart = (this._streams.length === 0); + if (lastPart) { + footer += this._lastBoundary(); + } + + next(footer); + }.bind(this); +}; + +FormData.prototype._lastBoundary = function() { + return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK; +}; + +FormData.prototype.getHeaders = function(userHeaders) { + var header; + var formHeaders = { + 'content-type': 'multipart/form-data; boundary=' + this.getBoundary() + }; + + for (header in userHeaders) { + if (userHeaders.hasOwnProperty(header)) { + formHeaders[header.toLowerCase()] = userHeaders[header]; + } + } + + return formHeaders; +}; + +FormData.prototype.setBoundary = function(boundary) { + this._boundary = boundary; +}; + +FormData.prototype.getBoundary = function() { + if (!this._boundary) { + this._generateBoundary(); + } + + return this._boundary; +}; + +FormData.prototype.getBuffer = function() { + var dataBuffer = new Buffer.alloc( 0 ); + var boundary = this.getBoundary(); + + // Create the form content. Add Line breaks to the end of data. + for (var i = 0, len = this._streams.length; i < len; i++) { + if (typeof this._streams[i] !== 'function') { + + // Add content to the buffer. + if(Buffer.isBuffer(this._streams[i])) { + dataBuffer = Buffer.concat( [dataBuffer, this._streams[i]]); + }else { + dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(this._streams[i])]); + } + + // Add break after content. + if (typeof this._streams[i] !== 'string' || this._streams[i].substring( 2, boundary.length + 2 ) !== boundary) { + dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(FormData.LINE_BREAK)] ); + } + } + } + + // Add the footer and return the Buffer object. + return Buffer.concat( [dataBuffer, Buffer.from(this._lastBoundary())] ); +}; + +FormData.prototype._generateBoundary = function() { + // This generates a 50 character boundary similar to those used by Firefox. + // They are optimized for boyer-moore parsing. + var boundary = '--------------------------'; + for (var i = 0; i < 24; i++) { + boundary += Math.floor(Math.random() * 10).toString(16); + } + + this._boundary = boundary; +}; + +// Note: getLengthSync DOESN'T calculate streams length +// As workaround one can calculate file size manually +// and add it as knownLength option +FormData.prototype.getLengthSync = function() { + var knownLength = this._overheadLength + this._valueLength; + + // Don't get confused, there are 3 "internal" streams for each keyval pair + // so it basically checks if there is any value added to the form + if (this._streams.length) { + knownLength += this._lastBoundary().length; + } + + // https://github.com/form-data/form-data/issues/40 + if (!this.hasKnownLength()) { + // Some async length retrievers are present + // therefore synchronous length calculation is false. + // Please use getLength(callback) to get proper length + this._error(new Error('Cannot calculate proper length in synchronous way.')); + } + + return knownLength; +}; + +// Public API to check if length of added values is known +// https://github.com/form-data/form-data/issues/196 +// https://github.com/form-data/form-data/issues/262 +FormData.prototype.hasKnownLength = function() { + var hasKnownLength = true; + + if (this._valuesToMeasure.length) { + hasKnownLength = false; + } + + return hasKnownLength; +}; + +FormData.prototype.getLength = function(cb) { + var knownLength = this._overheadLength + this._valueLength; + + if (this._streams.length) { + knownLength += this._lastBoundary().length; + } + + if (!this._valuesToMeasure.length) { + process.nextTick(cb.bind(this, null, knownLength)); + return; + } + + asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) { + if (err) { + cb(err); + return; + } + + values.forEach(function(length) { + knownLength += length; + }); + + cb(null, knownLength); + }); +}; + +FormData.prototype.submit = function(params, cb) { + var request + , options + , defaults = {method: 'post'} + ; + + // parse provided url if it's string + // or treat it as options object + if (typeof params == 'string') { + + params = parseUrl(params); + options = populate({ + port: params.port, + path: params.pathname, + host: params.hostname, + protocol: params.protocol + }, defaults); + + // use custom params + } else { + + options = populate(params, defaults); + // if no port provided use default one + if (!options.port) { + options.port = options.protocol == 'https:' ? 443 : 80; + } + } + + // put that good code in getHeaders to some use + options.headers = this.getHeaders(params.headers); + + // https if specified, fallback to http in any other case + if (options.protocol == 'https:') { + request = https.request(options); + } else { + request = http.request(options); + } + + // get content length and fire away + this.getLength(function(err, length) { + if (err && err !== 'Unknown stream') { + this._error(err); + return; + } + + // add content length + if (length) { + request.setHeader('Content-Length', length); + } + + this.pipe(request); + if (cb) { + var onResponse; + + var callback = function (error, responce) { + request.removeListener('error', callback); + request.removeListener('response', onResponse); + + return cb.call(this, error, responce); + }; + + onResponse = callback.bind(this, null); + + request.on('error', callback); + request.on('response', onResponse); + } + }.bind(this)); + + return request; +}; + +FormData.prototype._error = function(err) { + if (!this.error) { + this.error = err; + this.pause(); + this.emit('error', err); + } +}; + +FormData.prototype.toString = function () { + return '[object FormData]'; +}; diff --git a/3-asynchronous-JS/node_modules/form-data/lib/populate.js b/3-asynchronous-JS/node_modules/form-data/lib/populate.js new file mode 100644 index 0000000000..4d35738dd5 --- /dev/null +++ b/3-asynchronous-JS/node_modules/form-data/lib/populate.js @@ -0,0 +1,10 @@ +// populates missing values +module.exports = function(dst, src) { + + Object.keys(src).forEach(function(prop) + { + dst[prop] = dst[prop] || src[prop]; + }); + + return dst; +}; diff --git a/3-asynchronous-JS/node_modules/form-data/package.json b/3-asynchronous-JS/node_modules/form-data/package.json new file mode 100644 index 0000000000..9bd12c9510 --- /dev/null +++ b/3-asynchronous-JS/node_modules/form-data/package.json @@ -0,0 +1,71 @@ +{ + "author": "Felix Geisendörfer (http://debuggable.com/)", + "name": "form-data", + "description": "A library to create readable \"multipart/form-data\" streams. Can be used to submit forms and file uploads to other web applications.", + "version": "4.0.1", + "repository": { + "type": "git", + "url": "git://github.com/form-data/form-data.git" + }, + "main": "./lib/form_data", + "browser": "./lib/browser", + "typings": "./index.d.ts", + "scripts": { + "pretest": "npm run lint", + "pretests-only": "rimraf coverage test/tmp", + "tests-only": "istanbul cover test/run.js", + "posttests-only": "istanbul report lcov text", + "test": "npm run tests-only", + "posttest": "npx npm@'>=10.2' audit --production", + "lint": "eslint --ext=js,mjs .", + "report": "istanbul report lcov text", + "ci-lint": "is-node-modern 8 && npm run lint || is-node-not-modern 8", + "ci-test": "npm run tests-only && npm run browser && npm run report", + "predebug": "rimraf coverage test/tmp", + "debug": "verbose=1 ./test/run.js", + "browser": "browserify -t browserify-istanbul test/run-browser.js | obake --coverage", + "check": "istanbul check-coverage coverage/coverage*.json", + "files": "pkgfiles --sort=name", + "get-version": "node -e \"console.log(require('./package.json').version)\"", + "update-readme": "sed -i.bak 's/\\/master\\.svg/\\/v'$(npm --silent run get-version)'.svg/g' README.md", + "restore-readme": "mv README.md.bak README.md", + "prepublish": "in-publish && npm run update-readme || not-in-publish", + "postpublish": "npm run restore-readme" + }, + "pre-commit": [ + "lint", + "ci-test", + "check" + ], + "engines": { + "node": ">= 6" + }, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "devDependencies": { + "@types/node": "^12.0.10", + "browserify": "^13.1.1", + "browserify-istanbul": "^2.0.0", + "coveralls": "^3.0.4", + "cross-spawn": "^6.0.5", + "eslint": "^6.0.1", + "fake": "^0.2.2", + "far": "^0.0.7", + "formidable": "^1.0.17", + "in-publish": "^2.0.0", + "is-node-modern": "^1.0.0", + "istanbul": "^0.4.5", + "obake": "^0.1.2", + "puppeteer": "^1.19.0", + "pkgfiles": "^2.3.0", + "pre-commit": "^1.1.3", + "request": "^2.88.0", + "rimraf": "^2.7.1", + "tape": "^4.6.2", + "typescript": "^3.5.2" + }, + "license": "MIT" +} diff --git a/3-asynchronous-JS/node_modules/formidable/LICENSE b/3-asynchronous-JS/node_modules/formidable/LICENSE new file mode 100644 index 0000000000..5e7ad11752 --- /dev/null +++ b/3-asynchronous-JS/node_modules/formidable/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2011-present Felix Geisendörfer, and contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/3-asynchronous-JS/node_modules/formidable/README.md b/3-asynchronous-JS/node_modules/formidable/README.md new file mode 100644 index 0000000000..b1f1293444 --- /dev/null +++ b/3-asynchronous-JS/node_modules/formidable/README.md @@ -0,0 +1,884 @@ +

+ npm formidable package logo +

+ +# formidable [![npm version][npmv-img]][npmv-url] [![MIT license][license-img]][license-url] [![Libera Manifesto][libera-manifesto-img]][libera-manifesto-url] [![Twitter][twitter-img]][twitter-url] + +> A Node.js module for parsing form data, especially file uploads. + +[![Code style][codestyle-img]][codestyle-url] +[![codecoverage][codecov-img]][codecov-url] +[![linux build status][linux-build-img]][build-url] +[![windows build status][windows-build-img]][build-url] +[![macos build status][macos-build-img]][build-url] + +If you have any _how-to_ kind of questions, please read the [Contributing +Guide][contributing-url] and [Code of Conduct][code_of_conduct-url] +documents.
For bugs reports and feature requests, [please create an +issue][open-issue-url] or ping [@tunnckoCore / @3a1FcBx0](https://twitter.com/3a1FcBx0) +at Twitter. + +[![Conventional Commits][ccommits-img]][ccommits-url] +[![Minimum Required Nodejs][nodejs-img]][npmv-url] +[![Tidelift Subscription][tidelift-img]][tidelift-url] +[![Buy me a Kofi][kofi-img]][kofi-url] +[![Renovate App Status][renovateapp-img]][renovateapp-url] +[![Make A Pull Request][prs-welcome-img]][prs-welcome-url] + +This project is [semantically versioned](https://semver.org) and available as +part of the [Tidelift Subscription][tidelift-url] for professional grade +assurances, enhanced support and security. +[Learn more.](https://tidelift.com/subscription/pkg/npm-formidable?utm_source=npm-formidable&utm_medium=referral&utm_campaign=enterprise) + +_The maintainers of `formidable` 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._ + +[![][npm-weekly-img]][npmv-url] [![][npm-monthly-img]][npmv-url] +[![][npm-yearly-img]][npmv-url] [![][npm-alltime-img]][npmv-url] + +## Project Status: Maintained + +_Check [VERSION NOTES](https://github.com/node-formidable/formidable/blob/master/VERSION_NOTES.md) for more information on v1, v2, and v3 plans, NPM dist-tags and branches._ + +This module was initially developed by +[**@felixge**](https://github.com/felixge) for +[Transloadit](http://transloadit.com/), a service focused on uploading and +encoding images and videos. It has been battle-tested against hundreds of GBs of +file uploads from a large variety of clients and is considered production-ready +and is used in production for years. + +Currently, we are few maintainers trying to deal with it. :) More contributors +are always welcome! :heart: Jump on +[issue #412](https://github.com/felixge/node-formidable/issues/412) which is +closed, but if you are interested we can discuss it and add you after strict +rules, like enabling Two-Factor Auth in your npm and GitHub accounts. + +## Highlights + +- [Fast (~900-2500 mb/sec)](#benchmarks) & streaming multipart parser +- Automatically writing file uploads to disk (optional, see + [`options.fileWriteStreamHandler`](#options)) +- [Plugins API](#useplugin-plugin) - allowing custom parsers and plugins +- Low memory footprint +- Graceful error handling +- Very high test coverage + +## Install + +This package is a dual ESM/commonjs package. + +This project requires `Node.js >= 10.13`. Install it using +[yarn](https://yarnpkg.com) or [npm](https://npmjs.com).
_We highly +recommend to use Yarn when you think to contribute to this project._ + +This is a low-level package, and if you're using a high-level framework it _may_ +already be included. Check the examples below and the [examples/](https://github.com/node-formidable/formidable/tree/master/examples) folder. + +``` +# v2 +npm install formidable@v2 + +# v3 +npm install formidable +npm install formidable@v3 +``` + +_**Note:** Future not ready releases will be published on `*-next` dist-tags for the corresponding version._ + + +## Examples + +For more examples look at the `examples/` directory. + +### with Node.js http module + +Parse an incoming file upload, with the +[Node.js's built-in `http` module](https://nodejs.org/api/http.html). + +```js +import http from 'node:http'; +import formidable, {errors as formidableErrors} from 'formidable'; + +const server = http.createServer(async (req, res) => { + if (req.url === '/api/upload' && req.method.toLowerCase() === 'post') { + // parse a file upload + const form = formidable({}); + let fields; + let files; + try { + [fields, files] = await form.parse(req); + } catch (err) { + // example to check for a very specific error + if (err.code === formidableErrors.maxFieldsExceeded) { + + } + console.error(err); + res.writeHead(err.httpCode || 400, { 'Content-Type': 'text/plain' }); + res.end(String(err)); + return; + } + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ fields, files }, null, 2)); + return; + } + + // show a file upload form + res.writeHead(200, { 'Content-Type': 'text/html' }); + res.end(` +

With Node.js "http" module

+
+
Text field title:
+
File:
+ +
+ `); +}); + +server.listen(8080, () => { + console.log('Server listening on http://localhost:8080/ ...'); +}); +``` + +### with Express.js + +There are multiple variants to do this, but Formidable just need Node.js Request +stream, so something like the following example should work just fine, without +any third-party [Express.js](https://ghub.now.sh/express) middleware. + +Or try the +[examples/with-express.js](https://github.com/node-formidable/formidable/blob/master/examples/with-express.js) + +```js +import express from 'express'; +import formidable from 'formidable'; + +const app = express(); + +app.get('/', (req, res) => { + res.send(` +

With "express" npm package

+
+
Text field title:
+
File:
+ +
+ `); +}); + +app.post('/api/upload', (req, res, next) => { + const form = formidable({}); + + form.parse(req, (err, fields, files) => { + if (err) { + next(err); + return; + } + res.json({ fields, files }); + }); +}); + +app.listen(3000, () => { + console.log('Server listening on http://localhost:3000 ...'); +}); +``` + +### with Koa and Formidable + +Of course, with [Koa v1, v2 or future v3](https://ghub.now.sh/koa) the things +are very similar. You can use `formidable` manually as shown below or through +the [koa-better-body](https://ghub.now.sh/koa-better-body) package which is +using `formidable` under the hood and support more features and different +request bodies, check its documentation for more info. + +_Note: this example is assuming Koa v2. Be aware that you should pass `ctx.req` +which is Node.js's Request, and **NOT** the `ctx.request` which is Koa's Request +object - there is a difference._ + +```js +import Koa from 'Koa'; +import formidable from 'formidable'; + +const app = new Koa(); + +app.on('error', (err) => { + console.error('server error', err); +}); + +app.use(async (ctx, next) => { + if (ctx.url === '/api/upload' && ctx.method.toLowerCase() === 'post') { + const form = formidable({}); + + // not very elegant, but that's for now if you don't want to use `koa-better-body` + // or other middlewares. + await new Promise((resolve, reject) => { + form.parse(ctx.req, (err, fields, files) => { + if (err) { + reject(err); + return; + } + + ctx.set('Content-Type', 'application/json'); + ctx.status = 200; + ctx.state = { fields, files }; + ctx.body = JSON.stringify(ctx.state, null, 2); + resolve(); + }); + }); + await next(); + return; + } + + // show a file upload form + ctx.set('Content-Type', 'text/html'); + ctx.status = 200; + ctx.body = ` +

With "koa" npm package

+
+
Text field title:
+
File:
+ +
+ `; +}); + +app.use((ctx) => { + console.log('The next middleware is called'); + console.log('Results:', ctx.state); +}); + +app.listen(3000, () => { + console.log('Server listening on http://localhost:3000 ...'); +}); +``` + +## Benchmarks + +The benchmark is quite old, from the old codebase. But maybe quite true though. +Previously the numbers was around ~500 mb/sec. Currently with moving to the new +Node.js Streams API it's faster. You can clearly see the differences between the +Node versions. + +_Note: a lot better benchmarking could and should be done in future._ + +Benchmarked on 8GB RAM, Xeon X3440 (2.53 GHz, 4 cores, 8 threads) + +``` +~/github/node-formidable master +❯ nve --parallel 8 10 12 13 node benchmark/bench-multipart-parser.js + + ⬢ Node 8 + +1261.08 mb/sec + + ⬢ Node 10 + +1113.04 mb/sec + + ⬢ Node 12 + +2107.00 mb/sec + + ⬢ Node 13 + +2566.42 mb/sec +``` + +![benchmark January 29th, 2020](./benchmark/2020-01-29_xeon-x3440.png) + +## API + +### Formidable / IncomingForm + +All shown are equivalent. + +_Please pass [`options`](#options) to the function/constructor, not by assigning +them to the instance `form`_ + +```js +import formidable from 'formidable'; +const form = formidable(options); +``` + +### Options + +See it's defaults in [src/Formidable.js DEFAULT_OPTIONS](./src/Formidable.js) +(the `DEFAULT_OPTIONS` constant). + +- `options.encoding` **{string}** - default `'utf-8'`; sets encoding for + incoming form fields, +- `options.uploadDir` **{string}** - default `os.tmpdir()`; the directory for + placing file uploads in. You can move them later by using `fs.rename()`. +- `options.keepExtensions` **{boolean}** - default `false`; to include the + extensions of the original files or not +- `options.allowEmptyFiles` **{boolean}** - default `false`; allow upload empty + files +- `options.minFileSize` **{number}** - default `1` (1byte); the minium size of + uploaded file. +- `options.maxFiles` **{number}** - default `Infinity`; + limit the amount of uploaded files, set Infinity for unlimited +- `options.maxFileSize` **{number}** - default `200 * 1024 * 1024` (200mb); + limit the size of each uploaded file. +- `options.maxTotalFileSize` **{number}** - default `options.maxFileSize`; + limit the size of the batch of uploaded files. +- `options.maxFields` **{number}** - default `1000`; limit the number of fields, set Infinity for unlimited +- `options.maxFieldsSize` **{number}** - default `20 * 1024 * 1024` (20mb); + limit the amount of memory all fields together (except files) can allocate in + bytes. +- `options.hashAlgorithm` **{string | false}** - default `false`; include checksums calculated + for incoming files, set this to some hash algorithm, see + [crypto.createHash](https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm_options) + for available algorithms +- `options.fileWriteStreamHandler` **{function}** - default `null`, which by + default writes to host machine file system every file parsed; The function + should return an instance of a + [Writable stream](https://nodejs.org/api/stream.html#stream_class_stream_writable) + that will receive the uploaded file data. With this option, you can have any + custom behavior regarding where the uploaded file data will be streamed for. + If you are looking to write the file uploaded in other types of cloud storages + (AWS S3, Azure blob storage, Google cloud storage) or private file storage, + this is the option you're looking for. When this option is defined the default + behavior of writing the file in the host machine file system is lost. +- `options.filename` **{function}** - default `undefined` Use it to control + newFilename. Must return a string. Will be joined with options.uploadDir. + +- `options.filter` **{function}** - default function that always returns true. + Use it to filter files before they are uploaded. Must return a boolean. Will not make the form.parse error + +- `options.createDirsFromUploads` **{boolean}** - default false. If true, makes direct folder uploads possible. Use `` to create a form to upload folders. Has to be used with the options `options.uploadDir` and `options.filename` where `options.filename` has to return a string with the character `/` for folders to be created. The base will be `options.uploadDir`. + + +#### `options.filename` **{function}** function (name, ext, part, form) -> string + +where part can be decomposed as + +```js +const { originalFilename, mimetype} = part; +``` + +_**Note:** If this size of combined fields, or size of some file is exceeded, an +`'error'` event is fired._ + +```js +// The amount of bytes received for this form so far. +form.bytesReceived; +``` + +```js +// The expected number of bytes in this form. +form.bytesExpected; +``` + +#### `options.filter` **{function}** function ({name, originalFilename, mimetype}) -> boolean + +Behaves like Array.filter: Returning false will simply ignore the file and go to the next. + +```js +const options = { + filter: function ({name, originalFilename, mimetype}) { + // keep only images + return mimetype && mimetype.includes("image"); + } +}; +``` + +**Note:** use an outside variable to cancel all uploads upon the first error + +**Note:** use form.emit('error') to make form.parse error + +```js +let cancelUploads = false;// create variable at the same scope as form +const options = { + filter: function ({name, originalFilename, mimetype}) { + // keep only images + const valid = mimetype && mimetype.includes("image"); + if (!valid) { + form.emit('error', new formidableErrors.default('invalid type', 0, 400)); // optional make form.parse error + cancelUploads = true; //variable to make filter return false after the first problem + } + return valid && !cancelUploads; + } +}; +``` + + +### .parse(request, ?callback) + +Parses an incoming Node.js `request` containing form data. If `callback` is not provided a promise is returned. + +```js +const form = formidable({ uploadDir: __dirname }); + +form.parse(req, (err, fields, files) => { + console.log('fields:', fields); + console.log('files:', files); +}); + +// with Promise +const [fields, files] = await form.parse(req); +``` + +You may overwrite this method if you are interested in directly accessing the +multipart stream. Doing so will disable any `'field'` / `'file'` events +processing which would occur otherwise, making you fully responsible for +handling the processing. + +About `uploadDir`, given the following directory structure +``` +project-name +├── src +│ └── server.js +│ +└── uploads + └── image.jpg +``` + +`__dirname` would be the same directory as the source file itself (src) + + +```js + `${__dirname}/../uploads` +``` + +to put files in uploads. + +Omitting `__dirname` would make the path relative to the current working directory. This would be the same if server.js is launched from src but not project-name. + + +`null` will use default which is `os.tmpdir()` + +Note: If the directory does not exist, the uploaded files are __silently discarded__. To make sure it exists: + +```js +import {createNecessaryDirectoriesSync} from "filesac"; + + +const uploadPath = `${__dirname}/../uploads`; +createNecessaryDirectoriesSync(`${uploadPath}/x`); +``` + + +In the example below, we listen on couple of events and direct them to the +`data` listener, so you can do whatever you choose there, based on whether its +before the file been emitted, the header value, the header name, on field, on +file and etc. + +Or the other way could be to just override the `form.onPart` as it's shown a bit +later. + +```js +form.once('error', console.error); + +form.on('fileBegin', (formname, file) => { + form.emit('data', { name: 'fileBegin', formname, value: file }); +}); + +form.on('file', (formname, file) => { + form.emit('data', { name: 'file', formname, value: file }); +}); + +form.on('field', (fieldName, fieldValue) => { + form.emit('data', { name: 'field', key: fieldName, value: fieldValue }); +}); + +form.once('end', () => { + console.log('Done!'); +}); + +// If you want to customize whatever you want... +form.on('data', ({ name, key, value, buffer, start, end, formname, ...more }) => { + if (name === 'partBegin') { + } + if (name === 'partData') { + } + if (name === 'headerField') { + } + if (name === 'headerValue') { + } + if (name === 'headerEnd') { + } + if (name === 'headersEnd') { + } + if (name === 'field') { + console.log('field name:', key); + console.log('field value:', value); + } + if (name === 'file') { + console.log('file:', formname, value); + } + if (name === 'fileBegin') { + console.log('fileBegin:', formname, value); + } +}); +``` + +### .use(plugin: Plugin) + +A method that allows you to extend the Formidable library. By default we include +4 plugins, which essentially are adapters to plug the different built-in parsers. + +**The plugins added by this method are always enabled.** + +_See [src/plugins/](./src/plugins/) for more detailed look on default plugins._ + +The `plugin` param has such signature: + +```typescript +function(formidable: Formidable, options: Options): void; +``` + +The architecture is simple. The `plugin` is a function that is passed with the +Formidable instance (the `form` across the README examples) and the options. + +**Note:** the plugin function's `this` context is also the same instance. + +```js +const form = formidable({ keepExtensions: true }); + +form.use((self, options) => { + // self === this === form + console.log('woohoo, custom plugin'); + // do your stuff; check `src/plugins` for inspiration +}); + +form.parse(req, (error, fields, files) => { + console.log('done!'); +}); +``` + +**Important to note**, is that inside plugin `this.options`, `self.options` and +`options` MAY or MAY NOT be the same. General best practice is to always use the +`this`, so you can later test your plugin independently and more easily. + +If you want to disable some parsing capabilities of Formidable, you can disable +the plugin which corresponds to the parser. For example, if you want to disable +multipart parsing (so the [src/parsers/Multipart.js](./src/parsers/Multipart.js) +which is used in [src/plugins/multipart.js](./src/plugins/multipart.js)), then +you can remove it from the `options.enabledPlugins`, like so + +```js +import formidable, {octetstream, querystring, json} from "formidable"; +const form = formidable({ + hashAlgorithm: 'sha1', + enabledPlugins: [octetstream, querystring, json], +}); +``` + +**Be aware** that the order _MAY_ be important too. The names corresponds 1:1 to +files in [src/plugins/](./src/plugins) folder. + +Pull requests for new built-in plugins MAY be accepted - for example, more +advanced querystring parser. Add your plugin as a new file in `src/plugins/` +folder (lowercased) and follow how the other plugins are made. + +### form.onPart + +If you want to use Formidable to only handle certain parts for you, you can do +something similar. Or see +[#387](https://github.com/node-formidable/node-formidable/issues/387) for +inspiration, you can for example validate the mime-type. + +```js +const form = formidable(); + +form.onPart = (part) => { + part.on('data', (buffer) => { + // do whatever you want here + }); +}; +``` + +For example, force Formidable to be used only on non-file "parts" (i.e., html +fields) + +```js +const form = formidable(); + +form.onPart = function (part) { + // let formidable handle only non-file parts + if (part.originalFilename === '' || !part.mimetype) { + // used internally, please do not override! + form._handlePart(part); + } +}; +``` + +### File + +```ts +export interface File { + // The size of the uploaded file in bytes. + // If the file is still being uploaded (see `'fileBegin'` event), + // this property says how many bytes of the file have been written to disk yet. + file.size: number; + + // The path this file is being written to. You can modify this in the `'fileBegin'` event in + // case you are unhappy with the way formidable generates a temporary path for your files. + file.filepath: string; + + // The name this file had according to the uploading client. + file.originalFilename: string | null; + + // calculated based on options provided + file.newFilename: string | null; + + // The mime type of this file, according to the uploading client. + file.mimetype: string | null; + + // A Date object (or `null`) containing the time this file was last written to. + // Mostly here for compatibility with the [W3C File API Draft](http://dev.w3.org/2006/webapi/FileAPI/). + file.mtime: Date | null; + + file.hashAlgorithm: false | |'sha1' | 'md5' | 'sha256' + // If `options.hashAlgorithm` calculation was set, you can read the hex digest out of this var (at the end it will be a string) + file.hash: string | object | null; +} +``` + +#### file.toJSON() + +This method returns a JSON-representation of the file, allowing you to +`JSON.stringify()` the file which is useful for logging and responding to +requests. + +### Events + +#### `'progress'` + +Emitted after each incoming chunk of data that has been parsed. Can be used to +roll your own progress bar. **Warning** Use this only for server side progress bar. On the client side better use `XMLHttpRequest` with `xhr.upload.onprogress =` + +```js +form.on('progress', (bytesReceived, bytesExpected) => {}); +``` + +#### `'field'` + +Emitted whenever a field / value pair has been received. + +```js +form.on('field', (name, value) => {}); +``` + +#### `'fileBegin'` + +Emitted whenever a new file is detected in the upload stream. Use this event if +you want to stream the file to somewhere else while buffering the upload on the +file system. + +```js +form.on('fileBegin', (formName, file) => { + // accessible here + // formName the name in the form () or http filename for octetstream + // file.originalFilename http filename or null if there was a parsing error + // file.newFilename generated hexoid or what options.filename returned + // file.filepath default pathname as per options.uploadDir and options.filename + // file.filepath = CUSTOM_PATH // to change the final path +}); +``` + +#### `'file'` + +Emitted whenever a field / file pair has been received. `file` is an instance of +`File`. + +```js +form.on('file', (formname, file) => { + // same as fileBegin, except + // it is too late to change file.filepath + // file.hash is available if options.hash was used +}); +``` + +#### `'error'` + +Emitted when there is an error processing the incoming form. A request that +experiences an error is automatically paused, you will have to manually call +`request.resume()` if you want the request to continue firing `'data'` events. + +May have `error.httpCode` and `error.code` attached. + +```js +form.on('error', (err) => {}); +``` + +#### `'aborted'` + +Emitted when the request was aborted by the user. Right now this can be due to a +'timeout' or 'close' event on the socket. After this event is emitted, an +`error` event will follow. In the future there will be a separate 'timeout' +event (needs a change in the node core). + +```js +form.on('aborted', () => {}); +``` + +#### `'end'` + +Emitted when the entire request has been received, and all contained files have +finished flushing to disk. This is a great place for you to send your response. + +```js +form.on('end', () => {}); +``` + + +### Helpers + +#### firstValues + +Gets first values of fields, like pre 3.0.0 without multiples pass in a list of optional exceptions where arrays of strings is still wanted (` +
File:
+ + + `); +}); + +server.listen(8080, () => { + console.log('Server listening on http://localhost:8080/ ...'); +}); +``` + +### com Express.js + +Existem várias variantes para fazer isso, mas o Formidable só precisa do Node.js Request +stream, então algo como o exemplo a seguir deve funcionar bem, sem nenhum middleware [Express.js](https://ghub.now.sh/express) de terceiros. + +Ou tente o +[examples/with-express.js](https://github.com/node-formidable/formidable/blob/master/examples/with-express.js) + +```js +import express from 'express'; +import formidable from 'formidable'; + +const app = express(); + +app.get('/', (req, res) => { + res.send(` +

With "express" npm package

+
+
Text field title:
+
File:
+ +
+ `); +}); + +app.post('/api/upload', (req, res, next) => { + const form = formidable({}); + + form.parse(req, (err, fields, files) => { + if (err) { + next(err); + return; + } + res.json({ fields, files }); + }); +}); + +app.listen(3000, () => { + console.log('Server listening on http://localhost:3000 ...'); +}); +``` + +### com Koa e Formidable + +Claro, com [Koa v1, v2 ou future v3](https://ghub.now.sh/koa) as coisas +sao muito parecidas. Você pode usar `formidable` manualmente como mostrado abaixo ou através +do pacote [koa-better-body](https://ghub.now.sh/koa-better-body) que é +usando `formidable` sob o capô e suporte a mais recursos e diferentes +corpos de solicitação, verifique sua documentação para mais informações. + +_Nota: este exemplo está assumindo Koa v2. Esteja ciente de que você deve passar `ctx.req` +que é a solicitação do Node.js e **NÃO** o `ctx.request` que é a solicitação do Koa +objeto - há uma diferença._ + +```js +import Koa from 'Koa'; +import formidable from 'formidable'; + +const app = new Koa(); + +app.on('error', (err) => { + console.error('server error', err); +}); + +app.use(async (ctx, next) => { + if (ctx.url === '/api/upload' && ctx.method.toLowerCase() === 'post') { + const form = formidable({}); + + // não muito elegante, mas é por enquanto se você não quiser usar `koa-better-body` + // ou outros middlewares. + await new Promise((resolve, reject) => { + form.parse(ctx.req, (err, fields, files) => { + if (err) { + reject(err); + return; + } + + ctx.set('Content-Type', 'application/json'); + ctx.status = 200; + ctx.state = { fields, files }; + ctx.body = JSON.stringify(ctx.state, null, 2); + resolve(); + }); + }); + await next(); + return; + } + + // mostrar um formulário de upload de arquivo + ctx.set('Content-Type', 'text/html'); + ctx.status = 200; + ctx.body = ` +

With "koa" npm package

+
+
Text field title:
+
File:
+ +
+ `; +}); + +app.use((ctx) => { + console.log('The next middleware is called'); + console.log('Results:', ctx.state); +}); + +app.listen(3000, () => { + console.log('Server listening on http://localhost:3000 ...'); +}); +``` + +## Benchmarks + +O benchmark é bastante antigo, da antiga base de código. Mas talvez seja bem verdade. +Anteriormente, os números giravam em torno de ~ 500 mb/s. Atualmente com a mudança para o novo +Node.js Streams API, é mais rápido. Você pode ver claramente as diferenças entre as +versões do Node. + +_Observação: um benchmarking muito melhor pode e deve ser feito no futuro._ + +Benchmark realizado em 8 GB de RAM, Xeon X3440 (2,53 GHz, 4 núcleos, 8 threads) + +``` +~/github/node-formidable master +❯ nve --parallel 8 10 12 13 node benchmark/bench-multipart-parser.js + + ⬢ Node 8 + +1261.08 mb/sec + + ⬢ Node 10 + +1113.04 mb/sec + + ⬢ Node 12 + +2107.00 mb/sec + + ⬢ Node 13 + +2566.42 mb/sec +``` + +![benchmark 29 de janeiro de 2020](./benchmark/2020-01-29_xeon-x3440.png) + +## API + +### Formidable / IncomingForm + +Todos os mostrados são equivalentes. + +_Por favor, passe [`options`](#options) para a função/construtor, não atribuindo +eles para a instância `form`_ + +```js +import formidable from 'formidable'; +const form = formidable(options); +``` + +### Opções + +Veja seus padrões em [src/Formidable.js DEFAULT_OPTIONS](./src/Formidable.js) +(a constante `DEFAULT_OPTIONS`). + +- `options.encoding` **{string}** - padrão `'utf-8'`; define a codificação para campos de formulário de entrada, +- `options.uploadDir` **{string}** - padrão `os.tmpdir()`; o diretório para colocar os uploads de arquivos. Você pode movê-los mais tarde usando `fs.rename()`. +- `options.keepExtensions` **{boolean}** - padrão `false`; incluir as extensões dos arquivos originais ou não +- `options.allowEmptyFiles` **{boolean}** - padrão `false`; permitir upload de arquivos vazios +- `options.minFileSize` **{number}** - padrão `1` (1byte); o tamanho mínimo do arquivo carregado. +- `options.maxFiles` **{number}** - padrão `Infinity`; + limitar a quantidade de arquivos carregados, defina Infinity para ilimitado +- `options.maxFileSize` **{number}** - padrão `200 * 1024 * 1024` (200mb); + limitar o tamanho de cada arquivo carregado. +- `options.maxTotalFileSize` **{number}** - padrão `options.maxFileSize`; + limitar o tamanho do lote de arquivos carregados. +- `options.maxFields` **{number}** - padrão `1000`; limite o número de campos, defina Infinity para ilimitado +- `options.maxFieldsSize` **{number}** - padrão `20 * 1024 * 1024` (20mb); + limitar a quantidade de memória que todos os campos juntos (exceto arquivos) podem alocar em + bytes. +- `options.hashAlgorithm` **{string | false}** - padrão `false`; incluir checksums calculados + para arquivos recebidos, defina isso para algum algoritmo de hash, consulte + [crypto.createHash](https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm_options) + para algoritmos disponíveis +- `options.fileWriteStreamHandler` **{function}** - padrão `null`, que por padrão grava no sistema de arquivos da máquina host cada arquivo analisado; A função + deve retornar uma instância de um + [fluxo gravável](https://nodejs.org/api/stream.html#stream_class_stream_writable) + que receberá os dados do arquivo carregado. Com esta opção, você pode ter qualquer + comportamento personalizado em relação a onde os dados do arquivo carregado serão transmitidos. + Se você deseja gravar o arquivo carregado em outros tipos de armazenamento em nuvem + (AWS S3, armazenamento de blob do Azure, armazenamento em nuvem do Google) ou armazenamento de arquivo privado, + esta é a opção que você está procurando. Quando esta opção é definida, o comportamento padrão de gravar o arquivo no sistema de arquivos da máquina host é perdido. +- `options.filename` **{function}** - padrão `undefined` Use-o para controlar newFilename. Deve retornar uma string. Será associado a options.uploadDir. + +- `options.filter` **{function}** - função padrão que sempre retorna verdadeiro. + Use-o para filtrar arquivos antes de serem carregados. Deve retornar um booleano. + + +#### `options.filename` **{function}** function (name, ext, part, form) -> string + +onde a parte pode ser decomposta como + +```js +const { originalFilename, mimetype} = part; +``` + +_**Observação:** Se este tamanho de campos combinados, ou tamanho de algum arquivo for excedido, um +O evento `'error'` é disparado._ + +```js +// A quantidade de bytes recebidos para este formulário até agora. +form.bytesReceived; +``` + +```js +// O número esperado de bytes neste formulário. +form.bytesExpected; +``` + +#### `options.filter` **{function}** function ({name, originalFilename, mimetype}) -> boolean + +**Observação:** use uma variável externa para cancelar todos os uploads no primeiro erro + +```js +const options = { + filter: function ({name, originalFilename, mimetype}) { + // manter apenas imagens + return mimetype && mimetype.includes("image"); + } +}; +``` + + +### .parse(request, callback) + +Analisa uma `request` do Node.js recebida contendo dados de formulário. Se `callback` for +fornecido, todos os campos e arquivos são coletados e passados para o retorno de chamada. + +```js +const form = formidable({ uploadDir: __dirname }); + +form.parse(req, (err, fields, files) => { + console.log('fields:', fields); + console.log('files:', files); +}); +``` + +Você pode substituir esse método se estiver interessado em acessar diretamente o +fluxo de várias partes. Fazer isso desativará qualquer processamento de eventos `'field'` / `'file'` +que ocorreria de outra forma, tornando você totalmente responsável por lidar com o processamento. + +Sobre `uploadDir`, dada a seguinte estrutura de diretório +``` +project-name +├── src +│ └── server.js +│ +└── uploads + └── image.jpg +``` + +`__dirname` seria o mesmo diretório que o próprio arquivo de origem (src) + + +```js + `${__dirname}/../uploads` +``` + +para colocar arquivos em uploads. + +Omitir `__dirname` tornaria o caminho relativo ao diretório de trabalho atual. Isso seria o mesmo se server.js fosse iniciado a partir de src, mas não de project-name. + + +`null` usará o padrão que é `os.tmpdir()` + +Nota: Se o diretório não existir, os arquivos carregados são __silenciosamente descartados__. Para ter certeza de que existe: + +```js +import {createNecessaryDirectoriesSync} from "filesac"; + + +const uploadPath = `${__dirname}/../uploads`; +createNecessaryDirectoriesSync(`${uploadPath}/x`); +``` + + +No exemplo abaixo, escutamos alguns eventos e os direcionamos para o ouvinte `data`, para +que você possa fazer o que quiser lá, com base em se é antes do arquivo ser emitido, o valor do +cabeçalho, o nome do cabeçalho, no campo , em arquivo e etc. + +Ou a outra maneira poderia ser apenas substituir o `form.onPart` como é mostrado um pouco +mais tarde. + +```js +form.once('error', console.error); + +form.on('fileBegin', (formname, file) => { + form.emit('data', { name: 'fileBegin', formname, value: file }); +}); + +form.on('file', (formname, file) => { + form.emit('data', { name: 'file', formname, value: file }); +}); + +form.on('field', (fieldName, fieldValue) => { + form.emit('data', { name: 'field', key: fieldName, value: fieldValue }); +}); + +form.once('end', () => { + console.log('Done!'); +}); + +// Se você quiser personalizar o que quiser... +form.on('data', ({ name, key, value, buffer, start, end, formname, ...more }) => { + if (name === 'partBegin') { + } + if (name === 'partData') { + } + if (name === 'headerField') { + } + if (name === 'headerValue') { + } + if (name === 'headerEnd') { + } + if (name === 'headersEnd') { + } + if (name === 'field') { + console.log('field name:', key); + console.log('field value:', value); + } + if (name === 'file') { + console.log('file:', formname, value); + } + if (name === 'fileBegin') { + console.log('fileBegin:', formname, value); + } +}); +``` + +### .use(plugin: Plugin) + +Um método que permite estender a biblioteca Formidable. Por padrão, incluímos +4 plug-ins, que são essencialmente adaptadores para conectar os diferentes analisadores integrados. + +**Os plugins adicionados por este método estão sempre ativados.** + +_Consulte [src/plugins/](./src/plugins/) para uma visão mais detalhada dos plug-ins padrão._ + +O parâmetro `plugin` tem essa assinatura: + +```typescript +function(formidable: Formidable, options: Options): void; +``` + +A arquitetura é simples. O `plugin` é uma função que é passada com a instância Formidable (o `form` nos exemplos README) e as opções. + +**Observação:** o contexto `this` da função do plug-in também é a mesma instância. + +```js +const form = formidable({ keepExtensions: true }); + +form.use((self, options) => { + // self === this === form + console.log('woohoo, custom plugin'); + // faça suas coisas; verifique `src/plugins` para inspiração +}); + +form.parse(req, (error, fields, files) => { + console.log('done!'); +}); +``` +**Importante observar**, é que dentro do plugin `this.options`, `self.options` e +`options` PODEM ou NÃO ser iguais. A melhor prática geral é sempre usar o +`this`, para que você possa testar seu plugin mais tarde de forma independente e mais fácil. + +Se você quiser desabilitar alguns recursos de análise do Formidable, você pode desabilitar +o plugin que corresponde ao analisador. Por exemplo, se você deseja desabilitar a análise de +várias partes (para que o [src/parsers/Multipart.js](./src/parsers/Multipart.js) +que é usado em [src/plugins/multipart.js](./src/plugins/multipart.js)), então +você pode removê-lo do `options.enabledPlugins`, assim + +```js +import formidable, {octetstream, querystring, json} from "formidable"; +const form = formidable({ + hashAlgorithm: 'sha1', + enabledPlugins: [octetstream, querystring, json], +}); +``` + +**Esteja ciente** de que a ordem _PODE_ ser importante também. Os nomes correspondem 1:1 a +arquivos na pasta [src/plugins/](./src/plugins). + +Solicitações pull para novos plug-ins integrados PODEM ser aceitas - por exemplo, analisador de +querystring mais avançado. Adicione seu plugin como um novo arquivo na pasta `src/plugins/` (em letras minúsculas) e +siga como os outros plugins são feitos. + +### form.onPart + +Se você quiser usar Formidable para manipular apenas algumas partes para você, você pode fazer +alguma coisa similar. ou ver +[#387](https://github.com/node-formidable/node-formidable/issues/387) para +inspiração, você pode, por exemplo, validar o tipo mime. + +```js +const form = formidable(); + +form.onPart = (part) => { + part.on('data', (buffer) => { + // faça o que quiser aqui + }); +}; +``` + +Por exemplo, force Formidable a ser usado apenas em "partes" que não sejam de arquivo (ou seja, html +Campos) + +```js +const form = formidable(); + +form.onPart = function (part) { + // deixe formidável lidar apenas com partes não arquivadas + if (part.originalFilename === '' || !part.mimetype) { + // usado internamente, por favor, não substitua! + form._handlePart(part); + } +}; +``` + +### Arquivo + +```ts +export interface File { + // O tamanho do arquivo enviado em bytes. + // Se o arquivo ainda estiver sendo carregado (veja o evento `'fileBegin'`), + // esta propriedade diz quantos bytes do arquivo já foram gravados no disco. + file.size: number; + + // O caminho em que este arquivo está sendo gravado. Você pode modificar isso no evento `'fileBegin'` + // caso você esteja insatisfeito com a forma como o formidable gera um caminho temporário para seus arquivos. + file.filepath: string; + + // O nome que este arquivo tinha de acordo com o cliente de upload. + file.originalFilename: string | null; + + // calculado com base nas opções fornecidas. + file.newFilename: string | null; + + // O tipo mime deste arquivo, de acordo com o cliente de upload. + file.mimetype: string | null; + + // Um objeto Date (ou `null`) contendo a hora em que este arquivo foi gravado pela última vez. + // Principalmente aqui para compatibilidade com o [W3C File API Draft](http://dev.w3.org/2006/webapi/FileAPI/). + file.mtime: Date | null; + + file.hashAlgorithm: false | |'sha1' | 'md5' | 'sha256' + // Se o cálculo `options.hashAlgorithm` foi definido, você pode ler o resumo hexadecimal desta var (no final, será uma string) + file.hash: string | object | null; +} +``` + +#### file.toJSON() + +Este método retorna uma representação JSON do arquivo, permitindo que você `JSON.stringify()` +o arquivo que é útil para registrar e responder a solicitações. + +### Eventos + +#### `'progress'` +Emitido após cada bloco de entrada de dados que foi analisado. Pode ser usado para rolar sua própria barra de progresso. **Aviso** Use isso +apenas para a barra de progresso do lado do servidor. No lado do cliente, é melhor usar `XMLHttpRequest` com `xhr.upload.onprogress =` + +```js +form.on('progress', (bytesReceived, bytesExpected) => {}); +``` + +#### `'field'` + +Emitido sempre que um par campo/valor é recebido. + +```js +form.on('field', (name, value) => {}); +``` + +#### `'fileBegin'` + +Emitido sempre que um novo arquivo é detectado no fluxo de upload. +Use este evento se desejar transmitir o arquivo para outro lugar enquanto armazena o upload no sistema de arquivos. + +```js +form.on('fileBegin', (formName, file) => { + // acessível aqui + // formName o nome no formulário () ou http filename para octetstream + // file.originalFilename http filename ou null se houver um erro de análise + // file.newFilename gerou hexoid ou o que options.filename retornou + // file.filepath nome do caminho padrão de acordo com options.uploadDir e options.filename + // file.filepath = CUSTOM_PATH // para alterar o caminho final +}); +``` + +#### `'file'` + +Emitido sempre que um par campo/arquivo é recebido. `file` é uma instância de +`File`. + +```js +form.on('file', (formname, file) => { + // o mesmo que fileBegin, exceto + // é muito tarde para alterar file.filepath + // file.hash está disponível se options.hash foi usado +}); +``` + +#### `'error'` + +Emitido quando há um erro no processamento do formulário recebido. Uma solicitação que +apresenta um erro é pausada automaticamente, você terá que chamar manualmente +`request.resume()` se você quiser que a requisição continue disparando eventos `'data'`. + +Pode ter `error.httpCode` e `error.code` anexados. + +```js +form.on('error', (err) => {}); +``` + +#### `'aborted'` + +Emitido quando a requisição foi abortada pelo usuário. Agora isso pode ser devido a um +evento 'timeout' ou 'close' no soquete. Após este evento ser emitido, um +O evento `error` seguirá. No futuro, haverá um 'timeout' separado +evento (precisa de uma mudança no núcleo do nó). + +```js +form.on('aborted', () => {}); +``` + +#### `'end'` + +Emitido quando toda a solicitação foi recebida e todos os arquivos contidos foram +liberados para o disco. Este é um ótimo lugar para você enviar sua resposta. + +```js +form.on('end', () => {}); +``` + + +### Helpers + +#### firstValues + +Obtém os primeiros valores dos campos, como pré 3.0.0 sem passar múltiplos em uma +lista de exceções opcionais onde arrays de strings ainda são desejados (` '); + 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/4-natours/starter/node_modules/cookie/SECURITY.md b/4-natours/starter/node_modules/cookie/SECURITY.md new file mode 100644 index 0000000000..fd4a6c53a9 --- /dev/null +++ b/4-natours/starter/node_modules/cookie/SECURITY.md @@ -0,0 +1,25 @@ +# 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/4-natours/starter/node_modules/cookie/index.js b/4-natours/starter/node_modules/cookie/index.js new file mode 100644 index 0000000000..51a58cbe95 --- /dev/null +++ b/4-natours/starter/node_modules/cookie/index.js @@ -0,0 +1,334 @@ +/*! + * 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 + +/** + * 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 + * =