From b63ac87cf859723b3d968b6229e45217e97e7ba9 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Thu, 23 Mar 2023 18:05:27 -0300 Subject: [PATCH 01/14] adding observe sync option --- meteor | 2 +- package.json | 5 +- .../.npm/package/npm-shrinkwrap.json | 2727 ++++++----------- packages/minimongo/cursor.js | 54 +- packages/minimongo/local_collection.js | 4 +- 5 files changed, 966 insertions(+), 1826 deletions(-) diff --git a/meteor b/meteor index 77bd97c8ce..70d41e3a03 100755 --- a/meteor +++ b/meteor @@ -1,6 +1,6 @@ #!/usr/bin/env bash -BUNDLE_VERSION=14.21.3.1 +BUNDLE_VERSION=14.21.1.8 # OS Check. Put here because here is where we download the precompiled diff --git a/package.json b/package.json index 29e692c729..8c32e680dd 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,10 @@ "named": "never", "asyncArrow": "always" } - ] + ], + "complexity": "off", + "func-names": "off", + "no-undef": "warn" } } } diff --git a/packages/babel-compiler/.npm/package/npm-shrinkwrap.json b/packages/babel-compiler/.npm/package/npm-shrinkwrap.json index d5a644b0f6..da32024bb1 100644 --- a/packages/babel-compiler/.npm/package/npm-shrinkwrap.json +++ b/packages/babel-compiler/.npm/package/npm-shrinkwrap.json @@ -1,1831 +1,962 @@ { "lockfileVersion": 1, "dependencies": { - "@meteorjs/babel": { - "version": "7.19.0-beta.1", - "resolved": "https://registry.npmjs.org/@meteorjs/babel/-/babel-7.19.0-beta.1.tgz", - "integrity": "sha512-4dy7oSXEo6Eb2PHfPkMX0VVnkQJ9Kb6Qv6/ssiXOqQRtTRpBAgeWeMzUd42u/8VzxG6l8NoNqIhPSOHZjC2usg==", + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==" + }, + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==" + }, + "@babel/compat-data": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz", + "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==" + }, + "@babel/core": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.3.tgz", + "integrity": "sha512-qIJONzoa/qiHghnm0l1n4i/6IIziDpzqc36FBs4pzMhDUraHqponwJLiAKm1hGLP3OSB/TVNz6rMwVGpwxxySw==", "dependencies": { - "@ampproject/remapping": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.1.tgz", - "integrity": "sha512-Aolwjd7HSC2PyY0fDj/wA/EimQT4HfEnFYNp5s9CQlrdhyvWTtvZ5YzrUPu6R6/1jKiUlxu8bUhkdSnKHNAHMA==" - }, - "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==" - }, - "@babel/compat-data": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.9.tgz", - "integrity": "sha512-p3QjZmMGHDGdpcwEYYWu7i7oJShJvtgMjJeb0W95PPhSm++3lm8YXYOh45Y6iCN9PkZLTZ7CIX5nFrp7pw7TXw==" - }, - "@babel/core": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.2.tgz", - "integrity": "sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw==", - "dependencies": { - "@babel/compat-data": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", - "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==" - }, - "@babel/helper-compilation-targets": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", - "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==" - }, - "@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==" - }, - "browserslist": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", - "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==" - }, - "caniuse-lite": { - "version": "1.0.30001312", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", - "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==" - }, - "electron-to-chromium": { - "version": "1.4.68", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.68.tgz", - "integrity": "sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==" - }, - "node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==" - } - } - }, - "@babel/generator": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.0.tgz", - "integrity": "sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==", - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz", - "integrity": "sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA==" - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.14.5.tgz", - "integrity": "sha512-YTA/Twn0vBXDVGJuAX6PwW7x5zQei1luDDo2Pl6q1qZ7hVNl0RZrhHCQG/ArGpR29Vl7ETiB8eJyrvpuRp300w==" - }, - "@babel/helper-compilation-targets": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz", - "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==" - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.14.8", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.8.tgz", - "integrity": "sha512-bpYvH8zJBWzeqi1o+co8qOrw+EXzQ/0c74gVmY205AWXy9nifHrOg77y+1zwxX5lXE7Icq4sPlSQ4O2kWBrteQ==" - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz", - "integrity": "sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A==" - }, - "@babel/helper-define-polyfill-provider": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz", - "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==" - }, - "@babel/helper-environment-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", - "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==" - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.14.5.tgz", - "integrity": "sha512-Htb24gnGJdIGT4vnRKMdoXiOIlqOLmdiUYpAQ0mYfgVT/GDm8GOYhgi4GL+hMKrkiPRohO4ts34ELFsGAPQLDQ==" - }, - "@babel/helper-function-name": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", - "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==" - }, - "@babel/helper-get-function-arity": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", - "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==" - }, - "@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==" - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz", - "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==" - }, - "@babel/helper-module-imports": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", - "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==" - }, - "@babel/helper-module-transforms": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", - "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", - "dependencies": { - "@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==" - }, - "@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==" - } - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", - "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==" - }, - "@babel/helper-plugin-utils": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", - "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==" - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.14.5.tgz", - "integrity": "sha512-rLQKdQU+HYlxBwQIj8dk4/0ENOUEhA/Z0l4hN8BexpvmSMN9oA9EagjnhnDpNsRdWCfjwa4mn/HyBXO9yhQP6A==" - }, - "@babel/helper-replace-supers": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", - "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==" - }, - "@babel/helper-simple-access": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", - "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==" - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.14.5.tgz", - "integrity": "sha512-dmqZB7mrb94PZSAOYtr+ZN5qt5owZIAgqtoTuqiFbHFtxgEcmQlRJVI+bO++fciBunXtB6MK7HrzrfcAzIz2NQ==" - }, - "@babel/helper-split-export-declaration": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", - "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==" - }, - "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==" - }, - "@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==" - }, - "@babel/helper-wrap-function": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.14.5.tgz", - "integrity": "sha512-YEdjTCq+LNuNS1WfxsDCNpgXkJaIyqco6DAelTUjT4f2KIWC1nBcaCaSdHTBqQVLnTBexBcVcFhLSU1KnYuePQ==" - }, - "@babel/helpers": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", - "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==" - }, - "@babel/highlight": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", - "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==" - }, - "@babel/parser": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.0.tgz", - "integrity": "sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw==" - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.9.tgz", - "integrity": "sha512-d1lnh+ZnKrFKwtTYdw320+sQWCTwgkB9fmUhNXRADA4akR6wLjaruSGnIEUjpt9HCOwTr4ynFTKu19b7rFRpmw==" - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz", - "integrity": "sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==", - "dependencies": { - "@babel/helper-annotate-as-pure": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", - "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==" - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.17.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.1.tgz", - "integrity": "sha512-JBdSr/LtyYIno/pNnJ75lBcqc3Z1XXujzPanHqjvvrhOA+DTceTFuJi8XjmWTZh4r3fsdfqaCMN0iZemdkxZHQ==" - }, - "@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==" - }, - "@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==" - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz", - "integrity": "sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==" - }, - "@babel/helper-optimise-call-expression": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz", - "integrity": "sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==" - }, - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==" - }, - "@babel/helper-replace-supers": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz", - "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==" - }, - "@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==" - } - } - }, - "@babel/plugin-proposal-decorators": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.14.5.tgz", - "integrity": "sha512-LYz5nvQcvYeRVjui1Ykn28i+3aUiXwQ/3MGoEy0InTaz1pJo/lAzmIDXX+BQny/oufgHzJ6vnEEiXQ8KZjEVFg==" - }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz", - "integrity": "sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw==" - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz", - "integrity": "sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==" - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.7.tgz", - "integrity": "sha512-082hsZz+sVabfmDWo1Oct1u1AgbKbUAyVgmX4otIc7bdsRgHBXwTwb3DpDmD4Eyyx6DNiuz5UAATT655k+kL5g==" - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz", - "integrity": "sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ==" - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz", - "integrity": "sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==" - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==" - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==" - }, - "@babel/plugin-syntax-decorators": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.14.5.tgz", - "integrity": "sha512-c4sZMRWL4GSvP1EXy0woIP7m4jkVcEuG8R1TOZxPBPtp4FSM/kiPZub9UIs/Jrb5ZAOzvTUSGYrWsrSu1JvoPw==" - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==" - }, - "@babel/plugin-syntax-jsx": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz", - "integrity": "sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==", - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==" - } - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==" - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==" - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==" - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==" - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==" - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz", - "integrity": "sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A==" - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz", - "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==" - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz", - "integrity": "sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ==" - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.5.tgz", - "integrity": "sha512-LBYm4ZocNgoCqyxMLoOnwpsmQ18HWTQvql64t3GvMUzLQrNoV1BDG0lNftC8QKYERkZgCCT/7J5xWGObGAyHDw==" - }, - "@babel/plugin-transform-classes": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.9.tgz", - "integrity": "sha512-NfZpTcxU3foGWbl4wxmZ35mTsYJy8oQocbeIMoDAGGFarAmSQlL+LWMkDx/tj6pNotpbX3rltIA4dprgAPOq5A==" - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz", - "integrity": "sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg==" - }, - "@babel/plugin-transform-destructuring": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz", - "integrity": "sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw==" - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz", - "integrity": "sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA==" - }, - "@babel/plugin-transform-for-of": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.14.5.tgz", - "integrity": "sha512-CfmqxSUZzBl0rSjpoQSFoR9UEj3HzbGuGNL21/iFTmjb5gFggJp3ph0xR1YBhexmLoKRHzgxuFvty2xdSt6gTA==" - }, - "@babel/plugin-transform-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz", - "integrity": "sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A==" - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz", - "integrity": "sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA==", - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==" - } - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz", - "integrity": "sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg==" - }, - "@babel/plugin-transform-parameters": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.5.tgz", - "integrity": "sha512-Tl7LWdr6HUxTmzQtzuU14SqbgrSKmaR77M0OKyq4njZLQTPfOvzblNKyNkGwOfEFCEx7KeYHQHDI0P3F02IVkA==" - }, - "@babel/plugin-transform-property-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz", - "integrity": "sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==" - }, - "@babel/plugin-transform-react-display-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.7.tgz", - "integrity": "sha512-qgIg8BcZgd0G/Cz916D5+9kqX0c7nPZyXaP8R2tLNN5tkyIZdG5fEwBrxwplzSnjC1jvQmyMNVwUCZPcbGY7Pg==", - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==" - } - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.7.tgz", - "integrity": "sha512-8D16ye66fxiE8m890w0BpPpngG9o9OVBBy0gH2E+2AR7qMR2ZpTYJEqLxAsoroenMId0p/wMW+Blc0meDgu0Ag==", - "dependencies": { - "@babel/helper-annotate-as-pure": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", - "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==" - }, - "@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==" - }, - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==" - } - } - }, - "@babel/plugin-transform-react-jsx-development": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.7.tgz", - "integrity": "sha512-RMvQWvpla+xy6MlBpPlrKZCMRs2AGiHOGHY3xRwl0pEeim348dDyxeH4xBsMPbIMhujeq7ihE702eM2Ew0Wo+A==" - }, - "@babel/plugin-transform-react-pure-annotations": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.16.7.tgz", - "integrity": "sha512-hs71ToC97k3QWxswh2ElzMFABXHvGiJ01IB1TbYQDGeWRKWz/MPUTh5jGExdHvosYKpnJW5Pm3S4+TA3FyX+GA==", - "dependencies": { - "@babel/helper-annotate-as-pure": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", - "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==" - }, - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==" - } - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz", - "integrity": "sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg==" - }, - "@babel/plugin-transform-runtime": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.17.0.tgz", - "integrity": "sha512-fr7zPWnKXNc1xoHfrIU9mN/4XKX4VLZ45Q+oMhfsYIaHvg7mHgmhfOy/ckRWqDK7XF3QDigRpkh5DKq6+clE8A==", - "dependencies": { - "@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==" - }, - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==" - } - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz", - "integrity": "sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g==" - }, - "@babel/plugin-transform-spread": { - "version": "7.14.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz", - "integrity": "sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag==" - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz", - "integrity": "sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A==" - }, - "@babel/plugin-transform-template-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz", - "integrity": "sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg==" - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz", - "integrity": "sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw==" - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz", - "integrity": "sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw==" - }, - "@babel/preset-react": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.16.7.tgz", - "integrity": "sha512-fWpyI8UM/HE6DfPBzD8LnhQ/OcH8AgTaqcqP2nGOXEUV+VKBR5JRN9hCk9ai+zQQ57vtm9oWeXguBCPNUjytgA==", - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==" - }, - "@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==" - } - } - }, - "@babel/runtime": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", - "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==" - }, - "@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==" - }, - "@babel/traverse": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.0.tgz", - "integrity": "sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg==", - "dependencies": { - "@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==" - }, - "@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==" - }, - "@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==" - } - } - }, - "@babel/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", - "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==" - }, - "@jridgewell/resolve-uri": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", - "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==" - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.11", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", - "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==" - }, - "@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==" - }, - "@meteorjs/reify": { - "version": "https://github.com/meteor/reify/tarball/ee36898798645097948258eb9106dd0af60cec64", - "integrity": "sha512-ERt3gPO1iBDxJe+9UvkZPuGZKUmjD2/R3VjeF5HKEyXwiU6kh3swhRwQQrTopwpG8amPa2sjSr+DOihHMs+Z/g==", - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "@types/estree": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", - "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==" - }, - "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==" - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==" - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==" - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==" - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" - }, - "babel-helper-evaluate-path": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.5.0.tgz", - "integrity": "sha512-mUh0UhS607bGh5wUMAQfOpt2JX2ThXMtppHRdRU1kL7ZLRWIXxoV2UIV1r2cAeeNeU1M5SB5/RSUgUxrK8yOkA==" - }, - "babel-helper-flip-expressions": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.4.3.tgz", - "integrity": "sha1-NpZzahKKwYvCUlS19AoizrPB0/0=" - }, - "babel-helper-is-nodes-equiv": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz", - "integrity": "sha1-NOmzALFHnd2Y7HfqC76TQt/jloQ=" - }, - "babel-helper-is-void-0": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-helper-is-void-0/-/babel-helper-is-void-0-0.4.3.tgz", - "integrity": "sha1-fZwBtFYee5Xb2g9u7kj1tg5nMT4=" - }, - "babel-helper-mark-eval-scopes": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.4.3.tgz", - "integrity": "sha1-0kSjvvmESHJgP/tG4izorN9VFWI=" - }, - "babel-helper-remove-or-void": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.4.3.tgz", - "integrity": "sha1-pPA7QAd6D/6I5F0HAQ3uJB/1rmA=" - }, - "babel-helper-to-multiple-sequence-expressions": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.5.0.tgz", - "integrity": "sha512-m2CvfDW4+1qfDdsrtf4dwOslQC3yhbgyBFptncp4wvtdrDHqueW7slsYv4gArie056phvQFhT2nRcGS4bnm6mA==" - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==" - }, - "babel-plugin-minify-builtins": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.5.0.tgz", - "integrity": "sha512-wpqbN7Ov5hsNwGdzuzvFcjgRlzbIeVv1gMIlICbPj0xkexnfoIDe7q+AZHMkQmAE/F9R5jkrB6TLfTegImlXag==" - }, - "babel-plugin-minify-constant-folding": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.5.0.tgz", - "integrity": "sha512-Vj97CTn/lE9hR1D+jKUeHfNy+m1baNiJ1wJvoGyOBUx7F7kJqDZxr9nCHjO/Ad+irbR3HzR6jABpSSA29QsrXQ==" - }, - "babel-plugin-minify-dead-code-elimination": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.5.1.tgz", - "integrity": "sha512-x8OJOZIrRmQBcSqxBcLbMIK8uPmTvNWPXH2bh5MDCW1latEqYiRMuUkPImKcfpo59pTUB2FT7HfcgtG8ZlR5Qg==" - }, - "babel-plugin-minify-flip-comparisons": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.4.3.tgz", - "integrity": "sha1-AMqHDLjxO0XAOLPB68DyJyk8llo=" - }, - "babel-plugin-minify-guarded-expressions": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.4.4.tgz", - "integrity": "sha512-RMv0tM72YuPPfLT9QLr3ix9nwUIq+sHT6z8Iu3sLbqldzC1Dls8DPCywzUIzkTx9Zh1hWX4q/m9BPoPed9GOfA==" - }, - "babel-plugin-minify-infinity": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.4.3.tgz", - "integrity": "sha1-37h2obCKBldjhO8/kuZTumB7Oco=" - }, - "babel-plugin-minify-mangle-names": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.5.0.tgz", - "integrity": "sha512-3jdNv6hCAw6fsX1p2wBGPfWuK69sfOjfd3zjUXkbq8McbohWy23tpXfy5RnToYWggvqzuMOwlId1PhyHOfgnGw==" - }, - "babel-plugin-minify-numeric-literals": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.4.3.tgz", - "integrity": "sha1-jk/VYcefeAEob/YOjF/Z3u6TwLw=" - }, - "babel-plugin-minify-replace": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.5.0.tgz", - "integrity": "sha512-aXZiaqWDNUbyNNNpWs/8NyST+oU7QTpK7J9zFEFSA0eOmtUNMU3fczlTTTlnCxHmq/jYNFEmkkSG3DDBtW3Y4Q==" - }, - "babel-plugin-minify-simplify": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.5.1.tgz", - "integrity": "sha512-OSYDSnoCxP2cYDMk9gxNAed6uJDiDz65zgL6h8d3tm8qXIagWGMLWhqysT6DY3Vs7Fgq7YUDcjOomhVUb+xX6A==" - }, - "babel-plugin-minify-type-constructors": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.4.3.tgz", - "integrity": "sha1-G8bxW4f3qxCF1CszC3F2V6IVZQA=" - }, - "babel-plugin-polyfill-corejs2": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz", - "integrity": "sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==" - }, - "babel-plugin-polyfill-corejs3": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz", - "integrity": "sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==" - }, - "babel-plugin-polyfill-regenerator": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz", - "integrity": "sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==" - }, - "babel-plugin-transform-inline-consecutive-adds": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.4.3.tgz", - "integrity": "sha1-Mj1Ho+pjqDp6w8gRro5pQfrysNE=" - }, - "babel-plugin-transform-member-expression-literals": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.9.4.tgz", - "integrity": "sha1-NwOcmgwzE6OUlfqsL/OmtbnQOL8=" - }, - "babel-plugin-transform-merge-sibling-variables": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.9.4.tgz", - "integrity": "sha1-hbQi/DN3tEnJ0c3kQIcgNTJAHa4=" - }, - "babel-plugin-transform-minify-booleans": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.9.4.tgz", - "integrity": "sha1-rLs+VqNVXdI5KOS1gtKFFi3SsZg=" - }, - "babel-plugin-transform-property-literals": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.4.tgz", - "integrity": "sha1-mMHSHiVXNlc/k+zlRFn2ziSYXTk=" - }, - "babel-plugin-transform-regexp-constructors": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.4.3.tgz", - "integrity": "sha1-WLd3W2OvzzMyj66aX4j71PsLSWU=" - }, - "babel-plugin-transform-remove-console": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.9.4.tgz", - "integrity": "sha1-uYA2DAZzhOJLNXpYjYB9PINSd4A=" - }, - "babel-plugin-transform-remove-debugger": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.9.4.tgz", - "integrity": "sha1-QrcnYxyXl44estGZp67IShgznvI=" - }, - "babel-plugin-transform-remove-undefined": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.5.0.tgz", - "integrity": "sha512-+M7fJYFaEE/M9CXa0/IRkDbiV3wRELzA1kKQFCJ4ifhrzLKn/9VCCgj9OFmYWwBd8IB48YdgPkHYtbYq+4vtHQ==" - }, - "babel-plugin-transform-simplify-comparison-operators": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.9.4.tgz", - "integrity": "sha1-9ir+CWyrDh9ootdT/fKDiIRxzrk=" - }, - "babel-plugin-transform-undefined-to-void": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.4.tgz", - "integrity": "sha1-viQcqBQEAwZ4t0hxcyK4nQyP4oA=" - }, - "babel-preset-meteor": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/babel-preset-meteor/-/babel-preset-meteor-7.10.0.tgz", - "integrity": "sha512-bcdNfRCQAjTV42cUcmaG5/ltLZZQLpZajUcP+o0Lr+aLTY/XLNkGfASM5383wdXiAkEFl0sDOXeknnLlQtrmdg==" - }, - "babel-preset-minify": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-minify/-/babel-preset-minify-0.5.1.tgz", - "integrity": "sha512-1IajDumYOAPYImkHbrKeiN5AKKP9iOmRoO2IPbIuVp0j2iuCcj0n7P260z38siKMZZ+85d3mJZdtW8IgOv+Tzg==" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==" - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" - }, - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==" - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==" - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "caniuse-lite": { - "version": "1.0.30001248", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001248.tgz", - "integrity": "sha512-NwlQbJkxUFJ8nMErnGtT0QTM2TJ33xgz4KXJSMIrjXIbDVdaYueGyjOrLKRtJC+rTiWfi6j5cnZN1NBiSBJGNw==" - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==" - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==" - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==" - } - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==" - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==" - }, - "core-js-compat": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.21.0.tgz", - "integrity": "sha512-OSXseNPSK2OPJa6GdtkMz/XxeXx8/CJvfhQWTqd6neuUraujcL4jVsjkLQz1OWnax8xVQJnRPe0V2jqNWORA+A==", - "dependencies": { - "browserslist": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", - "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==" - }, - "caniuse-lite": { - "version": "1.0.30001312", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", - "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==" - }, - "electron-to-chromium": { - "version": "1.4.68", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.68.tgz", - "integrity": "sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==" - }, - "node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==" - }, - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==" - } - } - }, - "d3": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/d3/-/d3-4.13.0.tgz", - "integrity": "sha512-l8c4+0SldjVKLaE2WG++EQlqD7mh/dmQjvi2L2lKPadAVC+TbJC4ci7Uk9bRi+To0+ansgsS0iWfPjD7DBy+FQ==" - }, - "d3-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.1.tgz", - "integrity": "sha512-CyINJQ0SOUHojDdFDH4JEM0552vCR1utGyLHegJHyYH0JyCpSeTPxi4OBqHMA2jJZq4NH782LtaJWBImqI/HBw==" - }, - "d3-axis": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.8.tgz", - "integrity": "sha1-MacFoLU15ldZ3hQXOjGTMTfxjvo=" - }, - "d3-brush": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.0.4.tgz", - "integrity": "sha1-AMLyOAGfJPbAoZSibUGhUw/+e8Q=" - }, - "d3-chord": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.4.tgz", - "integrity": "sha1-fexPC6iG9xP+ERxF92NBT290yiw=" - }, - "d3-collection": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.4.tgz", - "integrity": "sha1-NC39EoN8kJdPM/HMCnha6lcNzcI=" - }, - "d3-color": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.0.3.tgz", - "integrity": "sha1-vHZD/KjlOoNH4vva/6I2eWtYUJs=" - }, - "d3-dispatch": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.3.tgz", - "integrity": "sha1-RuFJHqqbWMNY/OW+TovtYm54cfg=" - }, - "d3-drag": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.1.tgz", - "integrity": "sha512-Cg8/K2rTtzxzrb0fmnYOUeZHvwa4PHzwXOLZZPwtEs2SKLLKLXeYwZKBB+DlOxUvFmarOnmt//cU4+3US2lyyQ==" - }, - "d3-dsv": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.0.8.tgz", - "integrity": "sha512-IVCJpQ+YGe3qu6odkPQI0KPqfxkhbP/oM1XhhE/DFiYmcXKfCRub4KXyiuehV1d4drjWVXHUWx4gHqhdZb6n/A==" - }, - "d3-ease": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.3.tgz", - "integrity": "sha1-aL+8NJM4o4DETYrMT7wzBKotjA4=" - }, - "d3-force": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.1.0.tgz", - "integrity": "sha512-2HVQz3/VCQs0QeRNZTYb7GxoUCeb6bOzMp/cGcLa87awY9ZsPvXOGeZm0iaGBjXic6I1ysKwMn+g+5jSAdzwcg==" - }, - "d3-format": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.2.2.tgz", - "integrity": "sha512-zH9CfF/3C8zUI47nsiKfD0+AGDEuM8LwBIP7pBVpyR4l/sKkZqITmMtxRp04rwBrlshIZ17XeFAaovN3++wzkw==" - }, - "d3-geo": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.9.1.tgz", - "integrity": "sha512-l9wL/cEQkyZQYXw3xbmLsH3eQ5ij+icNfo4r0GrLa5rOCZR/e/3am45IQ0FvQ5uMsv+77zBRunLc9ufTWSQYFA==" - }, - "d3-hierarchy": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.5.tgz", - "integrity": "sha1-ochFxC+Eoga88cAcAQmOpN2qeiY=" - }, - "d3-interpolate": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.1.6.tgz", - "integrity": "sha512-mOnv5a+pZzkNIHtw/V6I+w9Lqm9L5bG3OTXPM5A+QO0yyVMQ4W1uZhR+VOJmazaOZXri2ppbiZ5BUNWT0pFM9A==" - }, - "d3-path": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.5.tgz", - "integrity": "sha1-JB6xhJvZ6egCHA0KeZ+KDo5EF2Q=" - }, - "d3-polygon": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.3.tgz", - "integrity": "sha1-FoiOkCZGCTPysXllKtN4Ik04LGI=" - }, - "d3-quadtree": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.3.tgz", - "integrity": "sha1-rHmH4+I/6AWpkPKOG1DTj8uCJDg=" - }, - "d3-queue": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/d3-queue/-/d3-queue-3.0.7.tgz", - "integrity": "sha1-yTouVLQXwJWRKdfXP2z31Ckudhg=" - }, - "d3-random": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.0.tgz", - "integrity": "sha1-ZkLlBsb6OmSFldKyRpeIqNElKdM=" - }, - "d3-request": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/d3-request/-/d3-request-1.0.6.tgz", - "integrity": "sha512-FJj8ySY6GYuAJHZMaCQ83xEYE4KbkPkmxZ3Hu6zA1xxG2GD+z6P+Lyp+zjdsHf0xEbp2xcluDI50rCS855EQ6w==" - }, - "d3-scale": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-1.0.7.tgz", - "integrity": "sha512-KvU92czp2/qse5tUfGms6Kjig0AhHOwkzXG0+PqIJB3ke0WUv088AHMZI0OssO9NCkXt4RP8yju9rpH8aGB7Lw==" - }, - "d3-selection": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.3.0.tgz", - "integrity": "sha512-qgpUOg9tl5CirdqESUAu0t9MU/t3O9klYfGfyKsXEmhyxyzLpzpeh08gaxBUTQw1uXIOkr/30Ut2YRjSSxlmHA==" - }, - "d3-shape": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.2.0.tgz", - "integrity": "sha1-RdAVOPBkuv0F6j1tLLdI/YxB93c=" - }, - "d3-time": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.0.8.tgz", - "integrity": "sha512-YRZkNhphZh3KcnBfitvF3c6E0JOFGikHZ4YqD+Lzv83ZHn1/u6yGenRU1m+KAk9J1GnZMnKcrtfvSktlA1DXNQ==" - }, - "d3-time-format": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.1.1.tgz", - "integrity": "sha512-8kAkymq2WMfzW7e+s/IUNAtN/y3gZXGRrdGfo6R8NKPAA85UBTxZg5E61bR6nLwjPjj4d3zywSQe1CkYLPFyrw==" - }, - "d3-timer": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.7.tgz", - "integrity": "sha512-vMZXR88XujmG/L5oB96NNKH5lCWwiLM/S2HyyAQLcjWJCloK5shxta4CwOFYLZoY3AWX73v8Lgv4cCAdWtRmOA==" - }, - "d3-transition": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.1.1.tgz", - "integrity": "sha512-xeg8oggyQ+y5eb4J13iDgKIjUcEfIOZs2BqV/eEmXm2twx80wTzJ4tB4vaZ5BKfz7XsI/DFmQL5me6O27/5ykQ==" - }, - "d3-voronoi": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.2.tgz", - "integrity": "sha1-Fodmfo8TotFYyAwUgMWinLDYlzw=" - }, - "d3-zoom": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.7.1.tgz", - "integrity": "sha512-sZHQ55DGq5BZBFGnRshUT8tm2sfhPHFnOlmPbbwTkAoPeVdRTkB4Xsf9GCY0TSHrTD8PeJPZGmP/TpGicwJDJQ==" - }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==" - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==" - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" - }, - "electron-to-chromium": { - "version": "1.3.793", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.793.tgz", - "integrity": "sha512-l9NrGV6Mr4ov5mayYPvIWcwklNw5ROmy6rllzz9dCACw9nKE5y+s5uQk+CBJMetxrWZ6QJFsvEfG6WDcH2IGUg==" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "es-abstract": { - "version": "1.18.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz", - "integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==" - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==" - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==" - }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==" - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==" - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==" - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=" - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==" - }, - "is-bigint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==" - }, - "is-boolean-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", - "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==" - }, - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" - }, - "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" - }, - "is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==" - }, - "is-date-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" - }, - "is-number-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", - "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==" - }, - "is-reference": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==" - }, - "is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==" - }, - "is-string": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", - "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==" - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==" - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==" - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==" - }, - "magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==" - }, - "meteor-babel-helpers": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/meteor-babel-helpers/-/meteor-babel-helpers-0.0.3.tgz", - "integrity": "sha1-8uXZ+HlvvS6JAQI9dpnlsgLqn7A=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==" - }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" - }, - "mkdirp": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", - "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==" - }, - "mocha": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", - "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==" - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==" - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==" - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node-environment-flags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", - "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "node-releases": { - "version": "1.1.73", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", - "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==" - }, - "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==" - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==" - }, - "object.getownpropertydescriptors": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", - "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=" - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==" - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==" - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "periscopic": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-2.0.3.tgz", - "integrity": "sha512-FuCZe61mWxQOJAQFEfmt9FjzebRlcpFz8sFPbyaCKtdusPkMEbA9ey0eARnRav5zAhmXznhaQkKGFAPn7X9NUw==" - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "promise": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz", - "integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==" - }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "regenerate-unicode-properties": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", - "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==" - }, - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, - "regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==" - }, - "regexpu-core": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", - "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==" - }, - "regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==" - }, - "regjsparser": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz", - "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==", - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==" - }, - "rw": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==" - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==" - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==" - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=" - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==" - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - }, - "typescript": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", - "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==" - }, - "unicode-canonical-property-names-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==" - }, - "unicode-match-property-ecmascript": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", - "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==" - }, - "unicode-match-property-value-ecmascript": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", - "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==" - }, - "unicode-property-aliases-ecmascript": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", - "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==" - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==" - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==" - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==" - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==" - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==" - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==" - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==" - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==" } } }, + "@babel/generator": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.3.tgz", + "integrity": "sha512-QS3iR1GYC/YGUnW7IdggFeN5c1poPUurnGttOV/bZgPGV+izC/D8HnD6DLwod0fsatNyVn1G3EVWMYIF0nHbeA==", + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==" + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==" + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", + "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==" + }, + "@babel/helper-compilation-targets": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.0.tgz", + "integrity": "sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ==" + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.0.tgz", + "integrity": "sha512-N+LaFW/auRSWdx7SHD/HiARwXQju1vXTW4fKr4u5SgBUTm51OKEjKgj+cs00ggW3kEvNqwErnlwuq7Y3xBe4eg==" + }, + "@babel/helper-define-polyfill-provider": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==" + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", + "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==" + }, + "@babel/helper-function-name": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==" + }, + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==" + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz", + "integrity": "sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==" + }, + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==" + }, + "@babel/helper-module-transforms": { + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", + "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==" + }, + "@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==" + }, + "@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==" + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", + "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==" + }, + "@babel/helper-replace-supers": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz", + "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==" + }, + "@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==" + }, + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", + "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==" + }, + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==" + }, + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==" + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" + }, + "@babel/helper-validator-option": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==" + }, + "@babel/helper-wrap-function": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", + "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==" + }, + "@babel/helpers": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", + "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==" + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==" + }, + "@babel/parser": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.3.tgz", + "integrity": "sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==" + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", + "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==" + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==" + }, + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", + "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==" + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==" + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==" + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", + "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==" + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==" + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==" + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==" + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==" + }, + "@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==" + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==" + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==" + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==" + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==" + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==" + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz", + "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==" + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz", + "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==" + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", + "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==" + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz", + "integrity": "sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==" + }, + "@babel/plugin-transform-classes": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz", + "integrity": "sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==" + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz", + "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==" + }, + "@babel/plugin-transform-destructuring": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz", + "integrity": "sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==" + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", + "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==" + }, + "@babel/plugin-transform-for-of": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz", + "integrity": "sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==" + }, + "@babel/plugin-transform-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", + "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==" + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz", + "integrity": "sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==" + }, + "@babel/plugin-transform-object-super": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", + "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==" + }, + "@babel/plugin-transform-parameters": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz", + "integrity": "sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==" + }, + "@babel/plugin-transform-property-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", + "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==" + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", + "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==" + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.0.tgz", + "integrity": "sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg==" + }, + "@babel/plugin-transform-react-jsx-development": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", + "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==" + }, + "@babel/plugin-transform-react-pure-annotations": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", + "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==" + }, + "@babel/plugin-transform-regenerator": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", + "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==" + }, + "@babel/plugin-transform-runtime": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.0.tgz", + "integrity": "sha512-ReY6pxwSzEU0b3r2/T/VhqMKg/AkceBT19X0UptA3/tYi5Pe2eXgEUH+NNMC5nok6c6XQz5tyVTUpuezRfSMSg==", + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", + "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==" + }, + "@babel/plugin-transform-spread": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz", + "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==" + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", + "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==" + }, + "@babel/plugin-transform-template-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", + "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==" + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", + "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==" + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", + "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==" + }, + "@babel/preset-react": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz", + "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==" + }, + "@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + }, + "@babel/runtime": { + "version": "7.17.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz", + "integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==" + }, + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==" + }, + "@babel/traverse": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.3.tgz", + "integrity": "sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==" + }, + "@babel/types": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.3.tgz", + "integrity": "sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==" + }, + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==" + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==" + }, + "@meteorjs/babel": { + "version": "7.19.0-beta.2", + "resolved": "https://registry.npmjs.org/@meteorjs/babel/-/babel-7.19.0-beta.2.tgz", + "integrity": "sha512-B7lAsVLq8QxdhkOQkOCaEcsG1rnzam9gU/RXEkeM5WC4EDzjn5SVY9CeO+Kqda0rcBM9166OKufs1tqnmQtvOw==" + }, + "@meteorjs/reify": { + "version": "https://github.com/meteor/reify/tarball/ee36898798645097948258eb9106dd0af60cec64", + "integrity": "sha512-ERt3gPO1iBDxJe+9UvkZPuGZKUmjD2/R3VjeF5HKEyXwiU6kh3swhRwQQrTopwpG8amPa2sjSr+DOihHMs+Z/g==", + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "@types/estree": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==" + }, + "acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==" + }, + "babel-helper-evaluate-path": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.5.0.tgz", + "integrity": "sha512-mUh0UhS607bGh5wUMAQfOpt2JX2ThXMtppHRdRU1kL7ZLRWIXxoV2UIV1r2cAeeNeU1M5SB5/RSUgUxrK8yOkA==" + }, + "babel-helper-flip-expressions": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.4.3.tgz", + "integrity": "sha512-rSrkRW4YQ2ETCWww9gbsWk4N0x1BOtln349Tk0dlCS90oT68WMLyGR7WvaMp3eAnsVrCqdUtC19lo1avyGPejA==" + }, + "babel-helper-is-nodes-equiv": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz", + "integrity": "sha512-ri/nsMFVRqXn7IyT5qW4/hIAGQxuYUFHa3qsxmPtbk6spZQcYlyDogfVpNm2XYOslH/ULS4VEJGUqQX5u7ACQw==" + }, + "babel-helper-is-void-0": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-is-void-0/-/babel-helper-is-void-0-0.4.3.tgz", + "integrity": "sha512-07rBV0xPRM3TM5NVJEOQEkECX3qnHDjaIbFvWYPv+T1ajpUiVLiqTfC+MmiZxY5KOL/Ec08vJdJD9kZiP9UkUg==" + }, + "babel-helper-mark-eval-scopes": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.4.3.tgz", + "integrity": "sha512-+d/mXPP33bhgHkdVOiPkmYoeXJ+rXRWi7OdhwpyseIqOS8CmzHQXHUp/+/Qr8baXsT0kjGpMHHofHs6C3cskdA==" + }, + "babel-helper-remove-or-void": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.4.3.tgz", + "integrity": "sha512-eYNceYtcGKpifHDir62gHJadVXdg9fAhuZEXiRQnJJ4Yi4oUTpqpNY//1pM4nVyjjDMPYaC2xSf0I+9IqVzwdA==" + }, + "babel-helper-to-multiple-sequence-expressions": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.5.0.tgz", + "integrity": "sha512-m2CvfDW4+1qfDdsrtf4dwOslQC3yhbgyBFptncp4wvtdrDHqueW7slsYv4gArie056phvQFhT2nRcGS4bnm6mA==" + }, + "babel-plugin-minify-builtins": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.5.0.tgz", + "integrity": "sha512-wpqbN7Ov5hsNwGdzuzvFcjgRlzbIeVv1gMIlICbPj0xkexnfoIDe7q+AZHMkQmAE/F9R5jkrB6TLfTegImlXag==" + }, + "babel-plugin-minify-constant-folding": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.5.0.tgz", + "integrity": "sha512-Vj97CTn/lE9hR1D+jKUeHfNy+m1baNiJ1wJvoGyOBUx7F7kJqDZxr9nCHjO/Ad+irbR3HzR6jABpSSA29QsrXQ==" + }, + "babel-plugin-minify-dead-code-elimination": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.5.2.tgz", + "integrity": "sha512-krq9Lwi0QIzyAlcNBXTL4usqUvevB4BzktdEsb8srcXC1AaYqRJiAQw6vdKdJSaXbz6snBvziGr6ch/aoRCfpA==" + }, + "babel-plugin-minify-flip-comparisons": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.4.3.tgz", + "integrity": "sha512-8hNwgLVeJzpeLVOVArag2DfTkbKodzOHU7+gAZ8mGBFGPQHK6uXVpg3jh5I/F6gfi5Q5usWU2OKcstn1YbAV7A==" + }, + "babel-plugin-minify-guarded-expressions": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.4.4.tgz", + "integrity": "sha512-RMv0tM72YuPPfLT9QLr3ix9nwUIq+sHT6z8Iu3sLbqldzC1Dls8DPCywzUIzkTx9Zh1hWX4q/m9BPoPed9GOfA==" + }, + "babel-plugin-minify-infinity": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.4.3.tgz", + "integrity": "sha512-X0ictxCk8y+NvIf+bZ1HJPbVZKMlPku3lgYxPmIp62Dp8wdtbMLSekczty3MzvUOlrk5xzWYpBpQprXUjDRyMA==" + }, + "babel-plugin-minify-mangle-names": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.5.1.tgz", + "integrity": "sha512-8KMichAOae2FHlipjNDTo2wz97MdEb2Q0jrn4NIRXzHH7SJ3c5TaNNBkeTHbk9WUsMnqpNUx949ugM9NFWewzw==" + }, + "babel-plugin-minify-numeric-literals": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.4.3.tgz", + "integrity": "sha512-5D54hvs9YVuCknfWywq0eaYDt7qYxlNwCqW9Ipm/kYeS9gYhJd0Rr/Pm2WhHKJ8DC6aIlDdqSBODSthabLSX3A==" + }, + "babel-plugin-minify-replace": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.5.0.tgz", + "integrity": "sha512-aXZiaqWDNUbyNNNpWs/8NyST+oU7QTpK7J9zFEFSA0eOmtUNMU3fczlTTTlnCxHmq/jYNFEmkkSG3DDBtW3Y4Q==" + }, + "babel-plugin-minify-simplify": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.5.1.tgz", + "integrity": "sha512-OSYDSnoCxP2cYDMk9gxNAed6uJDiDz65zgL6h8d3tm8qXIagWGMLWhqysT6DY3Vs7Fgq7YUDcjOomhVUb+xX6A==" + }, + "babel-plugin-minify-type-constructors": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.4.3.tgz", + "integrity": "sha512-4ADB0irJ/6BeXWHubjCJmrPbzhxDgjphBMjIjxCc25n4NGJ00NsYqwYt+F/OvE9RXx8KaSW7cJvp+iZX436tnQ==" + }, + "babel-plugin-polyfill-corejs2": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "babel-plugin-polyfill-corejs3": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", + "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==" + }, + "babel-plugin-polyfill-regenerator": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==" + }, + "babel-plugin-transform-inline-consecutive-adds": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.4.3.tgz", + "integrity": "sha512-8D104wbzzI5RlxeVPYeQb9QsUyepiH1rAO5hpPpQ6NPRgQLpIVwkS/Nbx944pm4K8Z+rx7CgjPsFACz/VCBN0Q==" + }, + "babel-plugin-transform-member-expression-literals": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.9.4.tgz", + "integrity": "sha512-Xq9/Rarpj+bjOZSl1nBbZYETsNEDDJSrb6Plb1sS3/36FukWFLLRysgecva5KZECjUJTrJoQqjJgtWToaflk5Q==" + }, + "babel-plugin-transform-merge-sibling-variables": { + "version": "6.9.5", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.9.5.tgz", + "integrity": "sha512-xj/KrWi6/uP+DrD844h66Qh2cZN++iugEIgH8QcIxhmZZPNP6VpOE9b4gP2FFW39xDAY43kCmYMM6U0QNKN8fw==" + }, + "babel-plugin-transform-minify-booleans": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.9.4.tgz", + "integrity": "sha512-9pW9ePng6DZpzGPalcrULuhSCcauGAbn8AeU3bE34HcDkGm8Ldt0ysjGkyb64f0K3T5ilV4mriayOVv5fg0ASA==" + }, + "babel-plugin-transform-property-literals": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.4.tgz", + "integrity": "sha512-Pf8JHTjTPxecqVyL6KSwD/hxGpoTZjiEgV7nCx0KFQsJYM0nuuoCajbg09KRmZWeZbJ5NGTySABYv8b/hY1eEA==" + }, + "babel-plugin-transform-regexp-constructors": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.4.3.tgz", + "integrity": "sha512-JjymDyEyRNhAoNFp09y/xGwYVYzT2nWTGrBrWaL6eCg2m+B24qH2jR0AA8V8GzKJTgC8NW6joJmc6nabvWBD/g==" + }, + "babel-plugin-transform-remove-console": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.9.4.tgz", + "integrity": "sha512-88blrUrMX3SPiGkT1GnvVY8E/7A+k6oj3MNvUtTIxJflFzXTw1bHkuJ/y039ouhFMp2prRn5cQGzokViYi1dsg==" + }, + "babel-plugin-transform-remove-debugger": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.9.4.tgz", + "integrity": "sha512-Kd+eTBYlXfwoFzisburVwrngsrz4xh9I0ppoJnU/qlLysxVBRgI4Pj+dk3X8F5tDiehp3hhP8oarRMT9v2Z3lw==" + }, + "babel-plugin-transform-remove-undefined": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.5.0.tgz", + "integrity": "sha512-+M7fJYFaEE/M9CXa0/IRkDbiV3wRELzA1kKQFCJ4ifhrzLKn/9VCCgj9OFmYWwBd8IB48YdgPkHYtbYq+4vtHQ==" + }, + "babel-plugin-transform-simplify-comparison-operators": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.9.4.tgz", + "integrity": "sha512-GLInxhGAQWJ9YIdjwF6dAFlmh4U+kN8pL6Big7nkDzHoZcaDQOtBm28atEhQJq6m9GpAovbiGEShKqXv4BSp0A==" + }, + "babel-plugin-transform-undefined-to-void": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.4.tgz", + "integrity": "sha512-D2UbwxawEY1xVc9svYAUZQM2xarwSNXue2qDIx6CeV2EuMGaes/0su78zlIDIAgE7BvnMw4UpmSo9fDy+znghg==" + }, + "babel-preset-meteor": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/babel-preset-meteor/-/babel-preset-meteor-7.10.0.tgz", + "integrity": "sha512-bcdNfRCQAjTV42cUcmaG5/ltLZZQLpZajUcP+o0Lr+aLTY/XLNkGfASM5383wdXiAkEFl0sDOXeknnLlQtrmdg==" + }, + "babel-preset-minify": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/babel-preset-minify/-/babel-preset-minify-0.5.2.tgz", + "integrity": "sha512-v4GL+kk0TfovbRIKZnC3HPbu2cAGmPAby7BsOmuPdMJfHV+4FVdsGXTH/OOGQRKYdjemBuL1+MsE6mobobhe9w==" + }, + "browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==" + }, + "caniuse-lite": { + "version": "1.0.30001469", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001469.tgz", + "integrity": "sha512-Rcp7221ScNqQPP3W+lVOYDyjdR6dC+neEQCttoNr5bAyz54AboB4iwpnWgyi8P4YUsPybVzT4LgWiBbI3drL4g==" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==" + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==" + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "core-js-compat": { + "version": "3.29.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.29.1.tgz", + "integrity": "sha512-QmchCua884D8wWskMX8tW5ydINzd8oSJVx38lx/pVkFGqztxt73GYre3pm/hyYq8bPf+MW5In4I/uRShFDsbrA==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==" + }, + "electron-to-chromium": { + "version": "1.4.337", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.337.tgz", + "integrity": "sha512-W8gdzXG86mVPoc56eM8YA+QiLxaAxJ8cmDjxZgfhLLWVvZQxyA918w5tX2JEWApZta45T1/sYcmFHTsTOUE3nw==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==" + }, + "is-reference": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", + "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, "json5": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==" }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==" + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==" + }, + "magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==" + }, + "meteor-babel-helpers": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/meteor-babel-helpers/-/meteor-babel-helpers-0.0.3.tgz", + "integrity": "sha512-PgfmiyT/HiBaxwGHxS4t3Qi0fpmEW3O0WW2VfrgekiMGz3aZPd9/4PRIaMMZsfyjQ1vyEm6dZqTAFZENbuoTxw==" }, "minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node-releases": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==" + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "periscopic": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-2.0.3.tgz", + "integrity": "sha512-FuCZe61mWxQOJAQFEfmt9FjzebRlcpFz8sFPbyaCKtdusPkMEbA9ey0eARnRav5zAhmXznhaQkKGFAPn7X9NUw==" + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "regenerate-unicode-properties": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==" + }, + "regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "regenerator-transform": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", + "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==" + }, + "regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==" + }, + "regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==" + } + } + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==" + }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==" + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + } + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==" + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" + }, + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==" + }, + "unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==" + }, + "unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==" + }, + "unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==" + }, + "unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==" + }, + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==" }, "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } } diff --git a/packages/minimongo/cursor.js b/packages/minimongo/cursor.js index f09f3db2fb..bf6bffc276 100644 --- a/packages/minimongo/cursor.js +++ b/packages/minimongo/cursor.js @@ -227,7 +227,7 @@ export default class Cursor { * @param {Object} callbacks Functions to call to deliver the result set as it * changes */ - async observeChanges(options) { + observeChanges(options) { const ordered = LocalCollection._observeChangesCallbacksAreOrdered(options); // there are several places that assume you aren't combining skip/limit with @@ -333,29 +333,37 @@ export default class Cursor { query.movedBefore = wrapCallback(options.movedBefore); } - if (!options._suppress_initial && !this.collection.paused) { - const handler = async doc => { - const fields = EJSON.clone(doc); + const isReadyPromise = (async () => { + if (!options._suppress_initial && !this.collection.paused) { + const handler = async (doc) => { + const fields = EJSON.clone(doc); - delete fields._id; + delete fields._id; - if (ordered) { - await query.addedBefore(doc._id, this._projectionFn(fields), null); + if (ordered) { + await query.addedBefore(doc._id, this._projectionFn(fields), null); + } + + await query.added(doc._id, this._projectionFn(fields)); + }; + // it means it's just an array + if (query.results.length) { + for (const doc of query.results) { + await handler(doc); + } } - - await query.added(doc._id, this._projectionFn(fields)); - }; - // it means it's just an array - if (query.results.length) { - for (const doc of query.results) { - await handler(doc); + // it means it's an id map + if (query.results?.size?.()) { + await query.results.forEachAsync(handler); } } - // it means it's an id map - if (query.results?.size?.()) { - await query.results.forEachAsync(handler); - } - } + + // run the observe callbacks resulting from the initial contents + // before we leave the observe. + await this.collection._observeQueue.drain(); + + handle.isReady = true; + })(); const handle = Object.assign(new LocalCollection.ObserveHandle, { collection: this.collection, @@ -363,7 +371,9 @@ export default class Cursor { if (this.reactive) { delete this.collection.queries[qid]; } - } + }, + isReady: false, + isReadyPromise, }); if (this.reactive && Tracker.active) { @@ -377,10 +387,6 @@ export default class Cursor { }); } - // run the observe callbacks resulting from the initial contents - // before we leave the observe. - await this.collection._observeQueue.drain(); - return handle; } diff --git a/packages/minimongo/local_collection.js b/packages/minimongo/local_collection.js index a06bf58aa1..11ff7ce0a6 100644 --- a/packages/minimongo/local_collection.js +++ b/packages/minimongo/local_collection.js @@ -1510,7 +1510,7 @@ LocalCollection._modify = (doc, modifier, options = {}) => { }); }; -LocalCollection._observeFromObserveChanges = async (cursor, observeCallbacks) => { +LocalCollection._observeFromObserveChanges = (cursor, observeCallbacks) => { const transform = cursor.getTransform() || (doc => doc); let suppressed = !!observeCallbacks._suppress_initial; @@ -1647,7 +1647,7 @@ LocalCollection._observeFromObserveChanges = async (cursor, observeCallbacks) => // So we can mark it as safe to reduce the ejson clones. // This is tested by the `mongo-livedata - (extended) scribbling` tests changeObserver.applyChange._fromObserve = true; - const handle = await cursor.observeChanges(changeObserver.applyChange, + const handle = cursor.observeChanges(changeObserver.applyChange, { nonMutatingCallbacks: true }); suppressed = false; From e09196080d39d5191165e7306d7fab1932ebbf16 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Thu, 23 Mar 2023 18:11:19 -0300 Subject: [PATCH 02/14] updated bundle --- meteor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meteor b/meteor index 70d41e3a03..77bd97c8ce 100755 --- a/meteor +++ b/meteor @@ -1,6 +1,6 @@ #!/usr/bin/env bash -BUNDLE_VERSION=14.21.1.8 +BUNDLE_VERSION=14.21.3.1 # OS Check. Put here because here is where we download the precompiled From 3d043423ce74952a6aa29acc9f34112dfbfcb9a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Miernik?= Date: Sat, 25 Mar 2023 15:48:15 +0100 Subject: [PATCH 03/14] Fixed re-suppression in observe. --- packages/minimongo/local_collection.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/minimongo/local_collection.js b/packages/minimongo/local_collection.js index 11ff7ce0a6..47e6a9647d 100644 --- a/packages/minimongo/local_collection.js +++ b/packages/minimongo/local_collection.js @@ -1650,7 +1650,12 @@ LocalCollection._observeFromObserveChanges = (cursor, observeCallbacks) => { const handle = cursor.observeChanges(changeObserver.applyChange, { nonMutatingCallbacks: true }); - suppressed = false; + // If needed, re-enable callbacks as soon as the initial batch is ready. + if (suppressed) { + handle.isReadyPromise.then(() => { + suppressed = false; + }); + } return handle; }; From c6e386b2f2c1d9b6409ddab6f0277b469a18ca6e Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Mon, 27 Mar 2023 10:56:18 -0300 Subject: [PATCH 04/14] updated linter --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 8c32e680dd..fd16128033 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,8 @@ ], "complexity": "off", "func-names": "off", - "no-undef": "warn" + "no-undef": "warn", + "curly": "off" } } } From 00fa5cd7937df38562bf32ec99dc8c8c674022bc Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Mon, 27 Mar 2023 10:56:30 -0300 Subject: [PATCH 05/14] made observe sync --- packages/minimongo/cursor.js | 103 +++++++++++++++-------------------- 1 file changed, 43 insertions(+), 60 deletions(-) diff --git a/packages/minimongo/cursor.js b/packages/minimongo/cursor.js index bf6bffc276..12ede3aa69 100644 --- a/packages/minimongo/cursor.js +++ b/packages/minimongo/cursor.js @@ -237,19 +237,16 @@ export default class Cursor { if (!options._allow_unordered && !ordered && (this.skip || this.limit)) { throw new Error( "Must use an ordered observe with skip or limit (i.e. 'addedBefore' " + - "for observeChanges or 'addedAt' for observe, instead of 'added')." + "for observeChanges or 'addedAt' for observe, instead of 'added')." ); } if (this.fields && (this.fields._id === 0 || this.fields._id === false)) { - throw Error('You may not observe a cursor with {fields: {_id: 0}}'); + throw Error("You may not observe a cursor with {fields: {_id: 0}}"); } - const distances = ( - this.matcher.hasGeoQuery() && - ordered && - new LocalCollection._IdMap - ); + const distances = + this.matcher.hasGeoQuery() && ordered && new LocalCollection._IdMap(); const query = { cursor: this, @@ -259,7 +256,7 @@ export default class Cursor { ordered, projectionFn: this._projectionFn, resultsSnapshot: null, - sorter: ordered && this.sorter + sorter: ordered && this.sorter, }; let qid; @@ -271,10 +268,13 @@ export default class Cursor { this.collection.queries[qid] = query; } - query.results = this._getRawObjects({ordered, distances: query.distances}); + query.results = this._getRawObjects({ + ordered, + distances: query.distances, + }); if (this.collection.paused) { - query.resultsSnapshot = ordered ? [] : new LocalCollection._IdMap; + query.resultsSnapshot = ordered ? [] : new LocalCollection._IdMap(); } // wrap callbacks we were passed. callbacks only fire when not paused and @@ -284,43 +284,23 @@ export default class Cursor { // furthermore, callbacks enqueue until the operation we're working on is // done. - const wrapCallback = fn => { + const wrapCallback = (fn) => { if (!fn) { return () => {}; } const self = this; - if (Meteor.isClient) { - return function(/* args*/) { - if (self.collection.paused) { - return; - } - - const args = arguments; - - self.collection._observeQueue.queueTask(() => { - fn.apply(this, args); - }); - }; - } - - return function(/* args*/) { + return function (/* args*/) { if (self.collection.paused) { return; } - let resolve; - const promise = new Promise(r => resolve = r); - const args = arguments; self.collection._observeQueue.queueTask(() => { fn.apply(this, args); - resolve(); }); - - return promise; }; }; @@ -333,39 +313,31 @@ export default class Cursor { query.movedBefore = wrapCallback(options.movedBefore); } - const isReadyPromise = (async () => { - if (!options._suppress_initial && !this.collection.paused) { - const handler = async (doc) => { - const fields = EJSON.clone(doc); + if (!options._suppress_initial && !this.collection.paused) { + const handler = (doc) => { + const fields = EJSON.clone(doc); - delete fields._id; + delete fields._id; - if (ordered) { - await query.addedBefore(doc._id, this._projectionFn(fields), null); - } - - await query.added(doc._id, this._projectionFn(fields)); - }; - // it means it's just an array - if (query.results.length) { - for (const doc of query.results) { - await handler(doc); - } + if (ordered) { + query.addedBefore(doc._id, this._projectionFn(fields), null); } - // it means it's an id map - if (query.results?.size?.()) { - await query.results.forEachAsync(handler); + + query.added(doc._id, this._projectionFn(fields)); + }; + // it means it's just an array + if (query.results.length) { + for (const doc of query.results) { + handler(doc); } } + // it means it's an id map + if (query.results?.size?.()) { + query.results.forEachAsync(handler); + } + } - // run the observe callbacks resulting from the initial contents - // before we leave the observe. - await this.collection._observeQueue.drain(); - - handle.isReady = true; - })(); - - const handle = Object.assign(new LocalCollection.ObserveHandle, { + const handle = Object.assign(new LocalCollection.ObserveHandle(), { collection: this.collection, stop: () => { if (this.reactive) { @@ -373,7 +345,7 @@ export default class Cursor { } }, isReady: false, - isReadyPromise, + isReadyPromise: null, }); if (this.reactive && Tracker.active) { @@ -387,6 +359,17 @@ export default class Cursor { }); } + // run the observe callbacks resulting from the initial contents + // before we leave the observe. + const isReadyPromise = this.collection._observeQueue.drain(); + + if (Meteor.isClient) handle.isReady = true; + else isReadyPromise.then(() => (handle.isReady = true)); + + handle.isReadyPromise = Meteor.isClient + ? Promise.resolve() + : isReadyPromise; + return handle; } From 628bfb28748b17e197b5d046771870183459b141 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Mon, 27 Mar 2023 10:57:14 -0300 Subject: [PATCH 06/14] tests: added sleep to test to make it work --- packages/minimongo/minimongo_tests_client.js | 87 +++++++++++++------- 1 file changed, 55 insertions(+), 32 deletions(-) diff --git a/packages/minimongo/minimongo_tests_client.js b/packages/minimongo/minimongo_tests_client.js index 450a53f122..9193f59efd 100644 --- a/packages/minimongo/minimongo_tests_client.js +++ b/packages/minimongo/minimongo_tests_client.js @@ -3207,63 +3207,86 @@ Tinytest.addAsync('minimongo - observe ordered', async test => { handle.stop(); }); -[true, false].forEach(ordered => { - Tinytest.addAsync(`minimongo - observe ordered: ${ordered}`, async test => { +[true, false].forEach((ordered) => { + Tinytest.addAsync(`minimongo - observe ordered: ${ordered}`, async (test) => { const c = new LocalCollection(); - let ev = ''; - const makecb = tag => { + let ev = ""; + const makecb = (tag) => { const ret = {}; - ['added', 'changed', 'removed'].forEach(fn => { + ["added", "changed", "removed"].forEach((fn) => { const fnName = ordered ? `${fn}At` : fn; - ret[fnName] = doc => { + ret[fnName] = (doc) => { ev = `${ev + fn.substr(0, 1) + tag + doc._id}_`; }; }); return ret; }; - const expect = x => { + const expect = (x) => { test.equal(ev, x); - ev = ''; + ev = ""; }; - await c.insertAsync({_id: 1, name: 'strawberry', tags: ['fruit', 'red', 'squishy']}); - await c.insertAsync({_id: 2, name: 'apple', tags: ['fruit', 'red', 'hard']}); - await c.insertAsync({_id: 3, name: 'rose', tags: ['flower', 'red', 'squishy']}); + await c.insertAsync({ + _id: 1, + name: "strawberry", + tags: ["fruit", "red", "squishy"], + }); + await c.insertAsync({ + _id: 2, + name: "apple", + tags: ["fruit", "red", "hard"], + }); + await c.insertAsync({ + _id: 3, + name: "rose", + tags: ["flower", "red", "squishy"], + }); // This should work equally well for ordered and unordered observations // (because the callbacks don't look at indices and there's no 'moved' // callback). - let handle = await c.find({tags: 'flower'}).observe(makecb('a')); - expect('aa3_'); - await c.updateAsync({name: 'rose'}, {$set: {tags: ['bloom', 'red', 'squishy']}}); - expect('ra3_'); - await c.updateAsync({name: 'rose'}, {$set: {tags: ['flower', 'red', 'squishy']}}); - expect('aa3_'); - await c.updateAsync({name: 'rose'}, {$set: {food: false}}); - expect('ca3_'); + let handle = await c.find({ tags: "flower" }).observe(makecb("a")); + expect("aa3_"); + await c.updateAsync( + { name: "rose" }, + { $set: { tags: ["bloom", "red", "squishy"] } } + ); + expect("ra3_"); + await c.updateAsync( + { name: "rose" }, + { $set: { tags: ["flower", "red", "squishy"] } } + ); + expect("aa3_"); + await c.updateAsync({ name: "rose" }, { $set: { food: false } }); + expect("ca3_"); c.remove({}); - expect('ra3_'); - await c.insertAsync({_id: 4, name: 'daisy', tags: ['flower']}); - expect('aa4_'); + expect("ra3_"); + await c.insertAsync({ _id: 4, name: "daisy", tags: ["flower"] }); + expect("aa4_"); handle.stop(); // After calling stop, no more callbacks are called. - await c.insertAsync({_id: 5, name: 'iris', tags: ['flower']}); - expect(''); + await c.insertAsync({ _id: 5, name: "iris", tags: ["flower"] }); + expect(""); // Test that observing a lookup by ID works. - handle = await c.find(4).observe(makecb('b')); - expect('ab4_'); - await c.updateAsync(4, {$set: {eek: 5}}); - expect('cb4_'); + handle = await c.find(4).observe(makecb("b")); + expect("ab4_"); + await c.updateAsync(4, { $set: { eek: 5 } }); + expect("cb4_"); handle.stop(); // Test observe with reactive: false. - handle = await c.find({tags: 'flower'}, {reactive: false}).observe(makecb('c')); - expect('ac4_ac5_'); + handle = await c + .find({ tags: "flower" }, { reactive: false }) + .observe(makecb("c")); + // TODO: think about this one below. + const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); + await sleep(10); + expect("ac4_ac5_"); // This insert shouldn't trigger a callback because it's not reactive. - await c.insertAsync({_id: 6, name: 'river', tags: ['flower']}); - expect(''); + await c.insertAsync({ _id: 6, name: "river", tags: ["flower"] }); + expect(""); handle.stop(); }); }); From ab07063c63561e5f803aeb770e9cdce18dec5044 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Mon, 27 Mar 2023 10:57:23 -0300 Subject: [PATCH 07/14] removed: async client tests --- .../minimongo/minimongo_tests_client_async.js | 3915 ----------------- packages/minimongo/package.js | 1 - 2 files changed, 3916 deletions(-) delete mode 100644 packages/minimongo/minimongo_tests_client_async.js diff --git a/packages/minimongo/minimongo_tests_client_async.js b/packages/minimongo/minimongo_tests_client_async.js deleted file mode 100644 index 6b4164e7d1..0000000000 --- a/packages/minimongo/minimongo_tests_client_async.js +++ /dev/null @@ -1,3915 +0,0 @@ -import {hasOwn} from './common'; - -// Hack to make LocalCollection generate ObjectIDs by default. -LocalCollection._useOID = true; - -// assert that f is a strcmp-style comparison function that puts -// 'values' in the provided order - -const assert_ordering = (test, f, values) => { - for (let i = 0; i < values.length; i++) { - let x = f(values[i], values[i]); - if (x !== 0) { - // XXX super janky - test.fail({type: 'minimongo-ordering', - message: "value doesn't order as equal to itself", - value: JSON.stringify(values[i]), - should_be_zero_but_got: JSON.stringify(x)}); - } - if (i + 1 < values.length) { - const less = values[i]; - const more = values[i + 1]; - x = f(less, more); - if (!(x < 0)) { - // XXX super janky - test.fail({type: 'minimongo-ordering', - message: 'ordering test failed', - first: JSON.stringify(less), - second: JSON.stringify(more), - should_be_negative_but_got: JSON.stringify(x)}); - } - x = f(more, less); - if (!(x > 0)) { - // XXX super janky - test.fail({type: 'minimongo-ordering', - message: 'ordering test failed', - first: JSON.stringify(less), - second: JSON.stringify(more), - should_be_positive_but_got: JSON.stringify(x)}); - } - } - } -}; - -const log_callbacks = operations => ({ - addedAt(obj, idx, before) { - delete obj._id; - operations.push(EJSON.clone(['added', obj, idx, before])); - }, - - changedAt(obj, old_obj, at) { - delete obj._id; - delete old_obj._id; - operations.push(EJSON.clone(['changed', obj, at, old_obj])); - }, - - movedTo(obj, old_at, new_at, before) { - delete obj._id; - operations.push(EJSON.clone(['moved', obj, old_at, new_at, before])); - }, - - removedAt(old_obj, at) { - const id = old_obj._id; - delete old_obj._id; - operations.push(EJSON.clone(['removed', id, at, old_obj])); - }, -}); - -// XXX test shared structure in all MM entrypoints -Tinytest.addAsync('async - minimongo - basics', async test => { - const c = new LocalCollection(); - let fluffyKitten_id; - let count; - - fluffyKitten_id = await c.insertAsync({type: 'kitten', name: 'fluffy'}); - await c.insertAsync({type: 'kitten', name: 'snookums'}); - await c.insertAsync({type: 'cryptographer', name: 'alice'}); - await c.insertAsync({type: 'cryptographer', name: 'bob'}); - await c.insertAsync({type: 'cryptographer', name: 'cara'}); - test.equal(await c.find().countAsync(), 5); - test.equal(await c.find({type: 'kitten'}).countAsync(), 2); - test.equal(await c.find({type: 'cryptographer'}).countAsync(), 3); - test.length(await c.find({type: 'kitten'}).fetchAsync(), 2); - test.length(await c.find({type: 'cryptographer'}).fetchAsync(), 3); - test.equal(fluffyKitten_id, c.findOne({type: 'kitten', name: 'fluffy'})._id); - - await c.removeAsync({name: 'cara'}); - test.equal(await c.find().countAsync(), 4); - test.equal(await c.find({type: 'kitten'}).countAsync(), 2); - test.equal(await c.find({type: 'cryptographer'}).countAsync(), 2); - test.length(await c.find({type: 'kitten'}).fetchAsync(), 2); - test.length(await c.find({type: 'cryptographer'}).fetchAsync(), 2); - - count = await c.updateAsync({name: 'snookums'}, {$set: {type: 'cryptographer'}}); - test.equal(count, 1); - test.equal(await c.find().countAsync(), 4); - test.equal(await c.find({type: 'kitten'}).countAsync(), 1); - test.equal(await c.find({type: 'cryptographer'}).countAsync(), 3); - test.length(await c.find({type: 'kitten'}).fetchAsync(), 1); - test.length(await c.find({type: 'cryptographer'}).fetchAsync(), 3); - - await c.removeAsync(null); - await c.removeAsync(false); - await c.removeAsync(undefined); - test.equal(await c.find().countAsync(), 4); - - await c.removeAsync({_id: null}); - await c.removeAsync({_id: false}); - await c.removeAsync({_id: undefined}); - count = await c.removeAsync(); - test.equal(count, 0); - // test.equal(await c.find().countAsync(), 4); - // - // count = await c.removeAsync({}); - // test.equal(count, 4); - // test.equal(await c.find().countAsync(), 0); - // - // await c.insertAsync({_id: 1, name: 'strawberry', tags: ['fruit', 'red', 'squishy']}); - // await c.insertAsync({_id: 2, name: 'apple', tags: ['fruit', 'red', 'hard']}); - // await c.insertAsync({_id: 3, name: 'rose', tags: ['flower', 'red', 'squishy']}); - // - // test.equal(await c.find({tags: 'flower'}).countAsync(), 1); - // test.equal(await c.find({tags: 'fruit'}).countAsync(), 2); - // test.equal(await c.find({tags: 'red'}).countAsync(), 3); - // test.length(await c.find({tags: 'flower'}).fetchAsync(), 1); - // test.length(await c.find({tags: 'fruit'}).fetchAsync(), 2); - // test.length(await c.find({tags: 'red'}).fetchAsync(), 3); - // - // test.equal(c.findOne(1).name, 'strawberry'); - // test.equal(c.findOne(2).name, 'apple'); - // test.equal(c.findOne(3).name, 'rose'); - // test.equal(c.findOne(4), undefined); - // test.equal(c.findOne('abc'), undefined); - // test.equal(c.findOne(undefined), undefined); - // - // test.equal(c.find(1).count(), 1); - // test.equal(c.find(4).count(), 0); - // test.equal(c.find('abc').count(), 0); - // test.equal(c.find(undefined).count(), 0); - // test.equal(c.find().count(), 3); - // test.equal(c.find(1, {skip: 1}).count(false), 0); - // test.equal(c.find(1, {skip: 1}).count(), 0); - // test.equal(c.find({_id: 1}, {skip: 1}).count(false), 0); - // test.equal(c.find({_id: 1}, {skip: 1}).count(), 0); - // test.equal(c.find({_id: undefined}).count(), 0); - // test.equal(c.find({_id: false}).count(), 0); - // test.equal(c.find({_id: null}).count(), 0); - // test.equal(c.find({_id: ''}).count(), 0); - // test.equal(c.find({_id: 0}).count(), 0); - // test.equal(c.find({}, {skip: 1}).count(false), 2); - // test.equal(c.find({}, {skip: 1}).count(), 2); - // test.equal(c.find({}, {skip: 2}).count(), 1); - // test.equal(c.find({}, {limit: 2}).count(false), 2); - // test.equal(c.find({}, {limit: 2}).count(), 2); - // test.equal(c.find({}, {limit: 1}).count(), 1); - // test.equal(c.find({}, {skip: 1, limit: 1}).count(false), 1); - // test.equal(c.find({}, {skip: 1, limit: 1}).count(), 1); - // test.equal(c.find({tags: 'fruit'}, {skip: 1}).count(false), 1); - // test.equal(c.find({tags: 'fruit'}, {skip: 1}).count(), 1); - // test.equal(c.find({tags: 'fruit'}, {limit: 1}).count(false), 1); - // test.equal(c.find({tags: 'fruit'}, {limit: 1}).count(), 1); - // test.equal(c.find({tags: 'fruit'}, {skip: 1, limit: 1}).count(false), 1); - // test.equal(c.find({tags: 'fruit'}, {skip: 1, limit: 1}).count(), 1); - // test.equal(c.find(1, {sort: ['_id', 'desc'], skip: 1}).count(false), 0); - // test.equal(c.find(1, {sort: ['_id', 'desc'], skip: 1}).count(), 0); - // test.equal(c.find({_id: 1}, {sort: ['_id', 'desc'], skip: 1}).count(false), 0); - // test.equal(c.find({_id: 1}, {sort: ['_id', 'desc'], skip: 1}).count(), 0); - // test.equal(c.find({}, {sort: ['_id', 'desc'], skip: 1}).count(false), 2); - // test.equal(c.find({}, {sort: ['_id', 'desc'], skip: 1}).count(), 2); - // test.equal(c.find({}, {sort: ['_id', 'desc'], skip: 2}).count(), 1); - // test.equal(c.find({}, {sort: ['_id', 'desc'], limit: 2}).count(false), 2); - // test.equal(c.find({}, {sort: ['_id', 'desc'], limit: 2}).count(), 2); - // test.equal(c.find({}, {sort: ['_id', 'desc'], limit: 1}).count(), 1); - // test.equal(c.find({}, {sort: ['_id', 'desc'], skip: 1, limit: 1}).count(false), 1); - // test.equal(c.find({}, {sort: ['_id', 'desc'], skip: 1, limit: 1}).count(), 1); - // test.equal(c.find({tags: 'fruit'}, {sort: ['_id', 'desc'], skip: 1}).count(false), 1); - // test.equal(c.find({tags: 'fruit'}, {sort: ['_id', 'desc'], skip: 1}).count(), 1); - // test.equal(c.find({tags: 'fruit'}, {sort: ['_id', 'desc'], limit: 1}).count(false), 1); - // test.equal(c.find({tags: 'fruit'}, {sort: ['_id', 'desc'], limit: 1}).count(), 1); - // test.equal(c.find({tags: 'fruit'}, {sort: ['_id', 'desc'], skip: 1, limit: 1}).count(false), 1); - // test.equal(c.find({tags: 'fruit'}, {sort: ['_id', 'desc'], skip: 1, limit: 1}).count(), 1); - // - // // Regression test for #455. - // await c.insertAsync({foo: {bar: 'baz'}}); - // test.equal(c.find({foo: {bam: 'baz'}}).count(), 0); - // test.equal(c.find({foo: {bar: 'baz'}}).count(), 1); - // - // // Regression test for #5301 - // await c.removeAsync({}); - // await c.insertAsync({a: 'a', b: 'b'}); - // const noop = () => null; - // test.equal(c.find({a: noop}).count(), 1); - // test.equal(c.find({a: 'a', b: noop}).count(), 1); - // test.equal(c.find({c: noop}).count(), 1); - // test.equal(c.find({a: noop, c: 'c'}).count(), 0); - // - // // Regression test for #4260 - // // Only insert enumerable, own properties from the object - // await c.removeAsync({}); - // function Thing() { - // this.a = 1; - // this.b = 2; - // Object.defineProperty(this, 'b', { enumerable: false }); - // } - // Thing.prototype.c = 3; - // Thing.prototype.d = () => null; - // const before = new Thing(); - // await c.insertAsync(before); - // const after = c.findOne(); - // test.equal(after.a, 1); - // test.equal(after.b, undefined); - // test.equal(after.c, undefined); - // test.equal(after.d, undefined); -}); - -Tinytest.addAsync('async - minimongo - error - no options', async test => { - try { - throw MinimongoError('Not fun to have errors'); - } catch (e) { - test.equal(e.message, 'Not fun to have errors'); - } -}); - -Tinytest.addAsync('async - minimongo - error - with field', async test => { - try { - throw MinimongoError('Cats are no fun', { field: 'mice' }); - } catch (e) { - test.equal(e.message, "Cats are no fun for field 'mice'"); - } -}); - -Tinytest.addAsync('async - minimongo - cursors', async test => { - const c = new LocalCollection(); - let res; - - for (let i = 0; i < 20; i++) {await c.insertAsync({i});} - - const q = c.find(); - test.equal(q.count(), 20); - - // fetch - res = q.fetch(); - test.length(res, 20); - for (let i = 0; i < 20; i++) { - test.equal(res[i].i, i); - } - // call it again, it still works - test.length(q.fetch(), 20); - - // forEach - let count = 0; - const context = {}; - q.forEach(function(obj, i, cursor) { - test.equal(obj.i, count++); - test.equal(obj.i, i); - test.isTrue(context === this); - test.isTrue(cursor === q); - }, context); - test.equal(count, 20); - // call it again, it still works - test.length(q.fetch(), 20); - - // iterator - count = 0; - for (let obj of q) { - test.equal(obj.i, count++); - }; - test.equal(count, 20); - // call it again, it still works - test.length(q.fetch(), 20); - // test spread operator - test.equal([...q], q.fetch()); - - // map - res = q.map(function(obj, i, cursor) { - test.equal(obj.i, i); - test.isTrue(context === this); - test.isTrue(cursor === q); - return obj.i * 2; - }, context); - test.length(res, 20); - for (let i = 0; i < 20; i++) {test.equal(res[i], i * 2);} - // call it again, it still works - test.length(q.fetch(), 20); - - // findOne (and no rewind first) - test.equal(c.findOne({i: 0}).i, 0); - test.equal(c.findOne({i: 1}).i, 1); - const id = c.findOne({i: 2})._id; - test.equal(c.findOne(id).i, 2); -}); - -Tinytest.addAsync('async - minimongo - transform', async test => { - const c = new LocalCollection; - await c.insertAsync({}); - // transform functions must return objects - const invalidTransform = doc => doc._id; - await test.throwsAsync(() => { - c.findOne({}, {transform: invalidTransform}); - }); - - // transformed documents get _id field transplanted if not present - const transformWithoutId = doc => { - const docWithoutId = Object.assign({}, doc); - delete docWithoutId._id; - return docWithoutId; - }; - test.equal(c.findOne({}, {transform: transformWithoutId})._id, - c.findOne()._id); -}); - -Tinytest.addAsync('async - minimongo - misc', async test => { - // deepcopy - let a = {a: [1, 2, 3], b: 'x', c: true, d: {x: 12, y: [12]}, - f: null, g: new Date()}; - let b = EJSON.clone(a); - test.equal(a, b); - test.isTrue(LocalCollection._f._equal(a, b)); - a.a.push(4); - test.length(b.a, 3); - a.c = false; - test.isTrue(b.c); - b.d.z = 15; - a.d.z = 14; - test.equal(b.d.z, 15); - a.d.y.push(88); - test.length(b.d.y, 1); - test.equal(a.g, b.g); - b.g.setDate(b.g.getDate() + 1); - test.notEqual(a.g, b.g); - - a = {x() {}}; - b = EJSON.clone(a); - a.x.a = 14; - test.equal(b.x.a, 14); // just to document current behavior -}); - -Tinytest.addAsync('async - minimongo - lookup', async test => { - const lookupA = MinimongoTest.makeLookupFunction('a'); - test.equal(lookupA({}), [{value: undefined}]); - test.equal(lookupA({a: 1}), [{value: 1}]); - test.equal(lookupA({a: [1]}), [{value: [1]}]); - - const lookupAX = MinimongoTest.makeLookupFunction('a.x'); - test.equal(lookupAX({a: {x: 1}}), [{value: 1}]); - test.equal(lookupAX({a: {x: [1]}}), [{value: [1]}]); - test.equal(lookupAX({a: 5}), [{value: undefined}]); - test.equal(lookupAX({a: [{x: 1}, {x: [2]}, {y: 3}]}), - [{value: 1, arrayIndices: [0]}, - {value: [2], arrayIndices: [1]}, - {value: undefined, arrayIndices: [2]}]); - - const lookupA0X = MinimongoTest.makeLookupFunction('a.0.x'); - test.equal(lookupA0X({a: [{x: 1}]}), [ - // From interpreting '0' as "0th array element". - {value: 1, arrayIndices: [0, 'x']}, - // From interpreting '0' as "after branching in the array, look in the - // object {x:1} for a field named 0". - {value: undefined, arrayIndices: [0]}]); - test.equal(lookupA0X({a: [{x: [1]}]}), [ - {value: [1], arrayIndices: [0, 'x']}, - {value: undefined, arrayIndices: [0]}]); - test.equal(lookupA0X({a: 5}), [{value: undefined}]); - test.equal(lookupA0X({a: [{x: 1}, {x: [2]}, {y: 3}]}), [ - // From interpreting '0' as "0th array element". - {value: 1, arrayIndices: [0, 'x']}, - // From interpreting '0' as "after branching in the array, look in the - // object {x:1} for a field named 0". - {value: undefined, arrayIndices: [0]}, - {value: undefined, arrayIndices: [1]}, - {value: undefined, arrayIndices: [2]}, - ]); - - test.equal( - MinimongoTest.makeLookupFunction('w.x.0.z')({ - w: [{x: [{z: 5}]}]}), [ - // From interpreting '0' as "0th array element". - {value: 5, arrayIndices: [0, 0, 'x']}, - // From interpreting '0' as "after branching in the array, look in the - // object {z:5} for a field named "0". - {value: undefined, arrayIndices: [0, 0]}, - ]); -}); - -Tinytest.addAsync('async - minimongo - selector_compiler', async test => { - const matches = (shouldMatch, selector, doc) => { - const doesMatch = new Minimongo.Matcher(selector).documentMatches(doc).result; - if (doesMatch != shouldMatch) { - // XXX super janky - test.fail({message: `minimongo match failure: document ${shouldMatch ? "should match, but doesn't" : - "shouldn't match, but does"}`, - selector: JSON.stringify(selector), - document: JSON.stringify(doc), - }); - } - }; - - const match = matches.bind(null, true); - const nomatch = matches.bind(null, false); - - // XXX blog post about what I learned while writing these tests (weird - // mongo edge cases) - - // empty selectors - match({}, {}); - match({}, {a: 12}); - - // scalars - match(1, {_id: 1, a: 'foo'}); - nomatch(1, {_id: 2, a: 'foo'}); - match('a', {_id: 'a', a: 'foo'}); - nomatch('a', {_id: 'b', a: 'foo'}); - - // safety - nomatch(undefined, {}); - nomatch(undefined, {_id: 'foo'}); - nomatch(false, {_id: 'foo'}); - nomatch(null, {_id: 'foo'}); - nomatch({_id: undefined}, {_id: 'foo'}); - nomatch({_id: false}, {_id: 'foo'}); - nomatch({_id: null}, {_id: 'foo'}); - nomatch({_id: ''}, {_id: ''}); - nomatch({_id: 0}, {_id: 0}); - - // matching one or more keys - nomatch({a: 12}, {}); - match({a: 12}, {a: 12}); - match({a: 12}, {a: 12, b: 13}); - match({a: 12, b: 13}, {a: 12, b: 13}); - match({a: 12, b: 13}, {a: 12, b: 13, c: 14}); - nomatch({a: 12, b: 13, c: 14}, {a: 12, b: 13}); - nomatch({a: 12, b: 13}, {b: 13, c: 14}); - - match({a: 12}, {a: [12]}); - match({a: 12}, {a: [11, 12, 13]}); - nomatch({a: 12}, {a: [11, 13]}); - match({a: 12, b: 13}, {a: [11, 12, 13], b: [13, 14, 15]}); - nomatch({a: 12, b: 13}, {a: [11, 12, 13], b: [14, 15]}); - - // dates - const date1 = new Date; - const date2 = new Date(date1.getTime() + 1000); - const date3 = new Date(''); - match({a: date1}, {a: date1}); - nomatch({a: date1}, {a: date2}); - match({a: date3}, {a: date3}); - nomatch({a: date1}, {a: date3}); - nomatch({a: date3}, {a: date1}); - match({a: {$gt: date3}}, {a: date1}); - match({a: {$gte: date3}}, {a: date1}); - nomatch({a: {$lt: date3}}, {a: date1}); - nomatch({a: {$lte: date3}}, {a: date1}); - - - // arrays - match({a: [1, 2]}, {a: [1, 2]}); - match({a: [1, 2]}, {a: [[1, 2]]}); - match({a: [1, 2]}, {a: [[3, 4], [1, 2]]}); - nomatch({a: [1, 2]}, {a: [3, 4]}); - nomatch({a: [1, 2]}, {a: [[[1, 2]]]}); - - // literal documents - match({a: {b: 12}}, {a: {b: 12}}); - nomatch({a: {b: 12, c: 13}}, {a: {b: 12}}); - nomatch({a: {b: 12}}, {a: {b: 12, c: 13}}); - match({a: {b: 12, c: 13}}, {a: {b: 12, c: 13}}); - nomatch({a: {b: 12, c: 13}}, {a: {c: 13, b: 12}}); // tested on mongodb - nomatch({a: {}}, {a: {b: 12}}); - nomatch({a: {b: 12}}, {a: {}}); - match( - {a: {b: 12, c: [13, true, false, 2.2, 'a', null, {d: 14}]}}, - {a: {b: 12, c: [13, true, false, 2.2, 'a', null, {d: 14}]}}); - match({a: {b: 12}}, {a: {b: 12}, k: 99}); - - match({a: {b: 12}}, {a: [{b: 12}]}); - nomatch({a: {b: 12}}, {a: [[{b: 12}]]}); - match({a: {b: 12}}, {a: [{b: 11}, {b: 12}, {b: 13}]}); - nomatch({a: {b: 12}}, {a: [{b: 11}, {b: 12, c: 20}, {b: 13}]}); - nomatch({a: {b: 12, c: 20}}, {a: [{b: 11}, {b: 12}, {c: 20}]}); - match({a: {b: 12, c: 20}}, {a: [{b: 11}, {b: 12, c: 20}, {b: 13}]}); - - // null - match({a: null}, {a: null}); - match({a: null}, {b: 12}); - nomatch({a: null}, {a: 12}); - match({a: null}, {a: [1, 2, null, 3]}); // tested on mongodb - nomatch({a: null}, {a: [1, 2, {}, 3]}); // tested on mongodb - - // order comparisons: $lt, $gt, $lte, $gte - match({a: {$lt: 10}}, {a: 9}); - nomatch({a: {$lt: 10}}, {a: 10}); - nomatch({a: {$lt: 10}}, {a: 11}); - - match({a: {$gt: 10}}, {a: 11}); - nomatch({a: {$gt: 10}}, {a: 10}); - nomatch({a: {$gt: 10}}, {a: 9}); - - match({a: {$lte: 10}}, {a: 9}); - match({a: {$lte: 10}}, {a: 10}); - nomatch({a: {$lte: 10}}, {a: 11}); - - match({a: {$gte: 10}}, {a: 11}); - match({a: {$gte: 10}}, {a: 10}); - nomatch({a: {$gte: 10}}, {a: 9}); - - match({a: {$lt: 10}}, {a: [11, 9, 12]}); - nomatch({a: {$lt: 10}}, {a: [11, 12]}); - - // (there's a full suite of ordering test elsewhere) - nomatch({a: {$lt: 'null'}}, {a: null}); - match({a: {$lt: {x: [2, 3, 4]}}}, {a: {x: [1, 3, 4]}}); - match({a: {$gt: {x: [2, 3, 4]}}}, {a: {x: [3, 3, 4]}}); - nomatch({a: {$gt: {x: [2, 3, 4]}}}, {a: {x: [1, 3, 4]}}); - nomatch({a: {$gt: {x: [2, 3, 4]}}}, {a: {x: [2, 3, 4]}}); - nomatch({a: {$lt: {x: [2, 3, 4]}}}, {a: {x: [2, 3, 4]}}); - match({a: {$gte: {x: [2, 3, 4]}}}, {a: {x: [2, 3, 4]}}); - match({a: {$lte: {x: [2, 3, 4]}}}, {a: {x: [2, 3, 4]}}); - - nomatch({a: {$gt: [2, 3]}}, {a: [1, 2]}); // tested against mongodb - - // composition of two qualifiers - nomatch({a: {$lt: 11, $gt: 9}}, {a: 8}); - nomatch({a: {$lt: 11, $gt: 9}}, {a: 9}); - match({a: {$lt: 11, $gt: 9}}, {a: 10}); - nomatch({a: {$lt: 11, $gt: 9}}, {a: 11}); - nomatch({a: {$lt: 11, $gt: 9}}, {a: 12}); - - match({a: {$lt: 11, $gt: 9}}, {a: [8, 9, 10, 11, 12]}); - match({a: {$lt: 11, $gt: 9}}, {a: [8, 9, 11, 12]}); // tested against mongodb - - // $all - match({a: {$all: [1, 2]}}, {a: [1, 2]}); - nomatch({a: {$all: [1, 2, 3]}}, {a: [1, 2]}); - match({a: {$all: [1, 2]}}, {a: [3, 2, 1]}); - match({a: {$all: [1, 'x']}}, {a: [3, 'x', 1]}); - nomatch({a: {$all: ['2']}}, {a: 2}); - nomatch({a: {$all: [2]}}, {a: '2'}); - match({a: {$all: [[1, 2], [1, 3]]}}, {a: [[1, 3], [1, 2], [1, 4]]}); - nomatch({a: {$all: [[1, 2], [1, 3]]}}, {a: [[1, 4], [1, 2], [1, 4]]}); - match({a: {$all: [2, 2]}}, {a: [2]}); // tested against mongodb - nomatch({a: {$all: [2, 3]}}, {a: [2, 2]}); - - nomatch({a: {$all: [1, 2]}}, {a: [[1, 2]]}); // tested against mongodb - nomatch({a: {$all: [1, 2]}}, {}); // tested against mongodb, field doesn't exist - nomatch({a: {$all: [1, 2]}}, {a: {foo: 'bar'}}); // tested against mongodb, field is not an object - nomatch({a: {$all: []}}, {a: []}); - nomatch({a: {$all: []}}, {a: [5]}); - match({a: {$all: [/i/, /e/i]}}, {a: ['foo', 'bEr', 'biz']}); - nomatch({a: {$all: [/i/, /e/i]}}, {a: ['foo', 'bar', 'biz']}); - match({a: {$all: [{b: 3}]}}, {a: [{b: 3}]}); - // Members of $all other than regexps are *equality matches*, not document - // matches. - nomatch({a: {$all: [{b: 3}]}}, {a: [{b: 3, k: 4}]}); - await test.throwsAsync(() => { - match({a: {$all: [{$gt: 4}]}}, {}); - }); - - // $exists - match({a: {$exists: true}}, {a: 12}); - nomatch({a: {$exists: true}}, {b: 12}); - nomatch({a: {$exists: false}}, {a: 12}); - match({a: {$exists: false}}, {b: 12}); - - match({a: {$exists: true}}, {a: []}); - nomatch({a: {$exists: true}}, {b: []}); - nomatch({a: {$exists: false}}, {a: []}); - match({a: {$exists: false}}, {b: []}); - - match({a: {$exists: true}}, {a: [1]}); - nomatch({a: {$exists: true}}, {b: [1]}); - nomatch({a: {$exists: false}}, {a: [1]}); - match({a: {$exists: false}}, {b: [1]}); - - match({a: {$exists: 1}}, {a: 5}); - match({a: {$exists: 0}}, {b: 5}); - - nomatch({'a.x': {$exists: false}}, {a: [{}, {x: 5}]}); - match({'a.x': {$exists: true}}, {a: [{}, {x: 5}]}); - match({'a.x': {$exists: true}}, {a: [{}, {x: 5}]}); - match({'a.x': {$exists: true}}, {a: {x: []}}); - match({'a.x': {$exists: true}}, {a: {x: null}}); - - // $mod - match({a: {$mod: [10, 1]}}, {a: 11}); - nomatch({a: {$mod: [10, 1]}}, {a: 12}); - match({a: {$mod: [10, 1]}}, {a: [10, 11, 12]}); - nomatch({a: {$mod: [10, 1]}}, {a: [10, 12]}); - [ - 5, - [10], - [10, 1, 2], - 'foo', - {bar: 1}, - [], - ].forEach(badMod => { - test.throws(() => { - match({a: {$mod: badMod}}, {a: 11}); - }); - }); - - // $eq - nomatch({a: {$eq: 1}}, {a: 2}); - match({a: {$eq: 2}}, {a: 2}); - nomatch({a: {$eq: [1]}}, {a: [2]}); - - match({a: {$eq: [1, 2]}}, {a: [1, 2]}); - match({a: {$eq: 1}}, {a: [1, 2]}); - match({a: {$eq: 2}}, {a: [1, 2]}); - nomatch({a: {$eq: 3}}, {a: [1, 2]}); - match({'a.b': {$eq: 1}}, {a: [{b: 1}, {b: 2}]}); - match({'a.b': {$eq: 2}}, {a: [{b: 1}, {b: 2}]}); - nomatch({'a.b': {$eq: 3}}, {a: [{b: 1}, {b: 2}]}); - - match({a: {$eq: {x: 1}}}, {a: {x: 1}}); - nomatch({a: {$eq: {x: 1}}}, {a: {x: 2}}); - nomatch({a: {$eq: {x: 1}}}, {a: {x: 1, y: 2}}); - - // $ne - match({a: {$ne: 1}}, {a: 2}); - nomatch({a: {$ne: 2}}, {a: 2}); - match({a: {$ne: [1]}}, {a: [2]}); - - nomatch({a: {$ne: [1, 2]}}, {a: [1, 2]}); // all tested against mongodb - nomatch({a: {$ne: 1}}, {a: [1, 2]}); - nomatch({a: {$ne: 2}}, {a: [1, 2]}); - match({a: {$ne: 3}}, {a: [1, 2]}); - nomatch({'a.b': {$ne: 1}}, {a: [{b: 1}, {b: 2}]}); - nomatch({'a.b': {$ne: 2}}, {a: [{b: 1}, {b: 2}]}); - match({'a.b': {$ne: 3}}, {a: [{b: 1}, {b: 2}]}); - - nomatch({a: {$ne: {x: 1}}}, {a: {x: 1}}); - match({a: {$ne: {x: 1}}}, {a: {x: 2}}); - match({a: {$ne: {x: 1}}}, {a: {x: 1, y: 2}}); - - // This query means: All 'a.b' must be non-5, and some 'a.b' must be >6. - match({'a.b': {$ne: 5, $gt: 6}}, {a: [{b: 2}, {b: 10}]}); - nomatch({'a.b': {$ne: 5, $gt: 6}}, {a: [{b: 2}, {b: 4}]}); - nomatch({'a.b': {$ne: 5, $gt: 6}}, {a: [{b: 2}, {b: 5}]}); - nomatch({'a.b': {$ne: 5, $gt: 6}}, {a: [{b: 10}, {b: 5}]}); - // Should work the same if the branch is at the bottom. - match({a: {$ne: 5, $gt: 6}}, {a: [2, 10]}); - nomatch({a: {$ne: 5, $gt: 6}}, {a: [2, 4]}); - nomatch({a: {$ne: 5, $gt: 6}}, {a: [2, 5]}); - nomatch({a: {$ne: 5, $gt: 6}}, {a: [10, 5]}); - - // $in - match({a: {$in: [1, 2, 3]}}, {a: 2}); - nomatch({a: {$in: [1, 2, 3]}}, {a: 4}); - match({a: {$in: [[1], [2], [3]]}}, {a: [2]}); - nomatch({a: {$in: [[1], [2], [3]]}}, {a: [4]}); - match({a: {$in: [{b: 1}, {b: 2}, {b: 3}]}}, {a: {b: 2}}); - nomatch({a: {$in: [{b: 1}, {b: 2}, {b: 3}]}}, {a: {b: 4}}); - - match({a: {$in: [1, 2, 3]}}, {a: [2]}); // tested against mongodb - match({a: {$in: [{x: 1}, {x: 2}, {x: 3}]}}, {a: [{x: 2}]}); - match({a: {$in: [1, 2, 3]}}, {a: [4, 2]}); - nomatch({a: {$in: [1, 2, 3]}}, {a: [4]}); - - match({a: {$in: ['x', /foo/i]}}, {a: 'x'}); - match({a: {$in: ['x', /foo/i]}}, {a: 'fOo'}); - match({a: {$in: ['x', /foo/i]}}, {a: ['f', 'fOo']}); - nomatch({a: {$in: ['x', /foo/i]}}, {a: ['f', 'fOx']}); - - match({a: {$in: [1, null]}}, {}); - match({'a.b': {$in: [1, null]}}, {}); - match({'a.b': {$in: [1, null]}}, {a: {}}); - match({'a.b': {$in: [1, null]}}, {a: {b: null}}); - nomatch({'a.b': {$in: [1, null]}}, {a: {b: 5}}); - nomatch({'a.b': {$in: [1]}}, {a: {b: null}}); - nomatch({'a.b': {$in: [1]}}, {a: {}}); - nomatch({'a.b': {$in: [1, null]}}, {a: [{b: 5}]}); - match({'a.b': {$in: [1, null]}}, {a: [{b: 5}, {}]}); - nomatch({'a.b': {$in: [1, null]}}, {a: [{b: 5}, []]}); - nomatch({'a.b': {$in: [1, null]}}, {a: [{b: 5}, 5]}); - - // $nin - nomatch({a: {$nin: [1, 2, 3]}}, {a: 2}); - match({a: {$nin: [1, 2, 3]}}, {a: 4}); - nomatch({a: {$nin: [[1], [2], [3]]}}, {a: [2]}); - match({a: {$nin: [[1], [2], [3]]}}, {a: [4]}); - nomatch({a: {$nin: [{b: 1}, {b: 2}, {b: 3}]}}, {a: {b: 2}}); - match({a: {$nin: [{b: 1}, {b: 2}, {b: 3}]}}, {a: {b: 4}}); - - nomatch({a: {$nin: [1, 2, 3]}}, {a: [2]}); // tested against mongodb - nomatch({a: {$nin: [{x: 1}, {x: 2}, {x: 3}]}}, {a: [{x: 2}]}); - nomatch({a: {$nin: [1, 2, 3]}}, {a: [4, 2]}); - nomatch({'a.b': {$nin: [1, 2, 3]}}, {a: [{b: 4}, {b: 2}]}); - match({a: {$nin: [1, 2, 3]}}, {a: [4]}); - match({'a.b': {$nin: [1, 2, 3]}}, {a: [{b: 4}]}); - - nomatch({a: {$nin: ['x', /foo/i]}}, {a: 'x'}); - nomatch({a: {$nin: ['x', /foo/i]}}, {a: 'fOo'}); - nomatch({a: {$nin: ['x', /foo/i]}}, {a: ['f', 'fOo']}); - match({a: {$nin: ['x', /foo/i]}}, {a: ['f', 'fOx']}); - - nomatch({a: {$nin: [1, null]}}, {}); - nomatch({'a.b': {$nin: [1, null]}}, {}); - nomatch({'a.b': {$nin: [1, null]}}, {a: {}}); - nomatch({'a.b': {$nin: [1, null]}}, {a: {b: null}}); - match({'a.b': {$nin: [1, null]}}, {a: {b: 5}}); - match({'a.b': {$nin: [1]}}, {a: {b: null}}); - match({'a.b': {$nin: [1]}}, {a: {}}); - match({'a.b': {$nin: [1, null]}}, {a: [{b: 5}]}); - nomatch({'a.b': {$nin: [1, null]}}, {a: [{b: 5}, {}]}); - match({'a.b': {$nin: [1, null]}}, {a: [{b: 5}, []]}); - match({'a.b': {$nin: [1, null]}}, {a: [{b: 5}, 5]}); - - // $size - match({a: {$size: 0}}, {a: []}); - match({a: {$size: 1}}, {a: [2]}); - match({a: {$size: 2}}, {a: [2, 2]}); - nomatch({a: {$size: 0}}, {a: [2]}); - nomatch({a: {$size: 1}}, {a: []}); - nomatch({a: {$size: 1}}, {a: [2, 2]}); - nomatch({a: {$size: 0}}, {a: '2'}); - nomatch({a: {$size: 1}}, {a: '2'}); - nomatch({a: {$size: 2}}, {a: '2'}); - - nomatch({a: {$size: 2}}, {a: [[2, 2]]}); // tested against mongodb - - - // $bitsAllClear - number - match({a: {$bitsAllClear: [0, 1, 2, 3]}}, {a: 0}); - match({a: {$bitsAllClear: [0, 1, 2, 3]}}, {a: 0b10000}); - nomatch({a: {$bitsAllClear: [0, 1, 2, 3]}}, {a: 0b1}); - nomatch({a: {$bitsAllClear: [0, 1, 2, 3]}}, {a: 0b10}); - nomatch({a: {$bitsAllClear: [0, 1, 2, 3]}}, {a: 0b100}); - nomatch({a: {$bitsAllClear: [0, 1, 2, 3]}}, {a: 0b1000}); - - // $bitsAllClear - buffer - match({a: {$bitsAllClear: new Uint8Array([3])}}, {a: new Uint8Array([4])}); - match({a: {$bitsAllClear: new Uint8Array([0, 1])}}, {a: new Uint8Array([255])}); // 256 should not be set for 255. - match({a: {$bitsAllClear: new Uint8Array([3])}}, {a: 4 }); - - match({a: {$bitsAllClear: new Uint8Array([3])}}, {a: 0 }); - - // $bitsAllSet - number - match({a: {$bitsAllSet: [0, 1, 2, 3]}}, {a: 0b1111}); - nomatch({a: {$bitsAllSet: [0, 1, 2, 3]}}, {a: 0b111}); - nomatch({a: {$bitsAllSet: [0, 1, 2, 3]}}, {a: 256}); - nomatch({a: {$bitsAllSet: [0, 1, 2, 3]}}, {a: 50000}); - match({a: {$bitsAllSet: [0, 1, 2]}}, {a: 15}); - match({a: {$bitsAllSet: [0, 12]}}, {a: 0b1000000000001}); - nomatch({a: {$bitsAllSet: [0, 12]}}, {a: 0b1000000000000}); - nomatch({a: {$bitsAllSet: [0, 12]}}, {a: 0b1}); - - // $bitsAllSet - buffer - match({a: {$bitsAllSet: new Uint8Array([3])}}, {a: new Uint8Array([3])}); - match({a: {$bitsAllSet: new Uint8Array([7])}}, {a: new Uint8Array([15])}); - match({a: {$bitsAllSet: new Uint8Array([3])}}, {a: 3 }); - - // $bitsAnySet - number - match({a: {$bitsAnySet: [0, 1, 2, 3]}}, {a: 0b1}); - match({a: {$bitsAnySet: [0, 1, 2, 3]}}, {a: 0b10}); - match({a: {$bitsAnySet: [0, 1, 2, 3]}}, {a: 0b100}); - match({a: {$bitsAnySet: [0, 1, 2, 3]}}, {a: 0b1000}); - match({a: {$bitsAnySet: [4]}}, {a: 0b10000}); - nomatch({a: {$bitsAnySet: [0, 1, 2, 3]}}, {a: 0b10000}); - nomatch({a: {$bitsAnySet: [0, 1, 2, 3]}}, {a: 0}); - - // $bitsAnySet - buffer - match({a: {$bitsAnySet: new Uint8Array([3])}}, {a: new Uint8Array([7])}); - match({a: {$bitsAnySet: new Uint8Array([15])}}, {a: new Uint8Array([7])}); - match({a: {$bitsAnySet: new Uint8Array([3])}}, {a: 1 }); - - // $bitsAnyClear - number - match({a: {$bitsAnyClear: [0, 1, 2, 3]}}, {a: 0}); - match({a: {$bitsAnyClear: [0, 1, 2, 3]}}, {a: 0b1}); - match({a: {$bitsAnyClear: [0, 1, 2, 3]}}, {a: 0b10}); - match({a: {$bitsAnyClear: [0, 1, 2, 3]}}, {a: 0b100}); - match({a: {$bitsAnyClear: [0, 1, 2, 3]}}, {a: 0b1000}); - match({a: {$bitsAnyClear: [0, 1, 2, 3]}}, {a: 0b10000}); - nomatch({a: {$bitsAnyClear: [0, 1, 2, 3]}}, {a: 0b1111}); - match({a: {$bitsAnyClear: [0, 1, 2, 3]}}, {a: 0b111}); - nomatch({a: {$bitsAnyClear: [0, 1, 2]}}, {a: 0b111}); - match({a: {$bitsAnyClear: [0, 1, 2, 3]}}, {a: 0b11}); - nomatch({a: {$bitsAnyClear: [0, 1]}}, {a: 0b11}); - match({a: {$bitsAnyClear: [0, 1, 2, 3]}}, {a: 0b1}); - nomatch({a: {$bitsAnyClear: [0]}}, {a: 0b1}); - nomatch({a: {$bitsAnyClear: [4]}}, {a: 0b10000}); - - // $bitsAnyClear - buffer - match({a: {$bitsAnyClear: new Uint8Array([8])}}, {a: new Uint8Array([7])}); - match({a: {$bitsAnyClear: new Uint8Array([1])}}, {a: new Uint8Array([0])}); - match({a: {$bitsAnyClear: new Uint8Array([1])}}, {a: 4 }); - - // taken from: https://github.com/mongodb/mongo/blob/master/jstests/core/bittest.js - const c = new LocalCollection; - function matchCount(query, count) { - const matches = c.find(query).count(); - if (matches !== count) { - test.fail({message: `minimongo match count failure: matched ${matches} times, but should match ${count} times`, - query: JSON.stringify(query), - count: JSON.stringify(count), - }); - } - } - - // Tests on numbers. - - await c.insertAsync({a: 0}); - await c.insertAsync({a: 1}); - await c.insertAsync({a: 54}); - await c.insertAsync({a: 88}); - await c.insertAsync({a: 255}); - - // Tests with bitmask. - matchCount({a: {$bitsAllSet: 0}}, 5); - matchCount({a: {$bitsAllSet: 1}}, 2); - matchCount({a: {$bitsAllSet: 16}}, 3); - matchCount({a: {$bitsAllSet: 54}}, 2); - matchCount({a: {$bitsAllSet: 55}}, 1); - matchCount({a: {$bitsAllSet: 88}}, 2); - matchCount({a: {$bitsAllSet: 255}}, 1); - matchCount({a: {$bitsAllClear: 0}}, 5); - matchCount({a: {$bitsAllClear: 1}}, 3); - matchCount({a: {$bitsAllClear: 16}}, 2); - matchCount({a: {$bitsAllClear: 129}}, 3); - matchCount({a: {$bitsAllClear: 255}}, 1); - matchCount({a: {$bitsAnySet: 0}}, 0); - matchCount({a: {$bitsAnySet: 9}}, 3); - matchCount({a: {$bitsAnySet: 255}}, 4); - matchCount({a: {$bitsAnyClear: 0}}, 0); - matchCount({a: {$bitsAnyClear: 18}}, 3); - matchCount({a: {$bitsAnyClear: 24}}, 3); - matchCount({a: {$bitsAnyClear: 255}}, 4); - - // Tests with array of bit positions. - matchCount({a: {$bitsAllSet: []}}, 5); - matchCount({a: {$bitsAllSet: [0]}}, 2); - matchCount({a: {$bitsAllSet: [4]}}, 3); - matchCount({a: {$bitsAllSet: [1, 2, 4, 5]}}, 2); - matchCount({a: {$bitsAllSet: [0, 1, 2, 4, 5]}}, 1); - matchCount({a: {$bitsAllSet: [3, 4, 6]}}, 2); - matchCount({a: {$bitsAllSet: [0, 1, 2, 3, 4, 5, 6, 7]}}, 1); - matchCount({a: {$bitsAllClear: []}}, 5); - matchCount({a: {$bitsAllClear: [0]}}, 3); - matchCount({a: {$bitsAllClear: [4]}}, 2); - matchCount({a: {$bitsAllClear: [1, 7]}}, 3); - matchCount({a: {$bitsAllClear: [0, 1, 2, 3, 4, 5, 6, 7]}}, 1); - matchCount({a: {$bitsAnySet: []}}, 0); - matchCount({a: {$bitsAnySet: [1, 3]}}, 3); - matchCount({a: {$bitsAnySet: [0, 1, 2, 3, 4, 5, 6, 7]}}, 4); - matchCount({a: {$bitsAnyClear: []}}, 0); - matchCount({a: {$bitsAnyClear: [1, 4]}}, 3); - matchCount({a: {$bitsAnyClear: [3, 4]}}, 3); - matchCount({a: {$bitsAnyClear: [0, 1, 2, 3, 4, 5, 6, 7]}}, 4); - - // Tests with multiple predicates. - matchCount({a: {$bitsAllSet: 54, $bitsAllClear: 201}}, 1); - - // Tests on negative numbers - - await c.removeAsync({}); - await c.insertAsync({a: -0}); - await c.insertAsync({a: -1}); - await c.insertAsync({a: -54}); - - // Tests with bitmask. - matchCount({a: {$bitsAllSet: 0}}, 3); - matchCount({a: {$bitsAllSet: 2}}, 2); - matchCount({a: {$bitsAllSet: 127}}, 1); - matchCount({a: {$bitsAllSet: 74}}, 2); - matchCount({a: {$bitsAllClear: 0}}, 3); - matchCount({a: {$bitsAllClear: 53}}, 2); - matchCount({a: {$bitsAllClear: 127}}, 1); - matchCount({a: {$bitsAnySet: 0}}, 0); - matchCount({a: {$bitsAnySet: 2}}, 2); - matchCount({a: {$bitsAnySet: 127}}, 2); - matchCount({a: {$bitsAnyClear: 0}}, 0); - matchCount({a: {$bitsAnyClear: 53}}, 2); - matchCount({a: {$bitsAnyClear: 127}}, 2); - - // Tests with array of bit positions. - const allPositions = []; - for (let i = 0; i < 64; i++) { - allPositions.push(i); - } - - matchCount({a: {$bitsAllSet: []}}, 3); - matchCount({a: {$bitsAllSet: [1]}}, 2); - matchCount({a: {$bitsAllSet: allPositions}}, 1); - matchCount({a: {$bitsAllSet: [1, 7, 6, 3, 100]}}, 2); - matchCount({a: {$bitsAllClear: []}}, 3); - matchCount({a: {$bitsAllClear: [5, 4, 2, 0]}}, 2); - matchCount({a: {$bitsAllClear: allPositions}}, 1); - matchCount({a: {$bitsAnySet: []}}, 0); - matchCount({a: {$bitsAnySet: [1]}}, 2); - matchCount({a: {$bitsAnySet: allPositions}}, 2); - matchCount({a: {$bitsAnyClear: []}}, 0); - matchCount({a: {$bitsAnyClear: [0, 2, 4, 5, 100]}}, 2); - matchCount({a: {$bitsAnyClear: allPositions}}, 2); - - // Tests with multiple predicates. - matchCount({a: {$bitsAllSet: 74, $bitsAllClear: 53}}, 1); - - // Tests on BinData. - - await c.removeAsync({}); - await c.insertAsync({a: EJSON.parse('{"$binary": "AAAAAAAAAAAAAAAAAAAAAAAAAAAA"}')}); - await c.insertAsync({a: EJSON.parse('{"$binary": "AANgAAAAAAAAAAAAAAAAAAAAAAAA"}')}); - await c.insertAsync({a: EJSON.parse('{"$binary": "JANgqwetkqwklEWRbWERKKJREtbq"}')}); - await c.insertAsync({a: EJSON.parse('{"$binary": "////////////////////////////"}')}); - - // Tests with binary string bitmask. - matchCount({a: {$bitsAllSet: EJSON.parse('{"$binary": "AAAAAAAAAAAAAAAAAAAAAAAAAAAA"}')}}, 4); - matchCount({a: {$bitsAllSet: EJSON.parse('{"$binary": "AANgAAAAAAAAAAAAAAAAAAAAAAAA"}')}}, 3); - matchCount({a: {$bitsAllSet: EJSON.parse('{"$binary": "JANgqwetkqwklEWRbWERKKJREtbq"}')}}, 2); - matchCount({a: {$bitsAllSet: EJSON.parse('{"$binary": "////////////////////////////"}')}}, 1); - matchCount({a: {$bitsAllClear: EJSON.parse('{"$binary": "AAAAAAAAAAAAAAAAAAAAAAAAAAAA"}')}}, 4); - matchCount({a: {$bitsAllClear: EJSON.parse('{"$binary": "AAyfAAAAAAAAAAAAAAAAAAAAAAAA"}')}}, 3); - matchCount({a: {$bitsAllClear: EJSON.parse('{"$binary": "JAyfqwetkqwklEWRbWERKKJREtbq"}')}}, 2); - matchCount({a: {$bitsAllClear: EJSON.parse('{"$binary": "////////////////////////////"}')}}, 1); - matchCount({a: {$bitsAnySet: EJSON.parse('{"$binary": "AAAAAAAAAAAAAAAAAAAAAAAAAAAA"}')}}, 0); - matchCount({a: {$bitsAnySet: EJSON.parse('{"$binary": "AAyfAAAAAAAAAAAAAAAAAAAAAAAA"}')}}, 1); - matchCount({a: {$bitsAnySet: EJSON.parse('{"$binary": "JAyfqwetkqwklEWRbWERKKJREtbq"}')}}, 2); - matchCount({a: {$bitsAnySet: EJSON.parse('{"$binary": "////////////////////////////"}')}}, 3); - matchCount({a: {$bitsAnyClear: EJSON.parse('{"$binary": "AAAAAAAAAAAAAAAAAAAAAAAAAAAA"}')}}, 0); - matchCount({a: {$bitsAnyClear: EJSON.parse('{"$binary": "AANgAAAAAAAAAAAAAAAAAAAAAAAA"}')}}, 1); - matchCount({a: {$bitsAnyClear: EJSON.parse('{"$binary": "JANgqwetkqwklEWRbWERKKJREtbq"}')}}, 2); - matchCount({a: {$bitsAnyClear: EJSON.parse('{"$binary": "////////////////////////////"}')}}, 3); - - // Tests with multiple predicates. - matchCount({ - a: { - $bitsAllSet: EJSON.parse('{"$binary": "AANgAAAAAAAAAAAAAAAAAAAAAAAA"}'), - $bitsAllClear: EJSON.parse('{"$binary": "//yf////////////////////////"}'), - }, - }, 1); - - await c.removeAsync({}); - - nomatch({a: {$bitsAllSet: 1}}, {a: false}); - nomatch({a: {$bitsAllSet: 1}}, {a: NaN}); - nomatch({a: {$bitsAllSet: 1}}, {a: Infinity}); - nomatch({a: {$bitsAllSet: 1}}, {a: null}); - nomatch({a: {$bitsAllSet: 1}}, {a: 'asdf'}); - nomatch({a: {$bitsAllSet: 1}}, {a: ['a', 'b']}); - nomatch({a: {$bitsAllSet: 1}}, {a: {foo: 'bar'}}); - nomatch({a: {$bitsAllSet: 1}}, {a: 1.2}); - nomatch({a: {$bitsAllSet: 1}}, {a: '1'}); - - [ - false, - NaN, - Infinity, - null, - 'asdf', - ['a', 'b'], - {foo: 'bar'}, - 1.2, - '1', - [0, -1], - ].forEach(badValue => { - test.throws(() => { - match({a: {$bitsAllSet: badValue}}, {a: 42}); - }); - }); - - // $type - match({a: {$type: 1}}, {a: 1.1}); - match({a: {$type: 'double'}}, {a: 1.1}); - match({a: {$type: 1}}, {a: 1}); - nomatch({a: {$type: 1}}, {a: '1'}); - match({a: {$type: 2}}, {a: '1'}); - match({a: {$type: 'string'}}, {a: '1'}); - nomatch({a: {$type: 2}}, {a: 1}); - match({a: {$type: 3}}, {a: {}}); - match({a: {$type: 'object'}}, {a: {}}); - match({a: {$type: 3}}, {a: {b: 2}}); - nomatch({a: {$type: 3}}, {a: []}); - nomatch({a: {$type: 3}}, {a: [1]}); - nomatch({a: {$type: 3}}, {a: null}); - match({a: {$type: 5}}, {a: EJSON.newBinary(0)}); - match({a: {$type: 'binData'}}, {a: EJSON.newBinary(0)}); - match({a: {$type: 5}}, {a: EJSON.newBinary(4)}); - nomatch({a: {$type: 5}}, {a: []}); - nomatch({a: {$type: 5}}, {a: [42]}); - match({a: {$type: 7}}, {a: new MongoID.ObjectID()}); - match({a: {$type: 'objectId'}}, {a: new MongoID.ObjectID()}); - nomatch({a: {$type: 7}}, {a: '1234567890abcd1234567890'}); - match({a: {$type: 8}}, {a: true}); - match({a: {$type: 'bool'}}, {a: true}); - match({a: {$type: 8}}, {a: false}); - nomatch({a: {$type: 8}}, {a: 'true'}); - nomatch({a: {$type: 8}}, {a: 0}); - nomatch({a: {$type: 8}}, {a: null}); - nomatch({a: {$type: 8}}, {a: ''}); - nomatch({a: {$type: 8}}, {}); - match({a: {$type: 9}}, {a: new Date}); - match({a: {$type: 'date'}}, {a: new Date}); - nomatch({a: {$type: 9}}, {a: +new Date}); - match({a: {$type: 10}}, {a: null}); - match({a: {$type: 'null'}}, {a: null}); - nomatch({a: {$type: 10}}, {a: false}); - nomatch({a: {$type: 10}}, {a: ''}); - nomatch({a: {$type: 10}}, {a: 0}); - nomatch({a: {$type: 10}}, {}); - match({a: {$type: 11}}, {a: /x/}); - match({a: {$type: 'regex'}}, {a: /x/}); - nomatch({a: {$type: 11}}, {a: 'x'}); - nomatch({a: {$type: 11}}, {}); - - // The normal rule for {$type:4} (4 means array) is that it NOT good enough to - // just have an array that's the leaf that matches the path. (An array inside - // that array is good, though.) - nomatch({a: {$type: 4}}, {a: []}); - nomatch({a: {$type: 4}}, {a: [1]}); // tested against mongodb - match({a: {$type: 1}}, {a: [1]}); - nomatch({a: {$type: 2}}, {a: [1]}); - match({a: {$type: 1}}, {a: ['1', 1]}); - match({a: {$type: 2}}, {a: ['1', 1]}); - nomatch({a: {$type: 3}}, {a: ['1', 1]}); - nomatch({a: {$type: 4}}, {a: ['1', 1]}); - nomatch({a: {$type: 1}}, {a: ['1', []]}); - match({a: {$type: 2}}, {a: ['1', []]}); - match({a: {$type: 4}}, {a: ['1', []]}); // tested against mongodb - // An exception to the normal rule is that an array found via numeric index is - // examined itself, and its elements are not. - match({'a.0': {$type: 4}}, {a: [[0]]}); - match({'a.0': {$type: 'array'}}, {a: [[0]]}); - nomatch({'a.0': {$type: 1}}, {a: [[0]]}); - - // invalid types should throw errors - await test.throwsAsync(() => { - match({a: {$type: 'foo'}}, {a: 1}); - }); - await test.throwsAsync(() => { - match({a: {$type: -2}}, {a: 1}); - }); - await test.throwsAsync(() => { - match({a: {$type: 0}}, {a: 1}); - }); - await test.throwsAsync(() => { - match({a: {$type: 20}}, {a: 1}); - }); - - // regular expressions - match({a: /a/}, {a: 'cat'}); - nomatch({a: /a/}, {a: 'cut'}); - nomatch({a: /a/}, {a: 'CAT'}); - match({a: /a/i}, {a: 'CAT'}); - match({a: /a/}, {a: ['foo', 'bar']}); // search within array... - nomatch({a: /,/}, {a: ['foo', 'bar']}); // but not by stringifying - match({a: {$regex: 'a'}}, {a: ['foo', 'bar']}); - nomatch({a: {$regex: ','}}, {a: ['foo', 'bar']}); - match({a: {$regex: /a/}}, {a: 'cat'}); - nomatch({a: {$regex: /a/}}, {a: 'cut'}); - nomatch({a: {$regex: /a/}}, {a: 'CAT'}); - match({a: {$regex: /a/i}}, {a: 'CAT'}); - match({a: {$regex: /a/, $options: 'i'}}, {a: 'CAT'}); // tested - match({a: {$regex: /a/i, $options: 'i'}}, {a: 'CAT'}); // tested - nomatch({a: {$regex: /a/i, $options: ''}}, {a: 'CAT'}); // tested - match({a: {$regex: 'a'}}, {a: 'cat'}); - nomatch({a: {$regex: 'a'}}, {a: 'cut'}); - nomatch({a: {$regex: 'a'}}, {a: 'CAT'}); - match({a: {$regex: 'a', $options: 'i'}}, {a: 'CAT'}); - match({a: {$regex: '', $options: 'i'}}, {a: 'foo'}); - nomatch({a: {$regex: '', $options: 'i'}}, {}); - nomatch({a: {$regex: '', $options: 'i'}}, {a: 5}); - nomatch({a: /undefined/}, {}); - nomatch({a: {$regex: 'undefined'}}, {}); - nomatch({a: /xxx/}, {}); - nomatch({a: {$regex: 'xxx'}}, {}); - - // GitHub issue #2817: - // Regexps with a global flag ('g') keep a state when tested against the same - // string. Selector shouldn't return different result for similar documents - // because of this state. - const reusedRegexp = /sh/ig; - match({a: reusedRegexp}, {a: 'Shorts'}); - match({a: reusedRegexp}, {a: 'Shorts'}); - match({a: reusedRegexp}, {a: 'Shorts'}); - - match({a: {$regex: reusedRegexp}}, {a: 'Shorts'}); - match({a: {$regex: reusedRegexp}}, {a: 'Shorts'}); - match({a: {$regex: reusedRegexp}}, {a: 'Shorts'}); - - await test.throwsAsync(() => { - match({a: {$options: 'i'}}, {a: 12}); - }); - - match({a: /a/}, {a: ['dog', 'cat']}); - nomatch({a: /a/}, {a: ['dog', 'puppy']}); - - // we don't support regexps in minimongo very well (eg, there's no EJSON - // encoding so it won't go over the wire), but run these tests anyway - match({a: /a/}, {a: /a/}); - match({a: /a/}, {a: ['x', /a/]}); - nomatch({a: /a/}, {a: /a/i}); - nomatch({a: /a/m}, {a: /a/}); - nomatch({a: /a/}, {a: /b/}); - nomatch({a: /5/}, {a: 5}); - nomatch({a: /t/}, {a: true}); - match({a: /m/i}, {a: ['x', 'xM']}); - - await test.throwsAsync(() => { - match({a: {$regex: /a/, $options: 'x'}}, {a: 'cat'}); - }); - await test.throwsAsync(() => { - match({a: {$regex: /a/, $options: 's'}}, {a: 'cat'}); - }); - - // $not - match({x: {$not: {$gt: 7}}}, {x: 6}); - nomatch({x: {$not: {$gt: 7}}}, {x: 8}); - match({x: {$not: {$lt: 10, $gt: 7}}}, {x: 11}); - nomatch({x: {$not: {$lt: 10, $gt: 7}}}, {x: 9}); - match({x: {$not: {$lt: 10, $gt: 7}}}, {x: 6}); - - match({x: {$not: {$gt: 7}}}, {x: [2, 3, 4]}); - match({'x.y': {$not: {$gt: 7}}}, {x: [{y: 2}, {y: 3}, {y: 4}]}); - nomatch({x: {$not: {$gt: 7}}}, {x: [2, 3, 4, 10]}); - nomatch({'x.y': {$not: {$gt: 7}}}, {x: [{y: 2}, {y: 3}, {y: 4}, {y: 10}]}); - - match({x: {$not: /a/}}, {x: 'dog'}); - nomatch({x: {$not: /a/}}, {x: 'cat'}); - match({x: {$not: /a/}}, {x: ['dog', 'puppy']}); - nomatch({x: {$not: /a/}}, {x: ['kitten', 'cat']}); - - // dotted keypaths: bare values - match({'a.b': 1}, {a: {b: 1}}); - nomatch({'a.b': 1}, {a: {b: 2}}); - match({'a.b': [1, 2, 3]}, {a: {b: [1, 2, 3]}}); - nomatch({'a.b': [1, 2, 3]}, {a: {b: [4]}}); - match({'a.b': /a/}, {a: {b: 'cat'}}); - nomatch({'a.b': /a/}, {a: {b: 'dog'}}); - match({'a.b.c': null}, {}); - match({'a.b.c': null}, {a: 1}); - match({'a.b': null}, {a: 1}); - match({'a.b.c': null}, {a: {b: 4}}); - - // dotted keypaths, nulls, numeric indices, arrays - nomatch({'a.b': null}, {a: [1]}); - match({'a.b': []}, {a: {b: []}}); - const big = {a: [{b: 1}, 2, {}, {b: [3, 4]}]}; - match({'a.b': 1}, big); - match({'a.b': [3, 4]}, big); - match({'a.b': 3}, big); - match({'a.b': 4}, big); - match({'a.b': null}, big); // matches on slot 2 - match({'a.1': 8}, {a: [7, 8, 9]}); - nomatch({'a.1': 7}, {a: [7, 8, 9]}); - nomatch({'a.1': null}, {a: [7, 8, 9]}); - match({'a.1': [8, 9]}, {a: [7, [8, 9]]}); - nomatch({'a.1': 6}, {a: [[6, 7], [8, 9]]}); - nomatch({'a.1': 7}, {a: [[6, 7], [8, 9]]}); - nomatch({'a.1': 8}, {a: [[6, 7], [8, 9]]}); - nomatch({'a.1': 9}, {a: [[6, 7], [8, 9]]}); - match({'a.1': 2}, {a: [0, {1: 2}, 3]}); - match({'a.1': {1: 2}}, {a: [0, {1: 2}, 3]}); - match({'x.1.y': 8}, {x: [7, {y: 8}, 9]}); - // comes from trying '1' as key in the plain object - match({'x.1.y': null}, {x: [7, {y: 8}, 9]}); - match({'a.1.b': 9}, {a: [7, {b: 9}, {1: {b: 'foo'}}]}); - match({'a.1.b': 'foo'}, {a: [7, {b: 9}, {1: {b: 'foo'}}]}); - match({'a.1.b': null}, {a: [7, {b: 9}, {1: {b: 'foo'}}]}); - match({'a.1.b': 2}, {a: [1, [{b: 2}], 3]}); - nomatch({'a.1.b': null}, {a: [1, [{b: 2}], 3]}); - // this is new behavior in mongo 2.5 - nomatch({'a.0.b': null}, {a: [5]}); - match({'a.1': 4}, {a: [{1: 4}, 5]}); - match({'a.1': 5}, {a: [{1: 4}, 5]}); - nomatch({'a.1': null}, {a: [{1: 4}, 5]}); - match({'a.1.foo': 4}, {a: [{1: {foo: 4}}, {foo: 5}]}); - match({'a.1.foo': 5}, {a: [{1: {foo: 4}}, {foo: 5}]}); - match({'a.1.foo': null}, {a: [{1: {foo: 4}}, {foo: 5}]}); - - // trying to access a dotted field that is undefined at some point - // down the chain - nomatch({'a.b': 1}, {x: 2}); - nomatch({'a.b.c': 1}, {a: {x: 2}}); - nomatch({'a.b.c': 1}, {a: {b: {x: 2}}}); - nomatch({'a.b.c': 1}, {a: {b: 1}}); - nomatch({'a.b.c': 1}, {a: {b: 0}}); - - // dotted keypaths: literal objects - match({'a.b': {c: 1}}, {a: {b: {c: 1}}}); - nomatch({'a.b': {c: 1}}, {a: {b: {c: 2}}}); - nomatch({'a.b': {c: 1}}, {a: {b: 2}}); - match({'a.b': {c: 1, d: 2}}, {a: {b: {c: 1, d: 2}}}); - nomatch({'a.b': {c: 1, d: 2}}, {a: {b: {c: 1, d: 1}}}); - nomatch({'a.b': {c: 1, d: 2}}, {a: {b: {d: 2}}}); - - // dotted keypaths: $ operators - match({'a.b': {$in: [1, 2, 3]}}, {a: {b: [2]}}); // tested against mongodb - match({'a.b': {$in: [{x: 1}, {x: 2}, {x: 3}]}}, {a: {b: [{x: 2}]}}); - match({'a.b': {$in: [1, 2, 3]}}, {a: {b: [4, 2]}}); - nomatch({'a.b': {$in: [1, 2, 3]}}, {a: {b: [4]}}); - - // $or - await test.throwsAsync(() => { - match({$or: []}, {}); - }); - await test.throwsAsync(() => { - match({$or: [5]}, {}); - }); - await test.throwsAsync(() => { - match({$or: []}, {a: 1}); - }); - match({$or: [{a: 1}]}, {a: 1}); - nomatch({$or: [{b: 2}]}, {a: 1}); - match({$or: [{a: 1}, {b: 2}]}, {a: 1}); - nomatch({$or: [{c: 3}, {d: 4}]}, {a: 1}); - match({$or: [{a: 1}, {b: 2}]}, {a: [1, 2, 3]}); - nomatch({$or: [{a: 1}, {b: 2}]}, {c: [1, 2, 3]}); - nomatch({$or: [{a: 1}, {b: 2}]}, {a: [2, 3, 4]}); - match({$or: [{a: 1}, {a: 2}]}, {a: 1}); - match({$or: [{a: 1}, {a: 2}], b: 2}, {a: 1, b: 2}); - nomatch({$or: [{a: 2}, {a: 3}], b: 2}, {a: 1, b: 2}); - nomatch({$or: [{a: 1}, {a: 2}], b: 3}, {a: 1, b: 2}); - - // Combining $or with equality - match({x: 1, $or: [{a: 1}, {b: 1}]}, {x: 1, b: 1}); - match({$or: [{a: 1}, {b: 1}], x: 1}, {x: 1, b: 1}); - nomatch({x: 1, $or: [{a: 1}, {b: 1}]}, {b: 1}); - nomatch({x: 1, $or: [{a: 1}, {b: 1}]}, {x: 1}); - - // $or and $lt, $lte, $gt, $gte - match({$or: [{a: {$lte: 1}}, {a: 2}]}, {a: 1}); - nomatch({$or: [{a: {$lt: 1}}, {a: 2}]}, {a: 1}); - match({$or: [{a: {$gte: 1}}, {a: 2}]}, {a: 1}); - nomatch({$or: [{a: {$gt: 1}}, {a: 2}]}, {a: 1}); - match({$or: [{b: {$gt: 1}}, {b: {$lt: 3}}]}, {b: 2}); - nomatch({$or: [{b: {$lt: 1}}, {b: {$gt: 3}}]}, {b: 2}); - - // $or and $in - match({$or: [{a: {$in: [1, 2, 3]}}]}, {a: 1}); - nomatch({$or: [{a: {$in: [4, 5, 6]}}]}, {a: 1}); - match({$or: [{a: {$in: [1, 2, 3]}}, {b: 2}]}, {a: 1}); - match({$or: [{a: {$in: [1, 2, 3]}}, {b: 2}]}, {b: 2}); - nomatch({$or: [{a: {$in: [1, 2, 3]}}, {b: 2}]}, {c: 3}); - match({$or: [{a: {$in: [1, 2, 3]}}, {b: {$in: [1, 2, 3]}}]}, {b: 2}); - nomatch({$or: [{a: {$in: [1, 2, 3]}}, {b: {$in: [4, 5, 6]}}]}, {b: 2}); - - // $or and $nin - nomatch({$or: [{a: {$nin: [1, 2, 3]}}]}, {a: 1}); - match({$or: [{a: {$nin: [4, 5, 6]}}]}, {a: 1}); - nomatch({$or: [{a: {$nin: [1, 2, 3]}}, {b: 2}]}, {a: 1}); - match({$or: [{a: {$nin: [1, 2, 3]}}, {b: 2}]}, {b: 2}); - match({$or: [{a: {$nin: [1, 2, 3]}}, {b: 2}]}, {c: 3}); - match({$or: [{a: {$nin: [1, 2, 3]}}, {b: {$nin: [1, 2, 3]}}]}, {b: 2}); - nomatch({$or: [{a: {$nin: [1, 2, 3]}}, {b: {$nin: [1, 2, 3]}}]}, {a: 1, b: 2}); - match({$or: [{a: {$nin: [1, 2, 3]}}, {b: {$nin: [4, 5, 6]}}]}, {b: 2}); - - // $or and dot-notation - match({$or: [{'a.b': 1}, {'a.b': 2}]}, {a: {b: 1}}); - match({$or: [{'a.b': 1}, {'a.c': 1}]}, {a: {b: 1}}); - nomatch({$or: [{'a.b': 2}, {'a.c': 1}]}, {a: {b: 1}}); - - // $or and nested objects - match({$or: [{a: {b: 1, c: 2}}, {a: {b: 2, c: 1}}]}, {a: {b: 1, c: 2}}); - nomatch({$or: [{a: {b: 1, c: 3}}, {a: {b: 2, c: 1}}]}, {a: {b: 1, c: 2}}); - - // $or and regexes - match({$or: [{a: /a/}]}, {a: 'cat'}); - nomatch({$or: [{a: /o/}]}, {a: 'cat'}); - match({$or: [{a: /a/}, {a: /o/}]}, {a: 'cat'}); - nomatch({$or: [{a: /i/}, {a: /o/}]}, {a: 'cat'}); - match({$or: [{a: /i/}, {b: /o/}]}, {a: 'cat', b: 'dog'}); - - // $or and $ne - match({$or: [{a: {$ne: 1}}]}, {}); - nomatch({$or: [{a: {$ne: 1}}]}, {a: 1}); - match({$or: [{a: {$ne: 1}}]}, {a: 2}); - match({$or: [{a: {$ne: 1}}]}, {b: 1}); - match({$or: [{a: {$ne: 1}}, {a: {$ne: 2}}]}, {a: 1}); - match({$or: [{a: {$ne: 1}}, {b: {$ne: 1}}]}, {a: 1}); - nomatch({$or: [{a: {$ne: 1}}, {b: {$ne: 2}}]}, {a: 1, b: 2}); - - // $or and $not - match({$or: [{a: {$not: {$mod: [10, 1]}}}]}, {}); - nomatch({$or: [{a: {$not: {$mod: [10, 1]}}}]}, {a: 1}); - match({$or: [{a: {$not: {$mod: [10, 1]}}}]}, {a: 2}); - match({$or: [{a: {$not: {$mod: [10, 1]}}}, {a: {$not: {$mod: [10, 2]}}}]}, {a: 1}); - nomatch({$or: [{a: {$not: {$mod: [10, 1]}}}, {a: {$mod: [10, 2]}}]}, {a: 1}); - match({$or: [{a: {$not: {$mod: [10, 1]}}}, {a: {$mod: [10, 2]}}]}, {a: 2}); - match({$or: [{a: {$not: {$mod: [10, 1]}}}, {a: {$mod: [10, 2]}}]}, {a: 3}); - // this is possibly an open-ended task, so we stop here ... - - // $nor - await test.throwsAsync(() => { - match({$nor: []}, {}); - }); - await test.throwsAsync(() => { - match({$nor: [5]}, {}); - }); - await test.throwsAsync(() => { - match({$nor: []}, {a: 1}); - }); - nomatch({$nor: [{a: 1}]}, {a: 1}); - match({$nor: [{b: 2}]}, {a: 1}); - nomatch({$nor: [{a: 1}, {b: 2}]}, {a: 1}); - match({$nor: [{c: 3}, {d: 4}]}, {a: 1}); - nomatch({$nor: [{a: 1}, {b: 2}]}, {a: [1, 2, 3]}); - match({$nor: [{a: 1}, {b: 2}]}, {c: [1, 2, 3]}); - match({$nor: [{a: 1}, {b: 2}]}, {a: [2, 3, 4]}); - nomatch({$nor: [{a: 1}, {a: 2}]}, {a: 1}); - - // $nor and $lt, $lte, $gt, $gte - nomatch({$nor: [{a: {$lte: 1}}, {a: 2}]}, {a: 1}); - match({$nor: [{a: {$lt: 1}}, {a: 2}]}, {a: 1}); - nomatch({$nor: [{a: {$gte: 1}}, {a: 2}]}, {a: 1}); - match({$nor: [{a: {$gt: 1}}, {a: 2}]}, {a: 1}); - nomatch({$nor: [{b: {$gt: 1}}, {b: {$lt: 3}}]}, {b: 2}); - match({$nor: [{b: {$lt: 1}}, {b: {$gt: 3}}]}, {b: 2}); - - // $nor and $in - nomatch({$nor: [{a: {$in: [1, 2, 3]}}]}, {a: 1}); - match({$nor: [{a: {$in: [4, 5, 6]}}]}, {a: 1}); - nomatch({$nor: [{a: {$in: [1, 2, 3]}}, {b: 2}]}, {a: 1}); - nomatch({$nor: [{a: {$in: [1, 2, 3]}}, {b: 2}]}, {b: 2}); - match({$nor: [{a: {$in: [1, 2, 3]}}, {b: 2}]}, {c: 3}); - nomatch({$nor: [{a: {$in: [1, 2, 3]}}, {b: {$in: [1, 2, 3]}}]}, {b: 2}); - match({$nor: [{a: {$in: [1, 2, 3]}}, {b: {$in: [4, 5, 6]}}]}, {b: 2}); - - // $nor and $nin - match({$nor: [{a: {$nin: [1, 2, 3]}}]}, {a: 1}); - nomatch({$nor: [{a: {$nin: [4, 5, 6]}}]}, {a: 1}); - match({$nor: [{a: {$nin: [1, 2, 3]}}, {b: 2}]}, {a: 1}); - nomatch({$nor: [{a: {$nin: [1, 2, 3]}}, {b: 2}]}, {b: 2}); - nomatch({$nor: [{a: {$nin: [1, 2, 3]}}, {b: 2}]}, {c: 3}); - nomatch({$nor: [{a: {$nin: [1, 2, 3]}}, {b: {$nin: [1, 2, 3]}}]}, {b: 2}); - match({$nor: [{a: {$nin: [1, 2, 3]}}, {b: {$nin: [1, 2, 3]}}]}, {a: 1, b: 2}); - nomatch({$nor: [{a: {$nin: [1, 2, 3]}}, {b: {$nin: [4, 5, 6]}}]}, {b: 2}); - - // $nor and dot-notation - nomatch({$nor: [{'a.b': 1}, {'a.b': 2}]}, {a: {b: 1}}); - nomatch({$nor: [{'a.b': 1}, {'a.c': 1}]}, {a: {b: 1}}); - match({$nor: [{'a.b': 2}, {'a.c': 1}]}, {a: {b: 1}}); - - // $nor and nested objects - nomatch({$nor: [{a: {b: 1, c: 2}}, {a: {b: 2, c: 1}}]}, {a: {b: 1, c: 2}}); - match({$nor: [{a: {b: 1, c: 3}}, {a: {b: 2, c: 1}}]}, {a: {b: 1, c: 2}}); - - // $nor and regexes - nomatch({$nor: [{a: /a/}]}, {a: 'cat'}); - match({$nor: [{a: /o/}]}, {a: 'cat'}); - nomatch({$nor: [{a: /a/}, {a: /o/}]}, {a: 'cat'}); - match({$nor: [{a: /i/}, {a: /o/}]}, {a: 'cat'}); - nomatch({$nor: [{a: /i/}, {b: /o/}]}, {a: 'cat', b: 'dog'}); - - // $nor and $ne - nomatch({$nor: [{a: {$ne: 1}}]}, {}); - match({$nor: [{a: {$ne: 1}}]}, {a: 1}); - nomatch({$nor: [{a: {$ne: 1}}]}, {a: 2}); - nomatch({$nor: [{a: {$ne: 1}}]}, {b: 1}); - nomatch({$nor: [{a: {$ne: 1}}, {a: {$ne: 2}}]}, {a: 1}); - nomatch({$nor: [{a: {$ne: 1}}, {b: {$ne: 1}}]}, {a: 1}); - match({$nor: [{a: {$ne: 1}}, {b: {$ne: 2}}]}, {a: 1, b: 2}); - - // $nor and $not - nomatch({$nor: [{a: {$not: {$mod: [10, 1]}}}]}, {}); - match({$nor: [{a: {$not: {$mod: [10, 1]}}}]}, {a: 1}); - nomatch({$nor: [{a: {$not: {$mod: [10, 1]}}}]}, {a: 2}); - nomatch({$nor: [{a: {$not: {$mod: [10, 1]}}}, {a: {$not: {$mod: [10, 2]}}}]}, {a: 1}); - match({$nor: [{a: {$not: {$mod: [10, 1]}}}, {a: {$mod: [10, 2]}}]}, {a: 1}); - nomatch({$nor: [{a: {$not: {$mod: [10, 1]}}}, {a: {$mod: [10, 2]}}]}, {a: 2}); - nomatch({$nor: [{a: {$not: {$mod: [10, 1]}}}, {a: {$mod: [10, 2]}}]}, {a: 3}); - - // $and - - await test.throwsAsync(() => { - match({$and: []}, {}); - }); - await test.throwsAsync(() => { - match({$and: [5]}, {}); - }); - await test.throwsAsync(() => { - match({$and: []}, {a: 1}); - }); - match({$and: [{a: 1}]}, {a: 1}); - nomatch({$and: [{a: 1}, {a: 2}]}, {a: 1}); - nomatch({$and: [{a: 1}, {b: 1}]}, {a: 1}); - match({$and: [{a: 1}, {b: 2}]}, {a: 1, b: 2}); - nomatch({$and: [{a: 1}, {b: 1}]}, {a: 1, b: 2}); - match({$and: [{a: 1}, {b: 2}], c: 3}, {a: 1, b: 2, c: 3}); - nomatch({$and: [{a: 1}, {b: 2}], c: 4}, {a: 1, b: 2, c: 3}); - - // $and and regexes - match({$and: [{a: /a/}]}, {a: 'cat'}); - match({$and: [{a: /a/i}]}, {a: 'CAT'}); - nomatch({$and: [{a: /o/}]}, {a: 'cat'}); - nomatch({$and: [{a: /a/}, {a: /o/}]}, {a: 'cat'}); - match({$and: [{a: /a/}, {b: /o/}]}, {a: 'cat', b: 'dog'}); - nomatch({$and: [{a: /a/}, {b: /a/}]}, {a: 'cat', b: 'dog'}); - - // $and, dot-notation, and nested objects - match({$and: [{'a.b': 1}]}, {a: {b: 1}}); - match({$and: [{a: {b: 1}}]}, {a: {b: 1}}); - nomatch({$and: [{'a.b': 2}]}, {a: {b: 1}}); - nomatch({$and: [{'a.c': 1}]}, {a: {b: 1}}); - nomatch({$and: [{'a.b': 1}, {'a.b': 2}]}, {a: {b: 1}}); - nomatch({$and: [{'a.b': 1}, {a: {b: 2}}]}, {a: {b: 1}}); - match({$and: [{'a.b': 1}, {'c.d': 2}]}, {a: {b: 1}, c: {d: 2}}); - nomatch({$and: [{'a.b': 1}, {'c.d': 1}]}, {a: {b: 1}, c: {d: 2}}); - match({$and: [{'a.b': 1}, {c: {d: 2}}]}, {a: {b: 1}, c: {d: 2}}); - nomatch({$and: [{'a.b': 1}, {c: {d: 1}}]}, {a: {b: 1}, c: {d: 2}}); - nomatch({$and: [{'a.b': 2}, {c: {d: 2}}]}, {a: {b: 1}, c: {d: 2}}); - match({$and: [{a: {b: 1}}, {c: {d: 2}}]}, {a: {b: 1}, c: {d: 2}}); - nomatch({$and: [{a: {b: 2}}, {c: {d: 2}}]}, {a: {b: 1}, c: {d: 2}}); - - // $and and $in - nomatch({$and: [{a: {$in: []}}]}, {}); - match({$and: [{a: {$in: [1, 2, 3]}}]}, {a: 1}); - nomatch({$and: [{a: {$in: [4, 5, 6]}}]}, {a: 1}); - nomatch({$and: [{a: {$in: [1, 2, 3]}}, {a: {$in: [4, 5, 6]}}]}, {a: 1}); - nomatch({$and: [{a: {$in: [1, 2, 3]}}, {b: {$in: [1, 2, 3]}}]}, {a: 1, b: 4}); - match({$and: [{a: {$in: [1, 2, 3]}}, {b: {$in: [4, 5, 6]}}]}, {a: 1, b: 4}); - - - // $and and $nin - match({$and: [{a: {$nin: []}}]}, {}); - nomatch({$and: [{a: {$nin: [1, 2, 3]}}]}, {a: 1}); - match({$and: [{a: {$nin: [4, 5, 6]}}]}, {a: 1}); - nomatch({$and: [{a: {$nin: [1, 2, 3]}}, {a: {$nin: [4, 5, 6]}}]}, {a: 1}); - nomatch({$and: [{a: {$nin: [1, 2, 3]}}, {b: {$nin: [1, 2, 3]}}]}, {a: 1, b: 4}); - nomatch({$and: [{a: {$nin: [1, 2, 3]}}, {b: {$nin: [4, 5, 6]}}]}, {a: 1, b: 4}); - - // $and and $lt, $lte, $gt, $gte - match({$and: [{a: {$lt: 2}}]}, {a: 1}); - nomatch({$and: [{a: {$lt: 1}}]}, {a: 1}); - match({$and: [{a: {$lte: 1}}]}, {a: 1}); - match({$and: [{a: {$gt: 0}}]}, {a: 1}); - nomatch({$and: [{a: {$gt: 1}}]}, {a: 1}); - match({$and: [{a: {$gte: 1}}]}, {a: 1}); - match({$and: [{a: {$gt: 0}}, {a: {$lt: 2}}]}, {a: 1}); - nomatch({$and: [{a: {$gt: 1}}, {a: {$lt: 2}}]}, {a: 1}); - nomatch({$and: [{a: {$gt: 0}}, {a: {$lt: 1}}]}, {a: 1}); - match({$and: [{a: {$gte: 1}}, {a: {$lte: 1}}]}, {a: 1}); - nomatch({$and: [{a: {$gte: 2}}, {a: {$lte: 0}}]}, {a: 1}); - - // $and and $ne - match({$and: [{a: {$ne: 1}}]}, {}); - nomatch({$and: [{a: {$ne: 1}}]}, {a: 1}); - match({$and: [{a: {$ne: 1}}]}, {a: 2}); - nomatch({$and: [{a: {$ne: 1}}, {a: {$ne: 2}}]}, {a: 2}); - match({$and: [{a: {$ne: 1}}, {a: {$ne: 3}}]}, {a: 2}); - - // $and and $not - match({$and: [{a: {$not: {$gt: 2}}}]}, {a: 1}); - nomatch({$and: [{a: {$not: {$lt: 2}}}]}, {a: 1}); - match({$and: [{a: {$not: {$lt: 0}}}, {a: {$not: {$gt: 2}}}]}, {a: 1}); - nomatch({$and: [{a: {$not: {$lt: 2}}}, {a: {$not: {$gt: 0}}}]}, {a: 1}); - - // $where - match({$where: 'this.a === 1'}, {a: 1}); - match({$where: 'obj.a === 1'}, {a: 1}); - nomatch({$where: 'this.a !== 1'}, {a: 1}); - nomatch({$where: 'obj.a !== 1'}, {a: 1}); - nomatch({$where: 'this.a === 1', a: 2}, {a: 1}); - match({$where: 'this.a === 1', b: 2}, {a: 1, b: 2}); - match({$where: 'this.a === 1 && this.b === 2'}, {a: 1, b: 2}); - match({$where: 'this.a instanceof Array'}, {a: []}); - nomatch({$where: 'this.a instanceof Array'}, {a: 1}); - - // reaching into array - match({'dogs.0.name': 'Fido'}, {dogs: [{name: 'Fido'}, {name: 'Rex'}]}); - match({'dogs.1.name': 'Rex'}, {dogs: [{name: 'Fido'}, {name: 'Rex'}]}); - nomatch({'dogs.1.name': 'Fido'}, {dogs: [{name: 'Fido'}, {name: 'Rex'}]}); - match({'room.1b': 'bla'}, {room: {'1b': 'bla'}}); - - match({'dogs.name': 'Fido'}, {dogs: [{name: 'Fido'}, {name: 'Rex'}]}); - match({'dogs.name': 'Rex'}, {dogs: [{name: 'Fido'}, {name: 'Rex'}]}); - match({'animals.dogs.name': 'Fido'}, - {animals: [{dogs: [{name: 'Rover'}]}, - {}, - {dogs: [{name: 'Fido'}, {name: 'Rex'}]}]}); - match({'animals.dogs.name': 'Fido'}, - {animals: [{dogs: {name: 'Rex'}}, - {dogs: {name: 'Fido'}}]}); - match({'animals.dogs.name': 'Fido'}, - {animals: [{dogs: [{name: 'Rover'}]}, - {}, - {dogs: [{name: ['Fido']}, {name: 'Rex'}]}]}); - nomatch({'dogs.name': 'Fido'}, {dogs: []}); - - // $elemMatch - match({dogs: {$elemMatch: {name: /e/}}}, - {dogs: [{name: 'Fido'}, {name: 'Rex'}]}); - nomatch({dogs: {$elemMatch: {name: /a/}}}, - {dogs: [{name: 'Fido'}, {name: 'Rex'}]}); - match({dogs: {$elemMatch: {age: {$gt: 4}}}}, - {dogs: [{name: 'Fido', age: 5}, {name: 'Rex', age: 3}]}); - match({dogs: {$elemMatch: {name: 'Fido', age: {$gt: 4}}}}, - {dogs: [{name: 'Fido', age: 5}, {name: 'Rex', age: 3}]}); - nomatch({dogs: {$elemMatch: {name: 'Fido', age: {$gt: 5}}}}, - {dogs: [{name: 'Fido', age: 5}, {name: 'Rex', age: 3}]}); - match({dogs: {$elemMatch: {name: /i/, age: {$gt: 4}}}}, - {dogs: [{name: 'Fido', age: 5}, {name: 'Rex', age: 3}]}); - nomatch({dogs: {$elemMatch: {name: /e/, age: 5}}}, - {dogs: [{name: 'Fido', age: 5}, {name: 'Rex', age: 3}]}); - - // Tests for https://github.com/meteor/meteor/issues/9111. - match( - { dogs: { $elemMatch: { name: 'Rex' } } }, - { dogs: [{ name: 'Rex', age: 3 }] }); - nomatch( - { dogs: { $not: { $elemMatch: { name: 'Rex' } } } }, - { dogs: [{ name: 'Rex', age: 3 }] }); - match({ - $or: [ - { dogs: { $elemMatch: { name: 'Rex' } } }, - { dogs: { $elemMatch: { name: 'Rex', age: 5 } } } - ] - }, { - dogs: [{ name: 'Rex', age: 3 }] - }); - nomatch({ - $or: [ - { dogs: { $not: { $elemMatch: { name: 'Rex' } } } }, - { dogs: { $elemMatch: { name: 'Rex', age: 5 } } } - ] - }, { - dogs: [{ name: 'Rex', age: 3 }] - }); - - match({x: {$elemMatch: {y: 9}}}, {x: [{y: 9}]}); - nomatch({x: {$elemMatch: {y: 9}}}, {x: [[{y: 9}]]}); - match({x: {$elemMatch: {$gt: 5, $lt: 9}}}, {x: [8]}); - nomatch({x: {$elemMatch: {$gt: 5, $lt: 9}}}, {x: [[8]]}); - match({'a.x': {$elemMatch: {y: 9}}}, - {a: [{x: []}, {x: [{y: 9}]}]}); - nomatch({a: {$elemMatch: {x: 5}}}, {a: {x: 5}}); - match({a: {$elemMatch: {0: {$gt: 5, $lt: 9}}}}, {a: [[6]]}); - match({a: {$elemMatch: {'0.b': {$gt: 5, $lt: 9}}}}, {a: [[{b: 6}]]}); - match({a: {$elemMatch: {x: 1, $or: [{a: 1}, {b: 1}]}}}, - {a: [{x: 1, b: 1}]}); - match({a: {$elemMatch: {$or: [{a: 1}, {b: 1}], x: 1}}}, - {a: [{x: 1, b: 1}]}); - match({a: {$elemMatch: {$or: [{a: 1}, {b: 1}]}}}, - {a: [{x: 1, b: 1}]}); - match({a: {$elemMatch: {$or: [{a: 1}, {b: 1}]}}}, - {a: [{x: 1, b: 1}]}); - match({a: {$elemMatch: {$and: [{b: 1}, {x: 1}]}}}, - {a: [{x: 1, b: 1}]}); - nomatch({a: {$elemMatch: {x: 1, $or: [{a: 1}, {b: 1}]}}}, - {a: [{b: 1}]}); - nomatch({a: {$elemMatch: {x: 1, $or: [{a: 1}, {b: 1}]}}}, - {a: [{x: 1}]}); - nomatch({a: {$elemMatch: {x: 1, $or: [{a: 1}, {b: 1}]}}}, - {a: [{x: 1}, {b: 1}]}); - - await test.throwsAsync(() => { - match({a: {$elemMatch: {$gte: 1, $or: [{a: 1}, {b: 1}]}}}, - {a: [{x: 1, b: 1}]}); - }); - - await test.throwsAsync(() => { - match({x: {$elemMatch: {$and: [{$gt: 5, $lt: 9}]}}}, {x: [8]}); - }); - - // $comment - match({a: 5, $comment: 'asdf'}, {a: 5}); - nomatch({a: 6, $comment: 'asdf'}, {a: 5}); - - // XXX still needs tests: - // - non-scalar arguments to $gt, $lt, etc -}); - -Tinytest.addAsync('async - minimongo - projection_compiler', async test => { - const testProjection = (projection, tests) => { - const projection_f = LocalCollection._compileProjection(projection); - const equalNonStrict = (a, b, desc) => { - test.isTrue(EJSON.equals(a, b), desc); - }; - - tests.forEach(testCase => { - equalNonStrict(projection_f(testCase[0]), testCase[1], testCase[2]); - }); - }; - - const testCompileProjectionThrows = (projection, expectedError) => { - test.throws(() => { - LocalCollection._compileProjection(projection); - }, expectedError); - }; - - testProjection({ foo: 1, bar: 1 }, [ - [{ foo: 42, bar: 'something', baz: 'else' }, - { foo: 42, bar: 'something' }, - 'simplest - whitelist'], - - [{ foo: { nested: 17 }, baz: {} }, - { foo: { nested: 17 } }, - 'nested whitelisted field'], - - [{ _id: 'uid', bazbaz: 42 }, - { _id: 'uid' }, - 'simplest whitelist - preserve _id'], - ]); - - testProjection({ foo: 0, bar: 0 }, [ - [{ foo: 42, bar: 'something', baz: 'else' }, - { baz: 'else' }, - 'simplest - blacklist'], - - [{ foo: { nested: 17 }, baz: { foo: 'something' } }, - { baz: { foo: 'something' } }, - 'nested blacklisted field'], - - [{ _id: 'uid', bazbaz: 42 }, - { _id: 'uid', bazbaz: 42 }, - 'simplest blacklist - preserve _id'], - ]); - - testProjection({ _id: 0, foo: 1 }, [ - [{ foo: 42, bar: 33, _id: 'uid' }, - { foo: 42 }, - 'whitelist - _id blacklisted'], - ]); - - testProjection({ _id: 0, foo: 0 }, [ - [{ foo: 42, bar: 33, _id: 'uid' }, - { bar: 33 }, - 'blacklist - _id blacklisted'], - ]); - - testProjection({ 'foo.bar.baz': 1 }, [ - [{ foo: { meh: 'fur', bar: { baz: 42 }, tr: 1 }, bar: 33, baz: 'trolololo' }, - { foo: { bar: { baz: 42 } } }, - 'whitelist nested'], - - // Behavior of this test is looked up in actual mongo - [{ foo: { meh: 'fur', bar: 'nope', tr: 1 }, bar: 33, baz: 'trolololo' }, - { foo: {} }, - 'whitelist nested - path not found in doc, different type'], - - // Behavior of this test is looked up in actual mongo - [{ foo: { meh: 'fur', bar: [], tr: 1 }, bar: 33, baz: 'trolololo' }, - { foo: { bar: [] } }, - 'whitelist nested - path not found in doc'], - ]); - - testProjection({ 'hope.humanity': 0, 'hope.people': 0 }, [ - [{ hope: { humanity: 'lost', people: 'broken', candies: 'long live!' } }, - { hope: { candies: 'long live!' } }, - 'blacklist nested'], - - [{ hope: 'new' }, - { hope: 'new' }, - 'blacklist nested - path not found in doc'], - ]); - - testProjection({ _id: 1 }, [ - [{ _id: 42, x: 1, y: { z: '2' } }, - { _id: 42 }, - '_id whitelisted'], - [{ _id: 33 }, - { _id: 33 }, - '_id whitelisted, _id only'], - [{ x: 1 }, - {}, - '_id whitelisted, no _id'], - ]); - - testProjection({ _id: 0 }, [ - [{ _id: 42, x: 1, y: { z: '2' } }, - { x: 1, y: { z: '2' } }, - '_id blacklisted'], - [{ _id: 33 }, - {}, - '_id blacklisted, _id only'], - [{ x: 1 }, - { x: 1 }, - '_id blacklisted, no _id'], - ]); - - testProjection({}, [ - [{ a: 1, b: 2, c: '3' }, - { a: 1, b: 2, c: '3' }, - 'empty projection'], - ]); - - testCompileProjectionThrows( - { inc: 1, excl: 0 }, - 'You cannot currently mix including and excluding fields'); - testCompileProjectionThrows( - { _id: 1, a: 0 }, - 'You cannot currently mix including and excluding fields'); - - testCompileProjectionThrows( - { a: 1, 'a.b': 1 }, - 'using both of them may trigger unexpected behavior'); - testCompileProjectionThrows( - { 'a.b.c': 1, 'a.b': 1, a: 1 }, - 'using both of them may trigger unexpected behavior'); - - testCompileProjectionThrows('some string', 'fields option must be an object'); -}); - -Tinytest.addAsync('async - minimongo - fetch with fields', async test => { - const c = new LocalCollection(); - await Promise.all(Array.from({length: 30}, (x, i) => { - return c.insertAsync({ - something: Random.id(), - anything: { - foo: 'bar', - cool: 'hot', - }, - nothing: i, - i, - }); - })); - - // Test just a regular fetch with some projection - let fetchResults = c.find({}, { fields: { - something: 1, - 'anything.foo': 1, - } }).fetch(); - - test.isTrue(fetchResults.every(x => x && - x.something && - x.anything && - x.anything.foo && - x.anything.foo === 'bar' && - !hasOwn.call(x, 'nothing') && - !hasOwn.call(x.anything, 'cool'))); - - // Test with a selector, even field used in the selector is excluded in the - // projection - fetchResults = c.find({ - nothing: { $gte: 5 }, - }, { - fields: { nothing: 0 }, - }).fetch(); - - test.isTrue(fetchResults.every(x => x && - x.something && - x.anything && - x.anything.foo === 'bar' && - x.anything.cool === 'hot' && - !hasOwn.call(x, 'nothing') && - x.i && - x.i >= 5)); - - test.isTrue(fetchResults.length === 25); - - // Test that we can sort, based on field excluded from the projection, use - // skip and limit as well! - // following find will get indexes [10..20) sorted by nothing - fetchResults = c.find({}, { - sort: { - nothing: 1, - }, - limit: 10, - skip: 10, - fields: { - i: 1, - something: 1, - }, - }).fetch(); - - test.isTrue(fetchResults.every(x => x && - x.something && - x.i >= 10 && x.i < 20)); - - fetchResults.forEach((x, i, arr) => { - if (!i) return; - test.isTrue(x.i === arr[i - 1].i + 1); - }); - - // Temporary unsupported operators - // queries are taken from MongoDB docs examples - await test.throwsAsync(() => { - c.find({}, { fields: { 'grades.$': 1 } }); - }); - await test.throwsAsync(() => { - c.find({}, { fields: { grades: { $elemMatch: { mean: 70 } } } }); - }); - await test.throwsAsync(() => { - c.find({}, { fields: { grades: { $slice: [20, 10] } } }); - }); -}); - -Tinytest.addAsync('async - minimongo - fetch with projection, subarrays', async test => { - // Apparently projection of type 'foo.bar.x' for - // { foo: [ { bar: { x: 42 } }, { bar: { x: 3 } } ] } - // should return exactly this object. More precisely, arrays are considered as - // sets and are queried separately and then merged back to result set - const c = new LocalCollection(); - - // Insert a test object with two set fields - await c.insertAsync({ - setA: [{ - fieldA: 42, - fieldB: 33, - }, { - fieldA: 'the good', - fieldB: 'the bad', - fieldC: 'the ugly', - }], - setB: [null, { - anotherA: { }, - anotherB: 'meh', - }, null, { - anotherA: 1234, - anotherB: 431, - }, null], - }); - - const equalNonStrict = (a, b, desc) => { - test.isTrue(EJSON.equals(a, b), desc); - }; - - const testForProjection = (projection, expected) => { - const fetched = c.find({}, { fields: projection }).fetch()[0]; - equalNonStrict(fetched, expected, `failed sub-set projection: ${JSON.stringify(projection)}`); - }; - - testForProjection({ 'setA.fieldA': 1, 'setB.anotherB': 1, _id: 0 }, - { - setA: [{ fieldA: 42 }, { fieldA: 'the good' }], - setB: [null, { anotherB: 'meh' }, null, { anotherB: 431 }, null], - }); - - testForProjection({ 'setA.fieldA': 0, 'setB.anotherA': 0, _id: 0 }, - { - setA: [{fieldB: 33}, {fieldB: 'the bad', fieldC: 'the ugly'}], - setB: [null, { anotherB: 'meh' }, null, { anotherB: 431 }, null], - }); - - await c.removeAsync({}); - await c.insertAsync({a: [[{b: 1, c: 2}, {b: 2, c: 4}], {b: 3, c: 5}, [{b: 4, c: 9}]]}); - - testForProjection({ 'a.b': 1, _id: 0 }, - {a: [ [ { b: 1 }, { b: 2 } ], { b: 3 }, [ { b: 4 } ] ] }); - testForProjection({ 'a.b': 0, _id: 0 }, - {a: [ [ { c: 2 }, { c: 4 } ], { c: 5 }, [ { c: 9 } ] ] }); -}); - -Tinytest.addAsync('async - minimongo - fetch with projection, deep copy', async test => { - // Compiled fields projection defines the contract: returned document doesn't - // retain anything from the passed argument. - const doc = { - a: { x: 42 }, - b: { - y: { z: 33 }, - }, - c: 'asdf', - }; - - let fields = { - a: 1, - 'b.y': 1, - }; - - let projectionFn = LocalCollection._compileProjection(fields); - let filteredDoc = projectionFn(doc); - doc.a.x++; - doc.b.y.z--; - test.equal(filteredDoc.a.x, 42, 'projection returning deep copy - including'); - test.equal(filteredDoc.b.y.z, 33, 'projection returning deep copy - including'); - - fields = { c: 0 }; - projectionFn = LocalCollection._compileProjection(fields); - filteredDoc = projectionFn(doc); - - doc.a.x = 5; - test.equal(filteredDoc.a.x, 43, 'projection returning deep copy - excluding'); -}); - -Tinytest.addAsync('async - minimongo - observe ordered with projection', async test => { - // These tests are copy-paste from "minimongo -observe ordered", - // slightly modified to test projection - const operations = []; - const cbs = log_callbacks(operations); - let handle; - - const c = new LocalCollection(); - handle = c.find({}, {sort: {a: 1}, fields: { a: 1 }}).observe(cbs); - test.isTrue(handle.collection === c); - - await c.insertAsync({_id: 'foo', a: 1, b: 2}); - test.equal(operations.shift(), ['added', {a: 1}, 0, null]); - await c.updateAsync({a: 1}, {$set: {a: 2, b: 1}}); - test.equal(operations.shift(), ['changed', {a: 2}, 0, {a: 1}]); - await c.insertAsync({_id: 'bar', a: 10, c: 33}); - test.equal(operations.shift(), ['added', {a: 10}, 1, null]); - await c.updateAsync({}, {$inc: {a: 1}}, {multi: true}); - await c.updateAsync({}, {$inc: {c: 1}}, {multi: true}); - test.equal(operations.shift(), ['changed', {a: 3}, 0, {a: 2}]); - test.equal(operations.shift(), ['changed', {a: 11}, 1, {a: 10}]); - await c.updateAsync({a: 11}, {a: 1, b: 44}); - test.equal(operations.shift(), ['changed', {a: 1}, 1, {a: 11}]); - test.equal(operations.shift(), ['moved', {a: 1}, 1, 0, 'foo']); - await c.removeAsync({a: 2}); - test.equal(operations.shift(), undefined); - await c.removeAsync({a: 3}); - test.equal(operations.shift(), ['removed', 'foo', 1, {a: 3}]); - - // test stop - handle.stop(); - const idA2 = Random.id(); - await c.insertAsync({_id: idA2, a: 2}); - test.equal(operations.shift(), undefined); - - const cursor = c.find({}, {fields: {a: 1, _id: 0}}); - await test.throwsAsync(() => { - cursor.observeChanges({added() {}}); - }); - await test.throwsAsync(() => { - cursor.observe({added() {}}); - }); - - // test initial inserts (and backwards sort) - handle = c.find({}, {sort: {a: -1}, fields: { a: 1 } }).observe(cbs); - test.equal(operations.shift(), ['added', {a: 2}, 0, null]); - test.equal(operations.shift(), ['added', {a: 1}, 1, null]); - handle.stop(); - - // test _suppress_initial - handle = c.find({}, {sort: {a: -1}, fields: { a: 1 }}).observe(Object.assign(cbs, {_suppress_initial: true})); - test.equal(operations.shift(), undefined); - await c.insertAsync({a: 100, b: { foo: 'bar' }}); - test.equal(operations.shift(), ['added', {a: 100}, 0, idA2]); - handle.stop(); - - // test skip and limit. - await c.removeAsync({}); - handle = c.find({}, {sort: {a: 1}, skip: 1, limit: 2, fields: { blacklisted: 0 }}).observe(cbs); - test.equal(operations.shift(), undefined); - await c.insertAsync({a: 1, blacklisted: 1324}); - test.equal(operations.shift(), undefined); - await c.insertAsync({_id: 'foo', a: 2, blacklisted: ['something']}); - test.equal(operations.shift(), ['added', {a: 2}, 0, null]); - await c.insertAsync({a: 3, blacklisted: { 2: 3 }}); - test.equal(operations.shift(), ['added', {a: 3}, 1, null]); - await c.insertAsync({a: 4, blacklisted: 6}); - test.equal(operations.shift(), undefined); - await c.updateAsync({a: 1}, {a: 0, blacklisted: 4444}); - test.equal(operations.shift(), undefined); - await c.updateAsync({a: 0}, {a: 5, blacklisted: 11111}); - test.equal(operations.shift(), ['removed', 'foo', 0, {a: 2}]); - test.equal(operations.shift(), ['added', {a: 4}, 1, null]); - await c.updateAsync({a: 3}, {a: 3.5, blacklisted: 333.4444}); - test.equal(operations.shift(), ['changed', {a: 3.5}, 0, {a: 3}]); - handle.stop(); - - // test _no_indices - - await c.removeAsync({}); - handle = c.find({}, {sort: {a: 1}, fields: { a: 1 }}).observe(Object.assign(cbs, {_no_indices: true})); - await c.insertAsync({_id: 'foo', a: 1, zoo: 'crazy'}); - test.equal(operations.shift(), ['added', {a: 1}, -1, null]); - await c.updateAsync({a: 1}, {$set: {a: 2, foobar: 'player'}}); - test.equal(operations.shift(), ['changed', {a: 2}, -1, {a: 1}]); - await c.insertAsync({a: 10, b: 123.45}); - test.equal(operations.shift(), ['added', {a: 10}, -1, null]); - await c.updateAsync({}, {$inc: {a: 1, b: 2}}, {multi: true}); - test.equal(operations.shift(), ['changed', {a: 3}, -1, {a: 2}]); - test.equal(operations.shift(), ['changed', {a: 11}, -1, {a: 10}]); - await c.updateAsync({a: 11, b: 125.45}, {a: 1, b: 444}); - test.equal(operations.shift(), ['changed', {a: 1}, -1, {a: 11}]); - test.equal(operations.shift(), ['moved', {a: 1}, -1, -1, 'foo']); - await c.removeAsync({a: 2}); - test.equal(operations.shift(), undefined); - await c.removeAsync({a: 3}); - test.equal(operations.shift(), ['removed', 'foo', -1, {a: 3}]); - handle.stop(); -}); - - -Tinytest.addAsync('async - minimongo - ordering', async test => { - const shortBinary = EJSON.newBinary(1); - shortBinary[0] = 128; - const longBinary1 = EJSON.newBinary(2); - longBinary1[1] = 42; - const longBinary2 = EJSON.newBinary(2); - longBinary2[1] = 50; - - const date1 = new Date; - const date2 = new Date(date1.getTime() + 1000); - - // value ordering - assert_ordering(test, LocalCollection._f._cmp, [ - null, - 1, 2.2, 3, - '03', '1', '11', '2', 'a', 'aaa', - {}, {a: 2}, {a: 3}, {a: 3, b: 4}, {b: 4}, {b: 4, a: 3}, - {b: {}}, {b: [1, 2, 3]}, {b: [1, 2, 4]}, - [], [1, 2], [1, 2, 3], [1, 2, 4], [1, 2, '4'], [1, 2, [4]], - shortBinary, longBinary1, longBinary2, - new MongoID.ObjectID('1234567890abcd1234567890'), - new MongoID.ObjectID('abcd1234567890abcd123456'), - false, true, - date1, date2, - ]); - - // document ordering under a sort specification - const verify = (sorts, docs) => { - (Array.isArray(sorts) ? sorts : [sorts]).forEach(sort => { - const sorter = new Minimongo.Sorter(sort); - assert_ordering(test, sorter.getComparator(), docs); - }); - }; - - // note: [] doesn't sort with "arrays", it sorts as "undefined". the position - // of arrays in _typeorder only matters for things like $lt. (This behavior - // verified with MongoDB 2.2.1.) We don't define the relative order of {a: []} - // and {c: 1} is undefined (MongoDB does seem to care but it's not clear how - // or why). - verify([{a: 1}, ['a'], [['a', 'asc']]], - [{a: []}, {a: 1}, {a: {}}, {a: true}]); - verify([{a: 1}, ['a'], [['a', 'asc']]], - [{c: 1}, {a: 1}, {a: {}}, {a: true}]); - verify([{a: -1}, [['a', 'desc']]], - [{a: true}, {a: {}}, {a: 1}, {c: 1}]); - verify([{a: -1}, [['a', 'desc']]], - [{a: true}, {a: {}}, {a: 1}, {a: []}]); - - verify([{a: 1, b: -1}, ['a', ['b', 'desc']], - [['a', 'asc'], ['b', 'desc']]], - [{c: 1}, {a: 1, b: 3}, {a: 1, b: 2}, {a: 2, b: 0}]); - - verify([{a: 1, b: 1}, ['a', 'b'], - [['a', 'asc'], ['b', 'asc']]], - [{c: 1}, {a: 1, b: 2}, {a: 1, b: 3}, {a: 2, b: 0}]); - - await test.throwsAsync(() => { - new Minimongo.Sorter('a'); - }); - - await test.throwsAsync(() => { - new Minimongo.Sorter(123); - }); - - // We don't support $natural:1 (since we don't actually have Mongo's on-disk - // ordering available!) - await test.throwsAsync(() => { - new Minimongo.Sorter({$natural: 1}); - }); - - // No sort spec implies everything equal. - test.equal(new Minimongo.Sorter({}).getComparator()({a: 1}, {a: 2}), 0); - - // All sorts of array edge cases! - // Increasing sort sorts by the smallest element it finds; 1 < 2. - verify({a: 1}, [ - {a: [1, 10, 20]}, - {a: [5, 2, 99]}, - ]); - // Decreasing sorts by largest it finds; 99 > 20. - verify({a: -1}, [ - {a: [5, 2, 99]}, - {a: [1, 10, 20]}, - ]); - // Can also sort by specific array indices. - verify({'a.1': 1}, [ - {a: [5, 2, 99]}, - {a: [1, 10, 20]}, - ]); - // We do NOT expand sub-arrays, so the minimum in the second doc is 5, not - // -20. (Numbers always sort before arrays.) - verify({a: 1}, [ - {a: [1, [10, 15], 20]}, - {a: [5, [-5, -20], 18]}, - ]); - // The maximum in each of these is the array, since arrays are "greater" than - // numbers. And [10, 15] is greater than [-5, -20]. - verify({a: -1}, [ - {a: [1, [10, 15], 20]}, - {a: [5, [-5, -20], 18]}, - ]); - // 'a.0' here ONLY means "first element of a", not "first element of something - // found in a", so it CANNOT find the 10 or -5. - verify({'a.0': 1}, [ - {a: [1, [10, 15], 20]}, - {a: [5, [-5, -20], 18]}, - ]); - verify({'a.0': -1}, [ - {a: [5, [-5, -20], 18]}, - {a: [1, [10, 15], 20]}, - ]); - // Similarly, this is just comparing [-5,-20] to [10, 15]. - verify({'a.1': 1}, [ - {a: [5, [-5, -20], 18]}, - {a: [1, [10, 15], 20]}, - ]); - verify({'a.1': -1}, [ - {a: [1, [10, 15], 20]}, - {a: [5, [-5, -20], 18]}, - ]); - // Here we are just comparing [10,15] directly to [19,3] (and NOT also - // iterating over the numbers; this is implemented by setting dontIterate in - // makeLookupFunction). So [10,15]<[19,3] even though 3 is the smallest - // number you can find there. - verify({'a.1': 1}, [ - {a: [1, [10, 15], 20]}, - {a: [5, [19, 3], 18]}, - ]); - verify({'a.1': -1}, [ - {a: [5, [19, 3], 18]}, - {a: [1, [10, 15], 20]}, - ]); - // Minimal elements are 1 and 5. - verify({a: 1}, [ - {a: [1, [10, 15], 20]}, - {a: [5, [19, 3], 18]}, - ]); - // Maximal elements are [19,3] and [10,15] (because arrays sort higher than - // numbers), even though there's a 20 floating around. - verify({a: -1}, [ - {a: [5, [19, 3], 18]}, - {a: [1, [10, 15], 20]}, - ]); - // Maximal elements are [10,15] and [3,19]. [10,15] is bigger even though 19 - // is the biggest number in them, because array comparison is lexicographic. - verify({a: -1}, [ - {a: [1, [10, 15], 20]}, - {a: [5, [3, 19], 18]}, - ]); - - // (0,4) < (0,5), so they go in this order. It's not correct to consider - // (0,3) as a sort key for the second document because they come from - // different a-branches. - verify({'a.x': 1, 'a.y': 1}, [ - {a: [{x: 0, y: 4}]}, - {a: [{x: 0, y: 5}, {x: 1, y: 3}]}, - ]); - - verify({'a.0.s': 1}, [ - {a: [ {s: 1} ]}, - {a: [ {s: 2} ]}, - ]); -}); - -Tinytest.addAsync('async - minimongo - sort', async test => { - const c = new LocalCollection(); - for (let i = 0; i < 50; i++) { - for (let j = 0; j < 2; j++) {await c.insertAsync({a: i, b: j, _id: `${i}_${j}`});} - } - - test.equal(c.find(null, {sort: {b: -1, a: 1}, limit: 5}).fetch(), []); - test.equal(c.find(undefined, {sort: {b: -1, a: 1}, limit: 5}).fetch(), []); - test.equal(c.find(false, {sort: {b: -1, a: 1}, limit: 5}).fetch(), []); - - test.equal( - c.find({a: {$gt: 10}}, {sort: {b: -1, a: 1}, limit: 5}).fetch(), [ - {a: 11, b: 1, _id: '11_1'}, - {a: 12, b: 1, _id: '12_1'}, - {a: 13, b: 1, _id: '13_1'}, - {a: 14, b: 1, _id: '14_1'}, - {a: 15, b: 1, _id: '15_1'}]); - - test.equal( - c.find({a: {$gt: 10}}, {sort: {b: -1, a: 1}, skip: 3, limit: 5}).fetch(), [ - {a: 14, b: 1, _id: '14_1'}, - {a: 15, b: 1, _id: '15_1'}, - {a: 16, b: 1, _id: '16_1'}, - {a: 17, b: 1, _id: '17_1'}, - {a: 18, b: 1, _id: '18_1'}]); - - test.equal( - c.find({a: {$gte: 20}}, {sort: {a: 1, b: -1}, skip: 50, limit: 5}).fetch(), [ - {a: 45, b: 1, _id: '45_1'}, - {a: 45, b: 0, _id: '45_0'}, - {a: 46, b: 1, _id: '46_1'}, - {a: 46, b: 0, _id: '46_0'}, - {a: 47, b: 1, _id: '47_1'}]); -}); - -Tinytest.addAsync('async - minimongo - subkey sort', async test => { - const c = new LocalCollection(); - - // normal case - await c.insertAsync({a: {b: 2}}); - await c.insertAsync({a: {b: 1}}); - await c.insertAsync({a: {b: 3}}); - test.equal( - c.find({}, {sort: {'a.b': -1}}).fetch().map(doc => doc.a), - [{b: 3}, {b: 2}, {b: 1}]); - - // isn't an object - await c.insertAsync({a: 1}); - test.equal( - c.find({}, {sort: {'a.b': 1}}).fetch().map(doc => doc.a), - [1, {b: 1}, {b: 2}, {b: 3}]); - - // complex object - await c.insertAsync({a: {b: {c: 1}}}); - test.equal( - c.find({}, {sort: {'a.b': -1}}).fetch().map(doc => doc.a), - [{b: {c: 1}}, {b: 3}, {b: 2}, {b: 1}, 1]); - - // no such top level prop - await c.insertAsync({c: 1}); - test.equal( - c.find({}, {sort: {'a.b': -1}}).fetch().map(doc => doc.a), - [{b: {c: 1}}, {b: 3}, {b: 2}, {b: 1}, 1, undefined]); - - // no such mid level prop. just test that it doesn't throw. - test.equal(c.find({}, {sort: {'a.nope.c': -1}}).count(), 6); -}); - -Tinytest.addAsync('async - minimongo - array sort', async test => { - const c = new LocalCollection(); - - // "up" and "down" are the indices that the docs should have when sorted - // ascending and descending by "a.x" respectively. They are not reverses of - // each other: when sorting ascending, you use the minimum value you can find - // in the document, and when sorting descending, you use the maximum value you - // can find. So [1, 4] shows up in the 1 slot when sorting ascending and the 4 - // slot when sorting descending. - // - // Similarly, "selected" is the index that the doc should have in the query - // that sorts ascending on "a.x" and selects {'a.x': {$gt: 1}}. In this case, - // the 1 in [1, 4] may not be used as a sort key. - await c.insertAsync({up: 1, down: 1, selected: 0, a: {x: [1, 4]}}); - await c.insertAsync({up: 2, down: 2, selected: 1, a: [{x: [2]}, {x: 3}]}); - await c.insertAsync({up: 0, down: 4, a: {x: 0}}); - await c.insertAsync({up: 3, down: 3, selected: 2, a: {x: 2.5}}); - await c.insertAsync({up: 4, down: 0, selected: 3, a: {x: 5}}); - - // Test that the the documents in "cursor" contain values with the name - // "field" running from 0 to the max value of that name in the collection. - const testCursorMatchesField = (cursor, field) => { - const fieldValues = []; - c.find().forEach(doc => { - if (hasOwn.call(doc, field)) {fieldValues.push(doc[field]);} - }); - test.equal(cursor.fetch().map(doc => doc[field]), - Array.from({length: Math.max(...fieldValues) + 1}, (x, i) => i)); - }; - - testCursorMatchesField(c.find({}, {sort: {'a.x': 1}}), 'up'); - testCursorMatchesField(c.find({}, {sort: {'a.x': -1}}), 'down'); - testCursorMatchesField(c.find({'a.x': {$gt: 1}}, {sort: {'a.x': 1}}), - 'selected'); -}); - -Tinytest.addAsync('async - minimongo - nested array sort', async test => { - const c = new LocalCollection(); - - // the short fields represent the order it should be when sorting for those keys - // e.g. the cdx_cdy field represents the order when you sort: { 'c.d.x': 1, 'c.d.y': 1 } - await c.insertAsync({ ab0x: 0, ab0x_g: 0, g_ab0x: 0, cdx: 0, cdx_cdy: 0, cdy_cdx: 0, n: 0 }); - await c.insertAsync({ ab0x: 1, ab0x_g: 2, g_ab0x: 3, cdx: 1, cdx_cdy: 2, cdy_cdx: 4, n: 1 , g: 2, c: { d: [{ y: 2}, { y: 3}] } }); - await c.insertAsync({ ab0x: 2, ab0x_g: 1, g_ab0x: 1, cdx: 2, cdx_cdy: 3, cdy_cdx: 5, n: 2 , c: { d: [{ y: 2}] }, g: 0 }); - await c.insertAsync({ ab0x: 3, ab0x_g: 3, g_ab0x: 2, cdx: 6, cdx_cdy: 6, cdy_cdx: 8, n: 3 , a: { b: [{ x: 0 }] }, c: { d: [{ x: 1, y: 2}] }, g: 1 }); - await c.insertAsync({ ab0x: 4, ab0x_g: 4, g_ab0x: 4, cdx: 3, cdx_cdy: 1, cdy_cdx: 1, n: 4 , a: { b: [{ x: [1, 4] }] }, c: { d: [] }, g: 2 }); - await c.insertAsync({ ab0x: 5, ab0x_g: 5, g_ab0x: 5, cdx: 7, cdx_cdy: 7, cdy_cdx: 3, n: 5 , a: { b: [{ x: [2] }, { x: 3 }]}, c: { d: [{x: 2, y: 2}, {x: 3, y: 1}] }, g: 3 }); - await c.insertAsync({ ab0x: 6, ab0x_g: 6, g_ab0x: 6, cdx: 8, cdx_cdy: 8, cdy_cdx: 2, n: 6 , a: { b: [{ x: 2.5 }] }, c: { d: [{x: 2, y: 2}, {x: 3}] }, g: 4 }); - await c.insertAsync({ ab0x: 7, ab0x_g: 7, g_ab0x: 7, cdx: 4, cdx_cdy: 4, cdy_cdx: 6, n: 7 , a: { b: [{ x: 5 }] }, c: { d: [{ y: 2}, { y: 3}] }, g: 5 }); - await c.insertAsync({ ab0x: 8, ab0x_g: 8, g_ab0x: 8, cdx: 5, cdx_cdy: 5, cdy_cdx: 7, n: 8 , a: { b: [{ x: 6 }, { x: 7 }] }, c: { d: [{ y: 2}, { x: 1.5, y: 2}] }, g: 6 }); - - // Test that the the documents in "cursor" contain values with the name - // "field" running from 0 to the max value of that name in the collection. - const testCursorMatchesField = (cursor, field) => { - const fieldValues = []; - c.find().forEach(doc => { - if (hasOwn.call(doc, field)) { - fieldValues.push(doc[field]); - } - }); - test.equal(cursor.fetch().map(doc => doc[field]), - Array.from({ length: Math.max(...fieldValues) + 1 }, (x, i) => i)); - }; - - testCursorMatchesField(c.find({}, { sort: { 'a.b.0.x': 1 } }), 'ab0x'); - testCursorMatchesField(c.find({}, { sort: { 'a.b.0.x': 1, 'g': 1 } }), 'ab0x_g'); - testCursorMatchesField(c.find({}, { sort: { 'g': 1, 'a.b.0.x': 1 } }), 'g_ab0x'); - testCursorMatchesField(c.find({}, { sort: { 'c.d.x': 1 } }), 'cdx'); - testCursorMatchesField(c.find({}, { sort: { 'c.d.x': 1, 'c.d.y': 1 } }), 'cdx_cdy'); - testCursorMatchesField(c.find({}, { sort: { 'c.d.y': 1, 'c.d.x': 1 } }), 'cdy_cdx'); - -}); - -Tinytest.addAsync('async - minimongo - sort keys', async test => { - const keyListToObject = keyList => { - const obj = {}; - keyList.forEach(key => { - obj[EJSON.stringify(key)] = true; - }); - return obj; - }; - - const testKeys = (sortSpec, doc, expectedKeyList) => { - const expectedKeys = keyListToObject(expectedKeyList); - const sorter = new Minimongo.Sorter(sortSpec); - - const actualKeyList = []; - sorter._generateKeysFromDoc(doc, key => { - actualKeyList.push(key); - }); - const actualKeys = keyListToObject(actualKeyList); - test.equal(actualKeys, expectedKeys); - }; - - const testParallelError = (sortSpec, doc) => { - const sorter = new Minimongo.Sorter(sortSpec); - test.throws(() => { - sorter._generateKeysFromDoc(doc, () => {}); - }, /parallel arrays/); - }; - - // Just non-array fields. - testKeys({'a.x': 1, 'a.y': 1}, - {a: {x: 0, y: 5}}, - [[0, 5]]); - - // Ensure that we don't get [0,3] and [1,5]. - testKeys({'a.x': 1, 'a.y': 1}, - {a: [{x: 0, y: 5}, {x: 1, y: 3}]}, - [[0, 5], [1, 3]]); - - // Ensure we can combine "array fields" with "non-array fields". - testKeys({'a.x': 1, 'a.y': 1, b: -1}, - {a: [{x: 0, y: 5}, {x: 1, y: 3}], b: 42}, - [[0, 5, 42], [1, 3, 42]]); - testKeys({b: -1, 'a.x': 1, 'a.y': 1}, - {a: [{x: 0, y: 5}, {x: 1, y: 3}], b: 42}, - [[42, 0, 5], [42, 1, 3]]); - testKeys({'a.x': 1, b: -1, 'a.y': 1}, - {a: [{x: 0, y: 5}, {x: 1, y: 3}], b: 42}, - [[0, 42, 5], [1, 42, 3]]); - testKeys({a: 1, b: 1}, - {a: [1, 2, 3], b: 42}, - [[1, 42], [2, 42], [3, 42]]); - - testKeys({'a.0.x': 1}, - {a: [{x: 0}]}, - [[0]]); - - testKeys({'a.0.x': 1}, - {a: []}, - [[undefined]]); - - // Don't support multiple arrays at the same level. - testParallelError({a: 1, b: 1}, - {a: [1, 2, 3], b: [42]}); - - // We are MORE STRICT than Mongo here; Mongo supports this! - // XXX support this too #NestedArraySort - testParallelError({'a.x': 1, 'a.y': 1}, - {a: [{x: 1, y: [2, 3]}, - {x: 2, y: [4, 5]}]}); -}); - -Tinytest.addAsync('async - minimongo - sort function', async test => { - const c = new LocalCollection(); - - await c.insertAsync({a: 1}); - await c.insertAsync({a: 10}); - await c.insertAsync({a: 5}); - await c.insertAsync({a: 7}); - await c.insertAsync({a: 2}); - await c.insertAsync({a: 4}); - await c.insertAsync({a: 3}); - - const sortFunction = (doc1, doc2) => doc2.a - doc1.a; - - test.equal(c.find({}, {sort: sortFunction}).fetch(), c.find({}).fetch().sort(sortFunction)); - test.notEqual(c.find({}).fetch(), c.find({}).fetch().sort(sortFunction)); - test.equal(c.find({}, {sort: {a: -1}}).fetch(), c.find({}).fetch().sort(sortFunction)); -}); - -Tinytest.addAsync('async - minimongo - binary search', async test => { - const forwardCmp = (a, b) => a - b; - - const backwardCmp = (a, b) => -1 * forwardCmp(a, b); - - const checkSearch = (cmp, array, value, expected, message) => { - const actual = LocalCollection._binarySearch(cmp, array, value); - if (expected != actual) { - test.fail({type: 'minimongo-binary-search', - message: `${message} : Expected index ${expected} but had ${actual}`, - }); - } - }; - - const checkSearchForward = (array, value, expected, message) => { - checkSearch(forwardCmp, array, value, expected, message); - }; - const checkSearchBackward = (array, value, expected, message) => { - checkSearch(backwardCmp, array, value, expected, message); - }; - - checkSearchForward([1, 2, 5, 7], 4, 2, 'Inner insert'); - checkSearchForward([1, 2, 3, 4], 3, 3, 'Inner insert, equal value'); - checkSearchForward([1, 2, 5], 4, 2, 'Inner insert, odd length'); - checkSearchForward([1, 3, 5, 6], 9, 4, 'End insert'); - checkSearchForward([1, 3, 5, 6], 0, 0, 'Beginning insert'); - checkSearchForward([1], 0, 0, 'Single array, less than.'); - checkSearchForward([1], 1, 1, 'Single array, equal.'); - checkSearchForward([1], 2, 1, 'Single array, greater than.'); - checkSearchForward([], 1, 0, 'Empty array'); - checkSearchForward([1, 1, 1, 2, 2, 2, 2], 1, 3, 'Highly degenerate array, lower'); - checkSearchForward([1, 1, 1, 2, 2, 2, 2], 2, 7, 'Highly degenerate array, upper'); - checkSearchForward([2, 2, 2, 2, 2, 2, 2], 1, 0, 'Highly degenerate array, lower'); - checkSearchForward([2, 2, 2, 2, 2, 2, 2], 2, 7, 'Highly degenerate array, equal'); - checkSearchForward([2, 2, 2, 2, 2, 2, 2], 3, 7, 'Highly degenerate array, upper'); - - checkSearchBackward([7, 5, 2, 1], 4, 2, 'Backward: Inner insert'); - checkSearchBackward([4, 3, 2, 1], 3, 2, 'Backward: Inner insert, equal value'); - checkSearchBackward([5, 2, 1], 4, 1, 'Backward: Inner insert, odd length'); - checkSearchBackward([6, 5, 3, 1], 9, 0, 'Backward: Beginning insert'); - checkSearchBackward([6, 5, 3, 1], 0, 4, 'Backward: End insert'); - checkSearchBackward([1], 0, 1, 'Backward: Single array, less than.'); - checkSearchBackward([1], 1, 1, 'Backward: Single array, equal.'); - checkSearchBackward([1], 2, 0, 'Backward: Single array, greater than.'); - checkSearchBackward([], 1, 0, 'Backward: Empty array'); - checkSearchBackward([2, 2, 2, 2, 1, 1, 1], 1, 7, 'Backward: Degenerate array, lower'); - checkSearchBackward([2, 2, 2, 2, 1, 1, 1], 2, 4, 'Backward: Degenerate array, upper'); - checkSearchBackward([2, 2, 2, 2, 2, 2, 2], 1, 7, 'Backward: Highly degenerate array, upper'); - checkSearchBackward([2, 2, 2, 2, 2, 2, 2], 2, 7, 'Backward: Highly degenerate array, upper'); - checkSearchBackward([2, 2, 2, 2, 2, 2, 2], 3, 0, 'Backward: Highly degenerate array, upper'); -}); - -Tinytest.addAsync('async - minimongo - modify', async test => { - const modifyWithQuery = async (doc, query, mod, expected) => { - const coll = new LocalCollection; - await coll.insertAsync(doc); - // The query is relevant for 'a.$.b'. - await coll.updateAsync(query, mod); - const actual = await coll.findOne(); - - if (!expected._id) { - delete actual._id; // added by insert - } - - if (typeof expected === 'function') { - expected(actual, EJSON.stringify({input: doc, mod})); - } else { - test.equal(actual, expected, EJSON.stringify({input: doc, mod})); - } - }; - const modify = async (doc, mod, expected) => { - try { - await modifyWithQuery(doc, {}, mod, expected); - } catch (e) { - console.log({e}); - } - }; - const exceptionWithQuery = async (doc, query, mod) => { - const coll = new LocalCollection; - await coll.insertAsync(doc); - await test.throwsAsync(async () => { - await coll.updateAsync(query, mod); - }); - }; - const exception = async (doc, mod) => { - await exceptionWithQuery(doc, {}, mod); - }; - - const upsert = async (query, mod, expected) => { - const coll = new LocalCollection; - - const result = await coll.upsertAsync(query, mod); - - const actual = await coll.findOne(); - - if (expected._id) { - test.equal(result.insertedId, expected._id); - } else { - delete actual._id; - } - - test.equal(actual, expected); - }; - - const upsertUpdate = async (initialDoc, query, mod, expected) => { - const collection = new LocalCollection; - - await collection.insertAsync(initialDoc); - - const result = await collection.upsertAsync(query, mod); - const actual = await collection.findOne(); - - if (!expected._id) { - delete actual._id; - } - - test.equal(actual, expected); - }; - - const upsertException = async (query, mod) => { - const coll = new LocalCollection; - await test.throwsAsync(async () => { - await coll.upsertAsync(query, mod); - }); - }; - - // document replacement - await modify( {}, {}, {}); - await modify( {a: 12}, {}, {}); // tested against mongodb - await modify( {a: 12}, {a: 13}, {a: 13}); - await modify( {a: 12, b: 99}, {a: 13}, {a: 13}); - await exception({a: 12}, {a: 13, $set: {b: 13}}); - await exception({a: 12}, {$set: {b: 13}, a: 13}); - - await exception({a: 12}, {$a: 13}); // invalid operator - await exception({a: 12}, {b: {$a: 13}}); - await exception({a: 12}, {b: {'a.b': 13}}); - await exception({a: 12}, {b: {'\0a': 13}}); - - // keys - await modify( {}, {$set: {a: 12}}, {a: 12}); - await modify( {}, {$set: {'a.b': 12}}, {a: {b: 12}}); - await modify( {}, {$set: {'a.b.c': 12}}, {a: {b: {c: 12}}}); - await modify( {a: {d: 99}}, {$set: {'a.b.c': 12}}, {a: {d: 99, b: {c: 12}}}); - await modify( {}, {$set: {'a.b.3.c': 12}}, {a: {b: {3: {c: 12}}}}); - await modify( {a: {b: []}}, {$set: {'a.b.3.c': 12}}, { - a: {b: [null, null, null, {c: 12}]}}); - await exception({a: [null, null, null]}, {$set: {'a.1.b': 12}}); - await exception({a: [null, 1, null]}, {$set: {'a.1.b': 12}}); - await exception({a: [null, 'x', null]}, {$set: {'a.1.b': 12}}); - await exception({a: [null, [], null]}, {$set: {'a.1.b': 12}}); - await modify( {a: [null, null, null]}, {$set: {'a.3.b': 12}}, { - a: [null, null, null, {b: 12}]}); - await exception({a: []}, {$set: {'a.b': 12}}); - await exception({a: 12}, {$set: {'a.b': 99}}); // tested on mongo - await exception({a: 'x'}, {$set: {'a.b': 99}}); - await exception({a: true}, {$set: {'a.b': 99}}); - await exception({a: null}, {$set: {'a.b': 99}}); - await modify( {a: {}}, {$set: {'a.3': 12}}, {a: {3: 12}}); - await modify( {a: []}, {$set: {'a.3': 12}}, {a: [null, null, null, 12]}); - await exception({}, {$set: {'': 12}}); // tested on mongo - await exception({}, {$set: {'.': 12}}); // tested on mongo - await exception({}, {$set: {'a.': 12}}); // tested on mongo - await exception({}, {$set: {'. ': 12}}); // tested on mongo - await exception({}, {$inc: {'... ': 12}}); // tested on mongo - await exception({}, {$set: {'a..b': 12}}); // tested on mongo - await modify( {a: [1, 2, 3]}, {$set: {'a.01': 99}}, {a: [1, 99, 3]}); - await modify( {a: [1, {a: 98}, 3]}, {$set: {'a.01.b': 99}}, {a: [1, {a: 98, b: 99}, 3]}); - await modify( {}, {$set: {'2.a.b': 12}}, {2: {a: {b: 12}}}); // tested - await exception({x: []}, {$set: {'x.2..a': 99}}); - await modify( {x: [null, null]}, {$set: {'x.2.a': 1}}, {x: [null, null, {a: 1}]}); - await exception({x: [null, null]}, {$set: {'x.1.a': 1}}); - - // a.$.b - await modifyWithQuery( {a: [{x: 2}, {x: 4}]}, {'a.x': 4}, {$set: {'a.$.z': 9}}, - {a: [{x: 2}, {x: 4, z: 9}]}); - await exception({a: [{x: 2}, {x: 4}]}, {$set: {'a.$.z': 9}}); - await exceptionWithQuery({a: [{x: 2}, {x: 4}], b: 5}, {b: 5}, {$set: {'a.$.z': 9}}); - // can't have two $ - await exceptionWithQuery({a: [{x: [2]}]}, {'a.x': 2}, {$set: {'a.$.x.$': 9}}); - await modifyWithQuery( {a: [5, 6, 7]}, {a: 6}, {$set: {'a.$': 9}}, {a: [5, 9, 7]}); - await modifyWithQuery( {a: [{b: [{c: 9}, {c: 10}]}, {b: {c: 11}}]}, {'a.b.c': 10}, - {$unset: {'a.$.b': 1}}, {a: [{}, {b: {c: 11}}]}); - await modifyWithQuery( {a: [{b: [{c: 9}, {c: 10}]}, {b: {c: 11}}]}, {'a.b.c': 11}, - {$unset: {'a.$.b': 1}}, - {a: [{b: [{c: 9}, {c: 10}]}, {}]}); - await modifyWithQuery( {a: [1]}, {'a.0': 1}, {$set: {'a.$': 5}}, {a: [5]}); - await modifyWithQuery( {a: [9]}, {a: {$mod: [2, 1]}}, {$set: {'a.$': 5}}, {a: [5]}); - // Negatives don't set '$'. - await exceptionWithQuery({a: [1]}, {$not: {a: 2}}, {$set: {'a.$': 5}}); - await exceptionWithQuery({a: [1]}, {'a.0': {$ne: 2}}, {$set: {'a.$': 5}}); - // One $or clause works. - await modifyWithQuery( {a: [{x: 2}, {x: 4}]}, - {$or: [{'a.x': 4}]}, {$set: {'a.$.z': 9}}, - {a: [{x: 2}, {x: 4, z: 9}]}); - // More $or clauses throw. - await exceptionWithQuery({a: [{x: 2}, {x: 4}]}, - {$or: [{'a.x': 4}, {'a.x': 4}]}, - {$set: {'a.$.z': 9}}); - // $and uses the last one. - await modifyWithQuery( {a: [{x: 1}, {x: 3}]}, - {$and: [{'a.x': 1}, {'a.x': 3}]}, - {$set: {'a.$.x': 5}}, - {a: [{x: 1}, {x: 5}]}); - await modifyWithQuery( {a: [{x: 1}, {x: 3}]}, - {$and: [{'a.x': 3}, {'a.x': 1}]}, - {$set: {'a.$.x': 5}}, - {a: [{x: 5}, {x: 3}]}); - // Same goes for the implicit AND of a document selector. - await modifyWithQuery( {a: [{x: 1}, {y: 3}]}, - {'a.x': 1, 'a.y': 3}, - {$set: {'a.$.z': 5}}, - {a: [{x: 1}, {y: 3, z: 5}]}); - await modifyWithQuery( {a: [{x: 1}, {y: 1}, {x: 1, y: 1}]}, - {a: {$elemMatch: {x: 1, y: 1}}}, - {$set: {'a.$.x': 2}}, - {a: [{x: 1}, {y: 1}, {x: 2, y: 1}]}); - await modifyWithQuery( {a: [{b: [{x: 1}, {y: 1}, {x: 1, y: 1}]}]}, - {'a.b': {$elemMatch: {x: 1, y: 1}}}, - {$set: {'a.$.b': 3}}, - {a: [{b: 3}]}); - // with $near, make sure it does not find the closest one (#3599) - await modifyWithQuery( {a: []}, - {'a.b': {$near: [5, 5]}}, - {$set: {'a.$.b': 'k'}}, - {a: []}); - await modifyWithQuery( {a: [{b: [ [3, 3], [4, 4] ]}]}, - {'a.b': {$near: [5, 5]}}, - {$set: {'a.$.b': 'k'}}, - {a: [{b: 'k'}]}); - await modifyWithQuery( {a: [{b: [1, 1]}, - {b: [ [3, 3], [4, 4] ]}, - {b: [9, 9]}]}, - {'a.b': {$near: [5, 5]}}, - {$set: {'a.$.b': 'k'}}, - {a: [{b: 'k'}, {b: [[3, 3], [4, 4]]}, {b: [9, 9]}]}); - await modifyWithQuery( {a: [{b: [1, 1]}, - {b: [ [3, 3], [4, 4] ]}, - {b: [9, 9]}]}, - {'a.b': {$near: [9, 9], $maxDistance: 1}}, - {$set: {'a.$.b': 'k'}}, - {a: [{b: 'k'}, {b: [[3, 3], [4, 4]]}, {b: [9, 9]}]}); - await modifyWithQuery( {a: [{b: [1, 1]}, - {b: [ [3, 3], [4, 4] ]}, - {b: [9, 9]}]}, - {'a.b': {$near: [9, 9]}}, - {$set: {'a.$.b': 'k'}}, - {a: [{b: 'k'}, {b: [[3, 3], [4, 4]]}, {b: [9, 9]}]}); - await modifyWithQuery( {a: [{b: [9, 9]}, - {b: [ [3, 3], [4, 4] ]}, - {b: [9, 9]}]}, - {'a.b': {$near: [9, 9]}}, - {$set: {'a.$.b': 'k'}}, - {a: [{b: 'k'}, {b: [[3, 3], [4, 4]]}, {b: [9, 9]}]}); - await modifyWithQuery( {a: [{b: [4, 3]}, - {c: [1, 1]}]}, - {'a.c': {$near: [1, 1]}}, - {$set: {'a.$.c': 'k'}}, - {a: [{c: 'k', b: [4, 3]}, {c: [1, 1]}]}); - await modifyWithQuery( {a: [{c: [9, 9]}, - {b: [ [3, 3], [4, 4] ]}, - {b: [1, 1]}]}, - {'a.b': {$near: [1, 1]}}, - {$set: {'a.$.b': 'k'}}, - {a: [{c: [9, 9], b: 'k'}, {b: [ [3, 3], [4, 4]]}, {b: [1, 1]}]}); - await modifyWithQuery( {a: [{c: [9, 9], b: [4, 3]}, - {b: [ [3, 3], [4, 4] ]}, - {b: [1, 1]}]}, - {'a.b': {$near: [1, 1]}}, - {$set: {'a.$.b': 'k'}}, - {a: [{c: [9, 9], b: 'k'}, {b: [ [3, 3], [4, 4]]}, {b: [1, 1]}]}); - - // $inc - await modify( {a: 1, b: 2}, {$inc: {a: 10}}, {a: 11, b: 2}); - await modify( {a: 1, b: 2}, {$inc: {c: 10}}, {a: 1, b: 2, c: 10}); - await exception({a: 1}, {$inc: {a: '10'}}); - await exception({a: 1}, {$inc: {a: true}}); - await exception({a: 1}, {$inc: {a: [10]}}); - await exception({a: '1'}, {$inc: {a: 10}}); - await exception({a: [1]}, {$inc: {a: 10}}); - await exception({a: {}}, {$inc: {a: 10}}); - await exception({a: false}, {$inc: {a: 10}}); - await exception({a: null}, {$inc: {a: 10}}); - await modify( {a: [1, 2]}, {$inc: {'a.1': 10}}, {a: [1, 12]}); - await modify( {a: [1, 2]}, {$inc: {'a.2': 10}}, {a: [1, 2, 10]}); - await modify( {a: [1, 2]}, {$inc: {'a.3': 10}}, {a: [1, 2, null, 10]}); - await modify( {a: {b: 2}}, {$inc: {'a.b': 10}}, {a: {b: 12}}); - await modify( {a: {b: 2}}, {$inc: {'a.c': 10}}, {a: {b: 2, c: 10}}); - await exception({}, {$inc: {_id: 1}}); - - // $currentDate - await modify( {}, {$currentDate: {a: true}}, (result, msg) => { test.instanceOf(result.a, Date, msg); }); - await modify( {}, {$currentDate: {a: {$type: 'date'}}}, (result, msg) => { test.instanceOf(result.a, Date, msg); }); - await exception({}, {$currentDate: {a: false}}); - await exception({}, {$currentDate: {a: {}}}); - await exception({}, {$currentDate: {a: {$type: 'timestamp'}}}); - - // $min - await modify( {a: 1, b: 2}, {$min: {b: 1}}, {a: 1, b: 1}); - await modify( {a: 1, b: 2}, {$min: {b: 3}}, {a: 1, b: 2}); - await modify( {a: 1, b: 2}, {$min: {c: 10}}, {a: 1, b: 2, c: 10}); - await exception({a: 1}, {$min: {a: '10'}}); - await exception({a: 1}, {$min: {a: true}}); - await exception({a: 1}, {$min: {a: [10]}}); - await exception({a: '1'}, {$min: {a: 10}}); - await exception({a: [1]}, {$min: {a: 10}}); - await exception({a: {}}, {$min: {a: 10}}); - await exception({a: false}, {$min: {a: 10}}); - await exception({a: null}, {$min: {a: 10}}); - await modify( {a: [1, 2]}, {$min: {'a.1': 1}}, {a: [1, 1]}); - await modify( {a: [1, 2]}, {$min: {'a.1': 3}}, {a: [1, 2]}); - await modify( {a: [1, 2]}, {$min: {'a.2': 10}}, {a: [1, 2, 10]}); - await modify( {a: [1, 2]}, {$min: {'a.3': 10}}, {a: [1, 2, null, 10]}); - await modify( {a: {b: 2}}, {$min: {'a.b': 1}}, {a: {b: 1}}); - await modify( {a: {b: 2}}, {$min: {'a.c': 10}}, {a: {b: 2, c: 10}}); - await exception( {}, {$min: {_id: 1}}); - - //$mul - await modify( {a: 1, b: 1}, {$mul: {b: 2}}, {a: 1, b: 2}); - await modify( {a: 1, b: 1}, {$mul: {c: 2}}, {a: 1, b: 1, c: 0}); - await modify( {a: 1, b: 2}, {$mul: {b: 2}}, {a: 1, b: 4}); - await modify( {a: 1, b: 2}, {$mul: {b: 10}}, {a: 1, b: 20}); - await exception( {a: 1}, {$mul: {a: '10'}}); - await exception( {a: 1}, {$mul: {a: true}}); - await exception( {a: 1}, {$mul: {a: [10]}}); - await exception( {a: '1'}, {$mul: {a: 10}}); - await exception( {a: [1]}, {$mul: {a: 10}}); - await exception( {a: {}}, {$mul: {a: 10}}); - await exception( {a: false}, {$mul: {a: 10}}); - await exception( {a: null}, {$mul: {a: 10}}); - await exception( {}, {$mul: {_id: 1}}); - await modify( {a: [1, 2]}, {$mul: {'a.0': 2}}, {a: [2, 2]}); - await modify( {a: [1, 2]}, {$mul: {'a.1': 3}}, {a: [1, 6]}); - await modify( {a: [1, 2]}, {$mul: {'a.1': 10}}, {a: [1, 20]}); - await modify( {a: [1, 2]}, {$mul: {'a.2': 10}}, {a: [1, 2, 0]}); - await modify( {a: {b: 2}}, {$mul: {'a.b': 1}}, {a: {b: 2}}); - await modify( {a: {b: 2}}, {$mul: {'a.c': 10}}, {a: {b: 2, c: 0}}); - - // $max - await modify( {a: 1, b: 2}, {$max: {b: 1}}, {a: 1, b: 2}); - await modify( {a: 1, b: 2}, {$max: {b: 3}}, {a: 1, b: 3}); - await modify( {a: 1, b: 2}, {$max: {c: 10}}, {a: 1, b: 2, c: 10}); - await exception( {a: 1}, {$max: {a: '10'}}); - await exception( {a: 1}, {$max: {a: true}}); - await exception( {a: 1}, {$max: {a: [10]}}); - await exception( {a: '1'}, {$max: {a: 10}}); - await exception( {a: [1]}, {$max: {a: 10}}); - await exception( {a: {}}, {$max: {a: 10}}); - await exception( {a: false}, {$max: {a: 10}}); - await exception( {a: null}, {$max: {a: 10}}); - await modify( {a: [1, 2]}, {$max: {'a.1': 3}}, {a: [1, 3]}); - await modify( {a: [1, 2]}, {$max: {'a.1': 1}}, {a: [1, 2]}); - await modify( {a: [1, 2]}, {$max: {'a.2': 10}}, {a: [1, 2, 10]}); - await modify( {a: [1, 2]}, {$max: {'a.3': 10}}, {a: [1, 2, null, 10]}); - await modify( {a: {b: 2}}, {$max: {'a.b': 3}}, {a: {b: 3}}); - await modify( {a: {b: 2}}, {$max: {'a.c': 10}}, {a: {b: 2, c: 10}}); - await exception( {}, {$max: {_id: 1}}); - - // $set - await modify( {a: 1, b: 2}, {$set: {a: 10}}, {a: 10, b: 2}); - await modify( {a: 1, b: 2}, {$set: {c: 10}}, {a: 1, b: 2, c: 10}); - await modify( {a: 1, b: 2}, {$set: {a: {c: 10}}}, {a: {c: 10}, b: 2}); - await modify( {a: [1, 2], b: 2}, {$set: {a: [3, 4]}}, {a: [3, 4], b: 2}); - await modify( {a: [1, 2, 3], b: 2}, {$set: {'a.1': [3, 4]}}, - {a: [1, [3, 4], 3], b: 2}); - await modify( {a: [1], b: 2}, {$set: {'a.1': 9}}, {a: [1, 9], b: 2}); - await modify( {a: [1], b: 2}, {$set: {'a.2': 9}}, {a: [1, null, 9], b: 2}); - await modify( {a: {b: 1}}, {$set: {'a.c': 9}}, {a: {b: 1, c: 9}}); - await modify( {}, {$set: {'x._id': 4}}, {x: {_id: 4}}); - - // Changing _id is disallowed - await exception( {}, {$set: {_id: 4}}); - await exception( {_id: 1}, {$set: {_id: 4}}); - await modify( {_id: 4}, {$set: {_id: 4}}, {_id: 4}); // not-changing _id is not bad - // restricted field names - await exception( {a: {}}, {$set: {a: {$a: 1}}}); - await exception( { a: {} }, { $set: { a: { c: - [{ b: { $a: 1 } }] } } }); - await exception( {a: {}}, {$set: {a: {'\0a': 1}}}); - await exception( {a: {}}, {$set: {a: {'a.b': 1}}}); - - // $unset - await modify( {}, {$unset: {a: 1}}, {}); - await modify( {a: 1}, {$unset: {a: 1}}, {}); - await modify( {a: 1, b: 2}, {$unset: {a: 1}}, {b: 2}); - await modify( {a: 1, b: 2}, {$unset: {a: 0}}, {b: 2}); - await modify( {a: 1, b: 2}, {$unset: {a: false}}, {b: 2}); - await modify( {a: 1, b: 2}, {$unset: {a: null}}, {b: 2}); - await modify( {a: 1, b: 2}, {$unset: {a: [1]}}, {b: 2}); - await modify( {a: 1, b: 2}, {$unset: {a: {}}}, {b: 2}); - await modify( {a: {b: 2, c: 3}}, {$unset: {'a.b': 1}}, {a: {c: 3}}); - await modify( {a: [1, 2, 3]}, {$unset: {'a.1': 1}}, {a: [1, null, 3]}); // tested - await modify( {a: [1, 2, 3]}, {$unset: {'a.2': 1}}, {a: [1, 2, null]}); // tested - await modify( {a: [1, 2, 3]}, {$unset: {'a.x': 1}}, {a: [1, 2, 3]}); // tested - await modify( {a: {b: 1}}, {$unset: {'a.b.c.d': 1}}, {a: {b: 1}}); - await modify( {a: {b: 1}}, {$unset: {'a.x.c.d': 1}}, {a: {b: 1}}); - await modify( {a: {b: {c: 1}}}, {$unset: {'a.b.c': 1}}, {a: {b: {}}}); - await exception( {}, {$unset: {_id: 1}}); - - // $push - await modify( {}, {$push: {a: 1}}, {a: [1]}); - await modify( {a: []}, {$push: {a: 1}}, {a: [1]}); - await modify( {a: [1]}, {$push: {a: 2}}, {a: [1, 2]}); - await exception( {a: true}, {$push: {a: 1}}); - await modify( {a: [1]}, {$push: {a: [2]}}, {a: [1, [2]]}); - await modify( {a: []}, {$push: {'a.1': 99}}, {a: [null, [99]]}); // tested - await modify( {a: {}}, {$push: {'a.x': 99}}, {a: {x: [99]}}); - await modify( {}, {$push: {a: {$each: [1, 2, 3]}}}, - {a: [1, 2, 3]}); - await modify( {a: []}, {$push: {a: {$each: [1, 2, 3]}}}, - {a: [1, 2, 3]}); - await modify( {a: [true]}, {$push: {a: {$each: [1, 2, 3]}}}, - {a: [true, 1, 2, 3]}); - await modify( {a: [true]}, {$push: {a: {$each: [1, 2, 3], $slice: -2}}}, - {a: [2, 3]}); - await modify( {a: [false, true]}, {$push: {a: {$each: [1], $slice: -2}}}, - {a: [true, 1]}); - await modify( - {a: [{x: 3}, {x: 1}]}, - {$push: {a: { - $each: [{x: 4}, {x: 2}], - $slice: -2, - $sort: {x: 1}, - }}}, - {a: [{x: 3}, {x: 4}]}); - await modify( {}, {$push: {a: {$each: [1, 2, 3], $slice: 0}}}, {a: []}); - await modify( {a: [1, 2]}, {$push: {a: {$each: [1, 2, 3], $slice: 0}}}, {a: []}); - // $push with $position modifier - // No negative number for $position - await exception( {a: []}, {$push: {a: {$each: [0], $position: -1}}}); - await modify( {a: [1, 2]}, {$push: {a: {$each: [0], $position: 0}}}, - {a: [0, 1, 2]}); - await modify( {a: [1, 2]}, {$push: {a: {$each: [-1, 0], $position: 0}}}, - {a: [-1, 0, 1, 2]}); - await modify( {a: [1, 3]}, {$push: {a: {$each: [2], $position: 1}}}, {a: [1, 2, 3]}); - await modify( {a: [1, 4]}, {$push: {a: {$each: [2, 3], $position: 1}}}, - {a: [1, 2, 3, 4]}); - await modify( {a: [1, 2]}, {$push: {a: {$each: [3], $position: 3}}}, {a: [1, 2, 3]}); - await modify( {a: [1, 2]}, {$push: {a: {$each: [3], $position: 99}}}, - {a: [1, 2, 3]}); - await modify( {a: [1, 2]}, {$push: {a: {$each: [3], $position: 99, $slice: -2}}}, - {a: [2, 3]}); - await modify( - {a: [{x: 1}, {x: 2}]}, - {$push: {a: {$each: [{x: 3}], $position: 0, $sort: {x: 1}, $slice: -3}}}, - {a: [{x: 1}, {x: 2}, {x: 3}]} - ); - await modify( - {a: [{x: 1}, {x: 2}]}, - {$push: {a: {$each: [{x: 3}], $position: 0, $sort: {x: 1}, $slice: 0}}}, - {a: []} - ); - // restricted field names - await exception( {}, {$push: {$a: 1}}); - await exception( {}, {$push: {'\0a': 1}}); - await exception( {}, {$push: {a: {$a: 1}}}); - await exception( {}, {$push: {a: {$each: [{$a: 1}]}}}); - await exception( {}, {$push: {a: {$each: [{'a.b': 1}]}}}); - await exception( {}, {$push: {a: {$each: [{'\0a': 1}]}}}); - await modify( {}, {$push: {a: {$each: [{'': 1}]}}}, {a: [ { '': 1 } ]}); - await modify( {}, {$push: {a: {$each: [{' ': 1}]}}}, {a: [ { ' ': 1 } ]}); - await exception( {}, {$push: {a: {$each: [{'.': 1}]}}}); - - // #issue 5167 - // $push $slice with positive numbers - await modify( {}, {$push: {a: {$each: [], $slice: 5}}}, {a: []}); - await modify( {a: [1, 2, 3]}, {$push: {a: {$each: [], $slice: 1}}}, {a: [1]}); - await modify( {a: [1, 2, 3]}, {$push: {a: {$each: [4, 5], $slice: 1}}}, {a: [1]}); - await modify( {a: [1, 2, 3]}, {$push: {a: {$each: [4, 5], $slice: 2}}}, {a: [1, 2]}); - await modify( {a: [1, 2, 3]}, {$push: {a: {$each: [4, 5], $slice: 4}}}, {a: [1, 2, 3, 4]}); - await modify( {a: [1, 2, 3]}, {$push: {a: {$each: [4, 5], $slice: 5}}}, {a: [1, 2, 3, 4, 5]}); - await modify( {a: [1, 2, 3]}, {$push: {a: {$each: [4, 5], $slice: 10}}}, {a: [1, 2, 3, 4, 5]}); - - - // $pushAll - await modify( {}, {$pushAll: {a: [1]}}, {a: [1]}); - await modify( {a: []}, {$pushAll: {a: [1]}}, {a: [1]}); - await modify( {a: [1]}, {$pushAll: {a: [2]}}, {a: [1, 2]}); - await modify( {}, {$pushAll: {a: [1, 2]}}, {a: [1, 2]}); - await modify( {a: []}, {$pushAll: {a: [1, 2]}}, {a: [1, 2]}); - await modify( {a: [1]}, {$pushAll: {a: [2, 3]}}, {a: [1, 2, 3]}); - await modify( {}, {$pushAll: {a: []}}, {a: []}); - await modify( {a: []}, {$pushAll: {a: []}}, {a: []}); - await modify( {a: [1]}, {$pushAll: {a: []}}, {a: [1]}); - await exception( {a: true}, {$pushAll: {a: [1]}}); - await exception( {a: []}, {$pushAll: {a: 1}}); - await modify( {a: []}, {$pushAll: {'a.1': [99]}}, {a: [null, [99]]}); - await modify( {a: []}, {$pushAll: {'a.1': []}}, {a: [null, []]}); - await modify( {a: {}}, {$pushAll: {'a.x': [99]}}, {a: {x: [99]}}); - await modify( {a: {}}, {$pushAll: {'a.x': []}}, {a: {x: []}}); - await exception( {a: [1]}, {$pushAll: {a: [{$a: 1}]}}); - await exception( {a: [1]}, {$pushAll: {a: [{'\0a': 1}]}}); - await exception( {a: [1]}, {$pushAll: {a: [{'a.b': 1}]}}); - - // $addToSet - await modify( {}, {$addToSet: {a: 1}}, {a: [1]}); - await modify( {a: []}, {$addToSet: {a: 1}}, {a: [1]}); - await modify( {a: [1]}, {$addToSet: {a: 2}}, {a: [1, 2]}); - await modify( {a: [1, 2]}, {$addToSet: {a: 1}}, {a: [1, 2]}); - await modify( {a: [1, 2]}, {$addToSet: {a: 2}}, {a: [1, 2]}); - await modify( {a: [1, 2]}, {$addToSet: {a: 3}}, {a: [1, 2, 3]}); - await exception( {a: true}, {$addToSet: {a: 1}}); - await modify( {a: [1]}, {$addToSet: {a: [2]}}, {a: [1, [2]]}); - await modify( {}, {$addToSet: {a: {x: 1}}}, {a: [{x: 1}]}); - await modify( {a: [{x: 1}]}, {$addToSet: {a: {x: 1}}}, {a: [{x: 1}]}); - await modify( {a: [{x: 1}]}, {$addToSet: {a: {x: 2}}}, {a: [{x: 1}, {x: 2}]}); - await modify( {a: [{x: 1, y: 2}]}, {$addToSet: {a: {x: 1, y: 2}}}, - {a: [{x: 1, y: 2}]}); - await modify( {a: [{x: 1, y: 2}]}, {$addToSet: {a: {y: 2, x: 1}}}, - {a: [{x: 1, y: 2}, {y: 2, x: 1}]}); - await modify( {a: [1, 2]}, {$addToSet: {a: {$each: [3, 1, 4]}}}, {a: [1, 2, 3, 4]}); - await modify( {}, {$addToSet: {a: {$each: []}}}, {a: []}); - await modify( {}, {$addToSet: {a: {$each: [1]}}}, {a: [1]}); - await modify( {a: []}, {$addToSet: {'a.1': 99}}, {a: [null, [99]]}); - await modify( {a: {}}, {$addToSet: {'a.x': 99}}, {a: {x: [99]}}); - - // invalid field names - await exception( {}, {$addToSet: {a: {$b: 1}}}); - await exception( {}, {$addToSet: {a: {'a.b': 1}}}); - await exception( {}, {$addToSet: {a: {'a.': 1}}}); - await exception( {}, {$addToSet: {a: {'\u0000a': 1}}}); - await exception( {a: [1, 2]}, {$addToSet: {a: {$each: [3, 1, {$a: 1}]}}}); - await exception( {a: [1, 2]}, {$addToSet: {a: {$each: [3, 1, {'\0a': 1}]}}}); - await exception( {a: [1, 2]}, {$addToSet: {a: {$each: [3, 1, [{$a: 1}]]}}}); - await exception( {a: [1, 2]}, {$addToSet: {a: {$each: [3, 1, [{b: {c: [{a: 1}, {'d.s': 2}]}}]]}}}); - await exception( {a: [1, 2]}, {$addToSet: {a: {b: [3, 1, [{b: {c: [{a: 1}, {'d.s': 2}]}}]]}}}); - // $each is first element and thus an operator - await modify( {a: [1, 2]}, {$addToSet: {a: {$each: [3, 1, 4], b: 12}}}, {a: [ 1, 2, 3, 4 ]}); - // this should fail because $each is now a field name (not first in object) and thus invalid field name with $ - await exception( {a: [1, 2]}, {$addToSet: {a: {b: 12, $each: [3, 1, 4]}}}); - - // $pop - await modify( {}, {$pop: {a: 1}}, {}); // tested - await modify( {}, {$pop: {a: -1}}, {}); // tested - await modify( {a: []}, {$pop: {a: 1}}, {a: []}); - await modify( {a: []}, {$pop: {a: -1}}, {a: []}); - await modify( {a: [1, 2, 3]}, {$pop: {a: 1}}, {a: [1, 2]}); - await modify( {a: [1, 2, 3]}, {$pop: {a: 10}}, {a: [1, 2]}); - await modify( {a: [1, 2, 3]}, {$pop: {a: 0.001}}, {a: [1, 2]}); - await modify( {a: [1, 2, 3]}, {$pop: {a: 0}}, {a: [1, 2]}); - await modify( {a: [1, 2, 3]}, {$pop: {a: 'stuff'}}, {a: [1, 2]}); - await modify( {a: [1, 2, 3]}, {$pop: {a: -1}}, {a: [2, 3]}); - await modify( {a: [1, 2, 3]}, {$pop: {a: -10}}, {a: [2, 3]}); - await modify( {a: [1, 2, 3]}, {$pop: {a: -0.001}}, {a: [2, 3]}); - await exception( {a: true}, {$pop: {a: 1}}); - await exception( {a: true}, {$pop: {a: -1}}); - await modify( {a: []}, {$pop: {'a.1': 1}}, {a: []}); // tested - await modify( {a: [1, [2, 3], 4]}, {$pop: {'a.1': 1}}, {a: [1, [2], 4]}); - await modify( {a: {}}, {$pop: {'a.x': 1}}, {a: {}}); // tested - await modify( {a: {x: [2, 3]}}, {$pop: {'a.x': 1}}, {a: {x: [2]}}); - - // $pull - await modify( {}, {$pull: {a: 1}}, {}); - await modify( {}, {$pull: {'a.x': 1}}, {}); - await modify( {a: {}}, {$pull: {'a.x': 1}}, {a: {}}); - await exception( {a: true}, {$pull: {a: 1}}); - await modify( {a: [2, 1, 2]}, {$pull: {a: 1}}, {a: [2, 2]}); - await modify( {a: [2, 1, 2]}, {$pull: {a: 2}}, {a: [1]}); - await modify( {a: [2, 1, 2]}, {$pull: {a: 3}}, {a: [2, 1, 2]}); - await modify( {a: [1, null, 2, null]}, {$pull: {a: null}}, {a: [1, 2]}); - await modify( {a: []}, {$pull: {a: 3}}, {a: []}); - await modify( {a: [[2], [2, 1], [3]]}, {$pull: {a: [2, 1]}}, - {a: [[2], [3]]}); // tested - await modify( {a: [{b: 1, c: 2}, {b: 2, c: 2}]}, {$pull: {a: {b: 1}}}, - {a: [{b: 2, c: 2}]}); - await modify( {a: [{b: 1, c: 2}, {b: 2, c: 2}]}, {$pull: {a: {c: 2}}}, - {a: []}); - // XXX implement this functionality! - // probably same refactoring as $elemMatch? - // await modify( {a: [1, 2, 3, 4]}, {$pull: {$gt: 2}}, {a: [1,2]}); fails! - - // $pullAll - await modify( {}, {$pullAll: {a: [1]}}, {}); - await modify( {a: [1, 2, 3]}, {$pullAll: {a: []}}, {a: [1, 2, 3]}); - await modify( {a: [1, 2, 3]}, {$pullAll: {a: [2]}}, {a: [1, 3]}); - await modify( {a: [1, 2, 3]}, {$pullAll: {a: [2, 1]}}, {a: [3]}); - await modify( {a: [1, 2, 3]}, {$pullAll: {a: [1, 2]}}, {a: [3]}); - await modify( {}, {$pullAll: {'a.b.c': [2]}}, {}); - await exception( {a: true}, {$pullAll: {a: [1]}}); - await exception( {a: [1, 2, 3]}, {$pullAll: {a: 1}}); - await modify( {x: [{a: 1}, {a: 1, b: 2}]}, {$pullAll: {x: [{a: 1}]}}, - {x: [{a: 1, b: 2}]}); - - // $rename - await modify( {}, {$rename: {a: 'b'}}, {}); - await modify( {a: [12]}, {$rename: {a: 'b'}}, {b: [12]}); - await modify( {a: {b: 12}}, {$rename: {a: 'c'}}, {c: {b: 12}}); - await modify( {a: {b: 12}}, {$rename: {'a.b': 'a.c'}}, {a: {c: 12}}); - await modify( {a: {b: 12}}, {$rename: {'a.b': 'x'}}, {a: {}, x: 12}); // tested - await modify( {a: {b: 12}}, {$rename: {'a.b': 'q.r'}}, {a: {}, q: {r: 12}}); - await modify( {a: {b: 12}}, {$rename: {'a.b': 'q.2.r'}}, {a: {}, q: {2: {r: 12}}}); - await modify( {a: {b: 12}, q: {}}, {$rename: {'a.b': 'q.2.r'}}, - {a: {}, q: {2: {r: 12}}}); - await exception( {a: {b: 12}, q: []}, {$rename: {'a.b': 'q.2'}}); // tested - await exception( {a: {b: 12}, q: []}, {$rename: {'a.b': 'q.2.r'}}); // tested - // These strange MongoDB behaviors throw. - // await modify( {a: {b: 12}, q: []}, {$rename: {'q.1': 'x'}}, - // {a: {b: 12}, x: []}); // tested - // await modify( {a: {b: 12}, q: []}, {$rename: {'q.1.j': 'x'}}, - // {a: {b: 12}, x: []}); // tested - await exception( {}, {$rename: {a: 'a'}}); - await exception( {}, {$rename: {'a.b': 'a.b'}}); - await modify( {a: 12, b: 13}, {$rename: {a: 'b'}}, {b: 12}); - await exception( {a: [12]}, {$rename: {a: '$b'}}); - await exception( {a: [12]}, {$rename: {a: '\0a'}}); - - // $setOnInsert - await modify( {a: 0}, {$setOnInsert: {a: 12}}, {a: 0}); - await upsert( {a: 12}, {$setOnInsert: {b: 12}}, {a: 12, b: 12}); - await upsert( {a: 12}, {$setOnInsert: {_id: 'test'}}, {_id: 'test', a: 12}); - await upsert( {'a.b': 10}, {$setOnInsert: {a: {b: 10, c: 12}}}, {a: {b: 10, c: 12}}); - await upsert( {'a.b': 10}, {$setOnInsert: {c: 12}}, {a: {b: 10}, c: 12}); - await upsert( {_id: 'test'}, {$setOnInsert: {c: 12}}, {_id: 'test', c: 12}); - await upsert( 'test', {$setOnInsert: {c: 12}}, {_id: 'test', c: 12}); - await upsertException( {a: 0}, {$setOnInsert: {$a: 12}}); - await upsertException( {a: 0}, {$setOnInsert: {'\0a': 12}}); - await upsert( {a: 0}, {$setOnInsert: {b: {a: 1}}}, {a: 0, b: {a: 1}}); - await upsertException( {a: 0}, {$setOnInsert: {b: {$a: 1}}}); - await upsertException( {a: 0}, {$setOnInsert: {b: {'a.b': 1}}}); - await upsertException( {a: 0}, {$setOnInsert: {b: {'\0a': 1}}}); - - // Test for https://github.com/meteor/meteor/issues/8775. - await upsert( - { a: { $exists: true }}, - { $setOnInsert: { a: 123 }}, - { a: 123 } - ); - - // Tests for https://github.com/meteor/meteor/issues/8794. - const testObjectId = new MongoID.ObjectID(); - await upsert( - { _id: testObjectId }, - { $setOnInsert: { a: 123 } }, - { _id: testObjectId, a: 123 }, - ); - await upsert( - { someOtherId: testObjectId }, - { $setOnInsert: { a: 123 } }, - { someOtherId: testObjectId, a: 123 }, - ); - await upsert( - { a: { $eq: testObjectId } }, - { $setOnInsert: { a: 123 } }, - { a: 123 }, - ); - const testDate = new Date('2017-01-01'); - await upsert( - { someDate: testDate }, - { $setOnInsert: { a: 123 } }, - { someDate: testDate, a: 123 }, - ); - await upsert( - { - a: Object.create(null, { - $exists: { - writable: true, - configurable: true, - value: true, - }, - }), - }, - { $setOnInsert: { a: 123 } }, - { a: 123 }, - ); - await upsert( - { foo: { $exists: true, $type: 2 }}, - { $setOnInsert: { bar: 'baz' } }, - { bar: 'baz' } - ); - await upsert( - { foo: {} }, - { $setOnInsert: { bar: 'baz' } }, - { foo: {}, bar: 'baz' } - ); - - // Tests for https://github.com/meteor/meteor/issues/8806 - await upsert( {"a": {"b": undefined, "c": null}}, {"$set": {"c": "foo"}}, {"a": {"b": undefined, "c": null}, "c": "foo"}) - await upsert( {"a": {"$eq": "bar" }}, {"$set": {"c": "foo"}}, {"a": "bar", "c": "foo"}) - // $all with 1 statement is similar to $eq - await upsert( {"a": {"$all": ["bar"] }}, {"$set": {"c": "foo"}}, {"a": "bar", "c": "foo"}) - await upsert( {"a": {"$eq": "bar" }, "b": "baz"}, {"$set": {"c": "foo"}}, {"a": "bar", "b": "baz", "c": "foo"}) - await upsert( {"a": {"$exists": true}}, {"$set": {"c": "foo"}}, {"c": "foo"}) - await upsert( {"a": {"$exists": true, "$eq": "foo"}}, {"$set": {"c": "foo"}}, {"a": "foo", "c": "foo"}) - await upsert( {"a": {"$gt": 3, "$eq": 2}}, {"$set": {"c": "foo"}}, {"a": 2, "c": "foo"}) - // $and - await upsert( {"$and": [{"a": {"$eq": "bar"}}]}, {"$set": {"c": "foo"}}, {"a": "bar", "c": "foo"}) - await upsert( {"$and": [{"a": {"$all": ["bar"]}}]}, {"$set": {"c": "foo"}}, {"a": "bar", "c": "foo"}) - await upsert( {"$and": [{"a": {"$all": ["bar"]}}]}, {"$set": {"c": "foo"}}, {"a": "bar", "c": "foo"}) - // $or with one statement is handled similar to $and - await upsert( {"$or": [{"a": "bar"}]}, {"$set": {"c": "foo"}}, {"a": "bar", "c": "foo"}) - // $or with multiple statements is ignored - await upsert( {"$or": [{"a": "bar"}, {"b": "baz"}]}, {"$set": {"c": "foo"}}, {"c": "foo"}) - // Negative logical operators are ignored - await upsert( {"$nor": [{"a": "bar"}]}, {"$set": {"c": "foo"}}, {"c": "foo"}) - // Filter out empty objects after filtering out operators - await upsert( {"a": {"$exists": true}}, {"$set": {"c": "foo"}}, {"c": "foo"}) - // But leave actual empty objects - await upsert( {"a": {}}, {"$set": {"c": "foo"}}, {"a": {}, "c": "foo"}) - // Also filter out shorthand regexp notation - await upsert( {"a": /a/}, {"$set": {"c": "foo"}}, {"c": "foo"}) - // Test nested fields - await upsert( {"$and": [{"a.a": "foo"}, {"$or": [{"a.b": "baz"}]}]}, {"$set": {"c": "foo"}}, {"a": {"a": "foo", "b": "baz"}, "c": "foo"}) - // Test for https://github.com/meteor/meteor/issues/5294 - await upsert( {"a": {"$ne": 444}}, {"$push": {"a": 123}}, {"a": [123]}) - // Mod takes precedence over query - await upsert( {"a": "foo"}, {"a": "bar"}, {"a": "bar"}) - await upsert( {"a": "foo"}, {"$set":{"a": "bar"}}, {"a": "bar"}) - // Replacement can take _id from query - await upsert( {"_id": "foo", "foo": "bar"}, {"bar": "foo"}, {"_id": "foo", "bar": "foo"}) - // Replacement update keeps _id - await upsertUpdate( {"_id": "foo", "bar": "baz"}, {"_id":"foo"}, {"bar": "crow"}, {"_id": "foo", "bar": "crow"}); - // Test for https://github.com/meteor/meteor/issues/9167 - await upsert( {key: 123, keyName: '321'}, {$set: {name: 'Todo'}}, {key: 123, keyName: '321', name: 'Todo'}); - await upsertException( {key: 123, "key.name": '321'}, {$set:{}}); - - // Nested fields don't work with literal objects - await upsertException( {"a": {}, "a.b": "foo"}, {}); - // You can't have an ambiguous ID - await upsertException( {"_id":"foo"}, {"_id":"bar"}); - await upsertException( {"_id":"foo"}, {"$set":{"_id":"bar"}}); - // You can't set the same field twice - await upsertException( {"$and": [{"a": "foo"}, {"a": "foo"}]}, {}); //not even with same value - await upsertException( {"a": {"$all": ["foo", "bar"]}}, {}); - await upsertException( {"$and": [{"a": {"$eq": "foo"}}, {"$or": [{"a": {"$all": ["bar"]}}]}]}, {}); - // You can't have nested dotted fields - await upsertException( {"a": {"foo.bar": "baz"}}, {}); - // You can't have dollar-prefixed fields above the first level (logical operators not counted) - await upsertException( {"a": {"a": {"$eq": "foo"}}}, {}); - await upsertException( {"a": {"a": {"$exists": true}}}, {}); - // You can't mix operators with other fields - await upsertException( {"a": {"$eq": "bar", "b": "foo"}}, {}) - await upsertException( {"a": {"b": "foo", "$eq": "bar"}}, {}) - - const mongoIdForUpsert = new MongoID.ObjectID('44915733af80844fa1cef07a'); - await upsert( {_id: mongoIdForUpsert}, {$setOnInsert: {a: 123}}, {a: 123}) - - // Test for https://github.com/meteor/meteor/issues/7758 - await upsert( {n_id: mongoIdForUpsert, c_n: "bar"}, - {$set: { t_t_o: "foo"}}, - {n_id: mongoIdForUpsert, t_t_o: "foo", c_n: "bar"}); - - await exception( {}, {$set: {_id: 'bad'}}); - - // $bit - // unimplemented - - // XXX test case sensitivity of modops - // XXX for each (most) modop, test that it performs a deep copy -}); - -// XXX test update() (selecting docs, multi, upsert..) - -Tinytest.addAsync('async - minimongo - observe ordered', async test => { - const operations = []; - const cbs = log_callbacks(operations); - let handle; - - const c = new LocalCollection(); - handle = c.find({}, {sort: {a: 1}}).observe(cbs); - test.isTrue(handle.collection === c); - - await c.insertAsync({_id: 'foo', a: 1}); - test.equal(operations.shift(), ['added', {a: 1}, 0, null]); - await c.updateAsync({a: 1}, {$set: {a: 2}}); - test.equal(operations.shift(), ['changed', {a: 2}, 0, {a: 1}]); - await c.insertAsync({a: 10}); - test.equal(operations.shift(), ['added', {a: 10}, 1, null]); - await c.updateAsync({}, {$inc: {a: 1}}, {multi: true}); - test.equal(operations.shift(), ['changed', {a: 3}, 0, {a: 2}]); - test.equal(operations.shift(), ['changed', {a: 11}, 1, {a: 10}]); - await c.updateAsync({a: 11}, {a: 1}); - test.equal(operations.shift(), ['changed', {a: 1}, 1, {a: 11}]); - test.equal(operations.shift(), ['moved', {a: 1}, 1, 0, 'foo']); - await c.removeAsync({a: 2}); - test.equal(operations.shift(), undefined); - await c.removeAsync({a: 3}); - test.equal(operations.shift(), ['removed', 'foo', 1, {a: 3}]); - - // test stop - handle.stop(); - const idA2 = Random.id(); - await c.insertAsync({_id: idA2, a: 2}); - test.equal(operations.shift(), undefined); - - // test initial inserts (and backwards sort) - handle = c.find({}, {sort: {a: -1}}).observe(cbs); - test.equal(operations.shift(), ['added', {a: 2}, 0, null]); - test.equal(operations.shift(), ['added', {a: 1}, 1, null]); - handle.stop(); - - // test _suppress_initial - handle = c.find({}, {sort: {a: -1}}).observe(Object.assign({ - _suppress_initial: true}, cbs)); - test.equal(operations.shift(), undefined); - await c.insertAsync({a: 100}); - test.equal(operations.shift(), ['added', {a: 100}, 0, idA2]); - handle.stop(); - - // test skip and limit. - await c.removeAsync({}); - handle = c.find({}, {sort: {a: 1}, skip: 1, limit: 2}).observe(cbs); - test.equal(operations.shift(), undefined); - await c.insertAsync({a: 1}); - test.equal(operations.shift(), undefined); - await c.insertAsync({_id: 'foo', a: 2}); - test.equal(operations.shift(), ['added', {a: 2}, 0, null]); - await c.insertAsync({a: 3}); - test.equal(operations.shift(), ['added', {a: 3}, 1, null]); - await c.insertAsync({a: 4}); - test.equal(operations.shift(), undefined); - await c.updateAsync({a: 1}, {a: 0}); - test.equal(operations.shift(), undefined); - await c.updateAsync({a: 0}, {a: 5}); - test.equal(operations.shift(), ['removed', 'foo', 0, {a: 2}]); - test.equal(operations.shift(), ['added', {a: 4}, 1, null]); - await c.updateAsync({a: 3}, {a: 3.5}); - test.equal(operations.shift(), ['changed', {a: 3.5}, 0, {a: 3}]); - handle.stop(); - - // test observe limit with pre-existing docs - await c.removeAsync({}); - await c.insertAsync({a: 1}); - await c.insertAsync({_id: 'two', a: 2}); - await c.insertAsync({a: 3}); - handle = c.find({}, {sort: {a: 1}, limit: 2}).observe(cbs); - test.equal(operations.shift(), ['added', {a: 1}, 0, null]); - test.equal(operations.shift(), ['added', {a: 2}, 1, null]); - test.equal(operations.shift(), undefined); - await c.removeAsync({a: 2}); - test.equal(operations.shift(), ['removed', 'two', 1, {a: 2}]); - test.equal(operations.shift(), ['added', {a: 3}, 1, null]); - test.equal(operations.shift(), undefined); - handle.stop(); - - // test _no_indices - - await c.removeAsync({}); - handle = c.find({}, {sort: {a: 1}}).observe(Object.assign(cbs, {_no_indices: true})); - await c.insertAsync({_id: 'foo', a: 1}); - test.equal(operations.shift(), ['added', {a: 1}, -1, null]); - await c.updateAsync({a: 1}, {$set: {a: 2}}); - test.equal(operations.shift(), ['changed', {a: 2}, -1, {a: 1}]); - await c.insertAsync({a: 10}); - test.equal(operations.shift(), ['added', {a: 10}, -1, null]); - await c.updateAsync({}, {$inc: {a: 1}}, {multi: true}); - test.equal(operations.shift(), ['changed', {a: 3}, -1, {a: 2}]); - test.equal(operations.shift(), ['changed', {a: 11}, -1, {a: 10}]); - await c.updateAsync({a: 11}, {a: 1}); - test.equal(operations.shift(), ['changed', {a: 1}, -1, {a: 11}]); - test.equal(operations.shift(), ['moved', {a: 1}, -1, -1, 'foo']); - await c.removeAsync({a: 2}); - test.equal(operations.shift(), undefined); - await c.removeAsync({a: 3}); - test.equal(operations.shift(), ['removed', 'foo', -1, {a: 3}]); - handle.stop(); -}); - -[true, false].forEach(ordered => { - Tinytest.addAsync(`async - minimongo - observe ordered: ${ordered}`, async test => { - const c = new LocalCollection(); - - let ev = ''; - const makecb = tag => { - const ret = {}; - ['added', 'changed', 'removed'].forEach(fn => { - const fnName = ordered ? `${fn}At` : fn; - ret[fnName] = doc => { - ev = `${ev + fn.substr(0, 1) + tag + doc._id}_`; - }; - }); - return ret; - }; - const expect = x => { - test.equal(ev, x); - ev = ''; - }; - - await c.insertAsync({_id: 1, name: 'strawberry', tags: ['fruit', 'red', 'squishy']}); - await c.insertAsync({_id: 2, name: 'apple', tags: ['fruit', 'red', 'hard']}); - await c.insertAsync({_id: 3, name: 'rose', tags: ['flower', 'red', 'squishy']}); - - // This should work equally well for ordered and unordered observations - // (because the callbacks don't look at indices and there's no 'moved' - // callback). - let handle = c.find({tags: 'flower'}).observe(makecb('a')); - expect('aa3_'); - await c.updateAsync({name: 'rose'}, {$set: {tags: ['bloom', 'red', 'squishy']}}); - expect('ra3_'); - await c.updateAsync({name: 'rose'}, {$set: {tags: ['flower', 'red', 'squishy']}}); - expect('aa3_'); - await c.updateAsync({name: 'rose'}, {$set: {food: false}}); - expect('ca3_'); - await c.removeAsync({}); - expect('ra3_'); - await c.insertAsync({_id: 4, name: 'daisy', tags: ['flower']}); - expect('aa4_'); - handle.stop(); - // After calling stop, no more callbacks are called. - await c.insertAsync({_id: 5, name: 'iris', tags: ['flower']}); - expect(''); - - // Test that observing a lookup by ID works. - handle = c.find(4).observe(makecb('b')); - expect('ab4_'); - await c.updateAsync(4, {$set: {eek: 5}}); - expect('cb4_'); - handle.stop(); - - // Test observe with reactive: false. - handle = c.find({tags: 'flower'}, {reactive: false}).observe(makecb('c')); - expect('ac4_ac5_'); - // This insert shouldn't trigger a callback because it's not reactive. - await c.insertAsync({_id: 6, name: 'river', tags: ['flower']}); - expect(''); - handle.stop(); - }); -}); - - -Tinytest.addAsync('async - minimongo - saveOriginals', async test => { - // set up some data - const c = new LocalCollection(); - - let count; - await c.insertAsync({_id: 'foo', x: 'untouched'}); - await c.insertAsync({_id: 'bar', x: 'updateme'}); - await c.insertAsync({_id: 'baz', x: 'updateme'}); - await c.insertAsync({_id: 'quux', y: 'removeme'}); - await c.insertAsync({_id: 'whoa', y: 'removeme'}); - - // Save originals and make some changes. - c.saveOriginals(); - await c.insertAsync({_id: 'hooray', z: 'insertme'}); - await c.removeAsync({y: 'removeme'}); - count = await c.updateAsync({x: 'updateme'}, {$set: {z: 5}}, {multi: true}); - await c.updateAsync('bar', {$set: {k: 7}}); // update same doc twice - - // Verify returned count is correct - test.equal(count, 2); - - // Verify the originals. - let originals = c.retrieveOriginals(); - const affected = ['bar', 'baz', 'quux', 'whoa', 'hooray']; - test.equal(originals.size(), affected.length); - affected.forEach(id => { - test.isTrue(originals.has(id)); - }); - test.equal(originals.get('bar'), {_id: 'bar', x: 'updateme'}); - test.equal(originals.get('baz'), {_id: 'baz', x: 'updateme'}); - test.equal(originals.get('quux'), {_id: 'quux', y: 'removeme'}); - test.equal(originals.get('whoa'), {_id: 'whoa', y: 'removeme'}); - test.equal(originals.get('hooray'), undefined); - - // Verify that changes actually occured. - test.equal(c.find().count(), 4); - test.equal(c.findOne('foo'), {_id: 'foo', x: 'untouched'}); - test.equal(c.findOne('bar'), {_id: 'bar', x: 'updateme', z: 5, k: 7}); - test.equal(c.findOne('baz'), {_id: 'baz', x: 'updateme', z: 5}); - test.equal(c.findOne('hooray'), {_id: 'hooray', z: 'insertme'}); - - // The next call doesn't get the same originals again. - c.saveOriginals(); - originals = c.retrieveOriginals(); - test.isTrue(originals); - test.isTrue(originals.empty()); - - // Insert and remove a document during the period. - c.saveOriginals(); - await c.insertAsync({_id: 'temp', q: 8}); - await c.removeAsync('temp'); - originals = c.retrieveOriginals(); - test.equal(originals.size(), 1); - test.isTrue(originals.has('temp')); - test.equal(originals.get('temp'), undefined); -}); - -Tinytest.addAsync('async - minimongo - saveOriginals errors', async test => { - const c = new LocalCollection(); - // Can't call retrieve before save. - await test.throwsAsync(() => { c.retrieveOriginals(); }); - c.saveOriginals(); - // Can't call save twice. - await test.throwsAsync(() => { c.saveOriginals(); }); -}); - -Tinytest.addAsync('async - minimongo - objectid transformation', async test => { - const testId = item => { - test.equal(item, MongoID.idParse(MongoID.idStringify(item))); - }; - const randomOid = new MongoID.ObjectID(); - testId(randomOid); - testId('FOO'); - testId('ffffffffffff'); - testId('0987654321abcdef09876543'); - testId(new MongoID.ObjectID()); - testId('--a string'); - - test.equal('ffffffffffff', MongoID.idParse(MongoID.idStringify('ffffffffffff'))); -}); - - -Tinytest.addAsync('async - minimongo - objectid', async test => { - const randomOid = new MongoID.ObjectID(); - const anotherRandomOid = new MongoID.ObjectID(); - test.notEqual(randomOid, anotherRandomOid); - await test.throwsAsync(() => { new MongoID.ObjectID('qqqqqqqqqqqqqqqqqqqqqqqq');}); - await test.throwsAsync(() => { new MongoID.ObjectID('ABCDEF'); }); - test.equal(randomOid, new MongoID.ObjectID(randomOid.valueOf())); -}); - -Tinytest.addAsync('async - minimongo - pause', async test => { - const operations = []; - const cbs = log_callbacks(operations); - - const c = new LocalCollection(); - const h = c.find({}).observe(cbs); - - // remove and add cancel out. - await c.insertAsync({_id: 1, a: 1}); - test.equal(operations.shift(), ['added', {a: 1}, 0, null]); - - c.pauseObservers(); - - await c.removeAsync({_id: 1}); - test.length(operations, 0); - await c.insertAsync({_id: 1, a: 1}); - test.length(operations, 0); - - await c.resumeObservers(); - test.length(operations, 0); - - - // two modifications become one - c.pauseObservers(); - - await c.updateAsync({_id: 1}, {a: 2}); - await c.updateAsync({_id: 1}, {a: 3}); - - await c.resumeObservers(); - test.equal(operations.shift(), ['changed', {a: 3}, 0, {a: 1}]); - test.length(operations, 0); - - // test special case for remove({}) - c.pauseObservers(); - test.equal(await c.removeAsync({}), 1); - test.length(operations, 0); - await c.resumeObservers(); - test.equal(operations.shift(), ['removed', 1, 0, {a: 3}]); - test.length(operations, 0); - - h.stop(); -}); - -Tinytest.addAsync('async - minimongo - ids matched by selector', async test => { - const check = (selector, ids) => { - const idsFromSelector = LocalCollection._idsMatchedBySelector(selector); - // XXX normalize order, in a way that also works for ObjectIDs? - test.equal(idsFromSelector, ids); - }; - check('foo', ['foo']); - check({_id: 'foo'}, ['foo']); - const oid1 = new MongoID.ObjectID(); - check(oid1, [oid1]); - check({_id: oid1}, [oid1]); - check({_id: 'foo', x: 42}, ['foo']); - check({}, null); - check({_id: {$in: ['foo', oid1]}}, ['foo', oid1]); - check({_id: {$ne: 'foo'}}, null); - // not actually valid, but works for now... - check({$and: ['foo']}, ['foo']); - check({$and: [{x: 42}, {_id: oid1}]}, [oid1]); - check({$and: [{x: 42}, {_id: {$in: [oid1]}}]}, [oid1]); -}); - -Tinytest.addAsync('async - minimongo - reactive stop', async test => { - const coll = new LocalCollection(); - coll.insert({_id: 'A'}); - coll.insert({_id: 'B'}); - coll.insert({_id: 'C'}); - - const addBefore = (str, newChar, before) => { - const idx = str.indexOf(before); - if (idx === -1) {return str + newChar;} - return str.slice(0, idx) + newChar + str.slice(idx); - }; - - let x, y; - const sortOrder = ReactiveVar(1); - - const c = Tracker.autorun(() => { - const q = coll.find({}, {sort: {_id: sortOrder.get()}}); - x = ''; - q.observe({ addedAt(doc, atIndex, before) { - x = addBefore(x, doc._id, before); - }}); - y = ''; - q.observeChanges({ addedBefore(id, fields, before) { - y = addBefore(y, id, before); - }}); - }); - - test.equal(x, 'ABC'); - test.equal(y, 'ABC'); - - sortOrder.set(-1); - test.equal(x, 'ABC'); - test.equal(y, 'ABC'); - Tracker.flush(); - test.equal(x, 'CBA'); - test.equal(y, 'CBA'); - - coll.insert({_id: 'D'}); - coll.insert({_id: 'E'}); - test.equal(x, 'EDCBA'); - test.equal(y, 'EDCBA'); - - c.stop(); - // stopping kills the observes immediately - coll.insert({_id: 'F'}); - test.equal(x, 'EDCBA'); - test.equal(y, 'EDCBA'); -}); - -Tinytest.addAsync('async - minimongo - immediate invalidate', async test => { - const coll = new LocalCollection(); - coll.insert({_id: 'A'}); - - // This has two separate findOnes. findOne() uses skip/limit, which means - // that its response to an update() call involves a recompute. We used to have - // a bug where we would first calculate all the calls that need to be - // recomputed, then recompute them one by one, without checking to see if the - // callbacks from recomputing one query stopped the second query, which - // crashed. - const c = Tracker.autorun(() => { - coll.findOne('A'); - coll.findOne('A'); - }); - - coll.updateAsync('A', {$set: {x: 42}}); - - c.stop(); -}); - - -Tinytest.addAsync('async - minimongo - count on cursor with limit', async test => { - const coll = new LocalCollection(); - let count, unlimitedCount; - - coll.insert({_id: 'A'}); - coll.insert({_id: 'B'}); - coll.insert({_id: 'C'}); - coll.insert({_id: 'D'}); - - const c = Tracker.autorun(c => { - const cursor = coll.find({_id: {$exists: true}}, {sort: {_id: 1}, limit: 3}); - count = cursor.count(); - }); - - test.equal(count, 3); - - coll.removeAsync('A'); // still 3 in the collection - Tracker.flush(); - test.equal(count, 3); - - coll.removeAsync('B'); // expect count now 2 - Tracker.flush(); - test.equal(count, 2); - - - coll.insert({_id: 'A'}); // now 3 again - Tracker.flush(); - test.equal(count, 3); - - coll.insert({_id: 'B'}); // now 4 entries, but count should be 3 still - Tracker.flush(); - test.equal(count, 3); - - c.stop(); -}); - -Tinytest.addAsync('async - minimongo - reactive count with cached cursor', async test => { - const coll = new LocalCollection; - const cursor = coll.find({}); - let firstAutorunCount, secondAutorunCount; - Tracker.autorun(() => { - firstAutorunCount = cursor.count(); - }); - Tracker.autorun(() => { - secondAutorunCount = coll.find({}).count(); - }); - test.equal(firstAutorunCount, 0); - test.equal(secondAutorunCount, 0); - coll.insert({i: 1}); - coll.insert({i: 2}); - coll.insert({i: 3}); - Tracker.flush(); - test.equal(firstAutorunCount, 3); - test.equal(secondAutorunCount, 3); -}); - -Tinytest.addAsync('async - minimongo - $near operator tests', async test => { - let coll = new LocalCollection(); - coll.insert({ rest: { loc: [2, 3] } }); - coll.insert({ rest: { loc: [-3, 3] } }); - coll.insert({ rest: { loc: [5, 5] } }); - - test.equal(coll.find({ 'rest.loc': { $near: [0, 0], $maxDistance: 30 } }).count(), 3); - test.equal(coll.find({ 'rest.loc': { $near: [0, 0], $maxDistance: 4 } }).count(), 1); - const points = coll.find({ 'rest.loc': { $near: [0, 0], $maxDistance: 6 } }).fetch(); - points.forEach((point, i, points) => { - test.isTrue(!i || distance([0, 0], point.rest.loc) >= distance([0, 0], points[i - 1].rest.loc)); - }); - - function distance(a, b) { - const x = a[0] - b[0]; - const y = a[1] - b[1]; - return Math.sqrt(x * x + y * y); - } - - // GeoJSON tests - coll = new LocalCollection(); - const data = [{ category: 'BURGLARY', descript: 'BURGLARY OF STORE, FORCIBLE ENTRY', address: '100 Block of 10TH ST', location: { type: 'Point', coordinates: [ -122.415449723856, 37.7749518087273 ] } }, - { category: 'WEAPON LAWS', descript: 'POSS OF PROHIBITED WEAPON', address: '900 Block of MINNA ST', location: { type: 'Point', coordinates: [ -122.415386041221, 37.7747879744156 ] } }, - { category: 'LARCENY/THEFT', descript: 'GRAND THEFT OF PROPERTY', address: '900 Block of MINNA ST', location: { type: 'Point', coordinates: [ -122.41538270191, 37.774683628213 ] } }, - { category: 'LARCENY/THEFT', descript: 'PETTY THEFT FROM LOCKED AUTO', address: '900 Block of MINNA ST', location: { type: 'Point', coordinates: [ -122.415396041221, 37.7747879744156 ] } }, - { category: 'OTHER OFFENSES', descript: 'POSSESSION OF BURGLARY TOOLS', address: '900 Block of MINNA ST', location: { type: 'Point', coordinates: [ -122.415386041221, 37.7747879734156 ] } }, - ]; - - data.forEach((x, i) => { coll.insert(Object.assign(x, { x: i })); }); - - const close15 = coll.find({ location: { $near: { - $geometry: { type: 'Point', - coordinates: [-122.4154282, 37.7746115] }, - $maxDistance: 15 } } }).fetch(); - test.length(close15, 1); - test.equal(close15[0].descript, 'GRAND THEFT OF PROPERTY'); - - const close20 = coll.find({ location: { $near: { - $geometry: { type: 'Point', - coordinates: [-122.4154282, 37.7746115] }, - $maxDistance: 20 } } }).fetch(); - test.length(close20, 4); - test.equal(close20[0].descript, 'GRAND THEFT OF PROPERTY'); - test.equal(close20[1].descript, 'PETTY THEFT FROM LOCKED AUTO'); - test.equal(close20[2].descript, 'POSSESSION OF BURGLARY TOOLS'); - test.equal(close20[3].descript, 'POSS OF PROHIBITED WEAPON'); - - // Any combinations of $near with $or/$and/$nor/$not should throw an error - await test.throwsAsync(() => { - coll.find({ location: { - $not: { - $near: { - $geometry: { - type: 'Point', - coordinates: [-122.4154282, 37.7746115], - }, $maxDistance: 20 } } } }); - }); - await test.throwsAsync(() => { - coll.find({ - $and: [ { location: { $near: { $geometry: { type: 'Point', coordinates: [-122.4154282, 37.7746115] }, $maxDistance: 20 }}}, - { x: 0 }], - }); - }); - await test.throwsAsync(() => { - coll.find({ - $or: [ { location: { $near: { $geometry: { type: 'Point', coordinates: [-122.4154282, 37.7746115] }, $maxDistance: 20 }}}, - { x: 0 }], - }); - }); - await test.throwsAsync(() => { - coll.find({ - $nor: [ { location: { $near: { $geometry: { type: 'Point', coordinates: [-122.4154282, 37.7746115] }, $maxDistance: 1 }}}, - { x: 0 }], - }); - }); - await test.throwsAsync(() => { - coll.find({ - $and: [{ - $and: [{ - location: { - $near: { - $geometry: { - type: 'Point', - coordinates: [-122.4154282, 37.7746115], - }, - $maxDistance: 1, - }, - }, - }], - }], - }); - }); - - // array tests - coll = new LocalCollection(); - coll.insert({ - _id: 'x', - k: 9, - a: [ - {b: [ - [100, 100], - [1, 1]]}, - {b: [150, 150]}]}); - coll.insert({ - _id: 'y', - k: 9, - a: {b: [5, 5]}}); - const testNear = (near, md, expected) => { - test.equal( - coll.find({'a.b': {$near: near, $maxDistance: md}}).fetch().map(doc => doc._id), - expected); - }; - testNear([149, 149], 4, ['x']); - testNear([149, 149], 1000, ['x', 'y']); - // It's important that we figure out that 'x' is closer than 'y' to [2,2] even - // though the first within-1000 point in 'x' (ie, [100,100]) is farther than - // 'y'. - testNear([2, 2], 1000, ['x', 'y']); - - // issue #3599 - // Ensure that distance is not used as a tie-breaker for sort. - test.equal( - coll.find({'a.b': {$near: [1, 1]}}, {sort: {k: 1}}).fetch().map(doc => doc._id), - ['x', 'y']); - test.equal( - coll.find({'a.b': {$near: [5, 5]}}, {sort: {k: 1}}).fetch().map(doc => doc._id), - ['x', 'y']); - - const operations = []; - const cbs = log_callbacks(operations); - const handle = coll.find({'a.b': {$near: [7, 7]}}).observe(cbs); - - test.length(operations, 2); - test.equal(operations.shift(), ['added', {k: 9, a: {b: [5, 5]}}, 0, null]); - test.equal(operations.shift(), - ['added', {k: 9, a: [{b: [[100, 100], [1, 1]]}, {b: [150, 150]}]}, - 1, null]); - // This needs to be inserted in the MIDDLE of the two existing ones. - coll.insert({a: {b: [3, 3]}}); - test.length(operations, 1); - test.equal(operations.shift(), ['added', {a: {b: [3, 3]}}, 1, 'x']); - - handle.stop(); -}); - -// issue #2077 -Tinytest.addAsync('async - minimongo - $near and $geometry for legacy coordinates', async test => { - const coll = new LocalCollection(); - - coll.insert({ - loc: { - x: 1, - y: 1, - }, - }); - coll.insert({ - loc: [-1, -1], - }); - coll.insert({ - loc: [40, -10], - }); - coll.insert({ - loc: { - x: -10, - y: 40, - }, - }); - - test.equal(coll.find({ loc: { $near: [0, 0], $maxDistance: 4 } }).count(), 2); - test.equal(coll.find({ loc: { $near: {$geometry: {type: 'Point', coordinates: [0, 0]}}} }).count(), 4); - test.equal(coll.find({ loc: { $near: {$geometry: {type: 'Point', coordinates: [0, 0]}, $maxDistance: 200000}}}).count(), 2); -}); - -// Regression test for #4377. Previously, "replace" updates didn't clone the -// argument. -Tinytest.addAsync('async - minimongo - update should clone', async test => { - const x = []; - const coll = new LocalCollection; - const id = coll.insert({}); - coll.updateAsync(id, {x}); - x.push(1); - test.equal(coll.findOne(id), {_id: id, x: []}); -}); - -// See #2275. -Tinytest.addAsync('async - minimongo - fetch in observe', async test => { - const coll = new LocalCollection; - let callbackInvoked = false; - const observe = coll.find().observeChanges({ - added(id, fields) { - callbackInvoked = true; - test.equal(fields, {foo: 1}); - const doc = coll.findOne({foo: 1}); - test.isTrue(doc); - test.equal(doc.foo, 1); - }, - }); - test.isFalse(callbackInvoked); - const computation = Tracker.autorun(computation => { - if (computation.firstRun) { - coll.insert({foo: 1}); - } - }); - test.isTrue(callbackInvoked); - observe.stop(); - computation.stop(); -}); - -// See #2254 -Tinytest.addAsync('async - minimongo - fine-grained reactivity of observe with fields projection', async test => { - const X = new LocalCollection; - const id = 'asdf'; - X.insert({_id: id, foo: {bar: 123}}); - - let callbackInvoked = false; - const obs = X.find(id, {fields: {'foo.bar': 1}}).observeChanges({ - changed(id, fields) { - callbackInvoked = true; - }, - }); - - test.isFalse(callbackInvoked); - X.updateAsync(id, {$set: {'foo.baz': 456}}); - test.isFalse(callbackInvoked); - - obs.stop(); -}); -Tinytest.addAsync('async - minimongo - fine-grained reactivity of query with fields projection', async test => { - const X = new LocalCollection; - const id = 'asdf'; - X.insert({_id: id, foo: {bar: 123}}); - - let callbackInvoked = false; - const computation = Tracker.autorun(() => { - callbackInvoked = true; - return X.findOne(id, { fields: { 'foo.bar': 1 } }); - }); - test.isTrue(callbackInvoked); - callbackInvoked = false; - X.updateAsync(id, {$set: {'foo.baz': 456}}); - test.isFalse(callbackInvoked); - X.updateAsync(id, {$set: {'foo.bar': 124}}); - Tracker.flush(); - test.isTrue(callbackInvoked); - - computation.stop(); -}); - -// Tests that the logic in `LocalCollection.prototype.update` -// correctly deals with count() on a cursor with skip or limit (since -// then the result set is an IdMap, not an array) -Tinytest.addAsync('async - minimongo - reactive skip/limit count while updating', async test => { - const X = new LocalCollection; - let count = -1; - - const c = Tracker.autorun(() => { - count = X.find({}, {skip: 1, limit: 1}).count(); - }); - - test.equal(count, 0); - - X.insert({}); - Tracker.flush({_throwFirstError: true}); - test.equal(count, 0); - - X.insert({}); - Tracker.flush({_throwFirstError: true}); - test.equal(count, 1); - - X.updateAsync({}, {$set: {foo: 1}}); - Tracker.flush({_throwFirstError: true}); - test.equal(count, 1); - - // Make sure a second update also works - X.updateAsync({}, {$set: {foo: 2}}); - Tracker.flush({_throwFirstError: true}); - test.equal(count, 1); - - c.stop(); -}); - -// Makes sure inserts cannot be performed using field names that have -// Mongo restricted characters in them ('.', '$', '\0'): -// https://docs.mongodb.com/manual/reference/limits/#Restrictions-on-Field-Names -Tinytest.addAsync('async - minimongo - cannot insert using invalid field names', async test => { - const collection = new LocalCollection(); - - // Quick test to make sure non-dot field inserts are working - await collection.insertAsync({ a: 'b' }); - - // Quick test to make sure field values with dots are allowed - await collection.insertAsync({ a: 'b.c' }); - - // Verify top level dot-field inserts are prohibited - ['a.b', '.b', 'a.', 'a.b.c'].forEach(async (field) => { - await test.throwsAsync(async () => { - await collection.insertAsync({ [field]: 'c' }); - }, `Key ${field} must not contain '.'`); - }); - - // Verify nested dot-field inserts are prohibited - await test.throwsAsync(async () => { - await collection.insertAsync({ a: { b: { 'c.d': 'e' } } }); - }, "Key c.d must not contain '.'"); - - // Verify field names starting with $ are prohibited - await test.throwsAsync(async () => { - await collection.insertAsync({ $a: 'b' }); - }, "Key $a must not start with '$'"); - - // Verify nested field names starting with $ are prohibited - await test.throwsAsync(async () => { - await collection.insert({ a: { b: { $c: 'd' } } }); - }, "Key $c must not start with '$'"); - - // Verify top level fields with null characters are prohibited - ['\0a', 'a\0', 'a\0b', '\u0000a', 'a\u0000', 'a\u0000b'].forEach(async (field) => { - await test.throwsAsync(async () => { - await collection.insert({ [field]: 'c' }); - }, `Key ${field} must not contain null bytes`); - }); - - // Verify nested field names with null characters are prohibited - await test.throwsAsync(async () => { - await collection.insert({ a: { b: { '\0c': 'd' } } }); - }, 'Key \0c must not contain null bytes'); -}); - -// Makes sure $set's cannot be performed using null bytes -// https://docs.mongodb.com/manual/reference/limits/#Restrictions-on-Field-Names -Tinytest.addAsync('async - minimongo - cannot $set with null bytes', async test => { - const collection = new LocalCollection(); - - // Quick test to make sure non-null byte $set's are working - const id = await collection.insertAsync({ a: 'b', c: 'd' }); - await collection.updateAsync({ _id: id }, { $set: { e: 'f' } }); - - // Verify $set's with null bytes throw an exception - await test.throwsAsync(async () => { - await collection.updateAsync({ _id: id }, { $set: { '\0a': 'b' } }); - }, 'Key \0a must not contain null bytes'); -}); - -// Makes sure $rename's cannot be performed using null bytes -// https://docs.mongodb.com/manual/reference/limits/#Restrictions-on-Field-Names -Tinytest.addAsync('async - minimongo - cannot $rename with null bytes', async test => { - const collection = new LocalCollection(); - - // Quick test to make sure non-null byte $rename's are working - let id = await collection.insertAsync({ a: 'b', c: 'd' }); - await collection.updateAsync({ _id: id }, { $rename: { a: 'a1', c: 'c1' } }); - - // Verify $rename's with null bytes throw an exception - await collection.removeAsync({}); - id = await collection.insertAsync({ a: 'b', c: 'd' }); - await test.throwsAsync(async () => { - await collection.updateAsync({ _id: id }, { $rename: { a: '\0a', c: 'c\0' } }); - }, "The 'to' field for $rename cannot contain an embedded null byte"); -}); diff --git a/packages/minimongo/package.js b/packages/minimongo/package.js index 0761dd75fc..358939e1e9 100644 --- a/packages/minimongo/package.js +++ b/packages/minimongo/package.js @@ -49,5 +49,4 @@ Package.onTest(api => { api.addFiles('minimongo_tests.js'); api.addFiles('minimongo_tests_client.js', 'client'); api.addFiles('minimongo_tests_server.js', 'server'); - api.addFiles('minimongo_tests_client_async.js', 'client'); }); From 3d3bb13198414a21eed679e099bc8fce66cbcb2b Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Mon, 27 Mar 2023 11:14:05 -0300 Subject: [PATCH 08/14] tests: removed await from observe ordered with projection --- packages/minimongo/minimongo_tests_client.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/minimongo/minimongo_tests_client.js b/packages/minimongo/minimongo_tests_client.js index 9193f59efd..c31c22e1cd 100644 --- a/packages/minimongo/minimongo_tests_client.js +++ b/packages/minimongo/minimongo_tests_client.js @@ -1867,7 +1867,7 @@ Tinytest.addAsync('minimongo - observe ordered with projection', async test => { let handle; const c = new LocalCollection(); - handle = await c.find({}, {sort: {a: 1}, fields: { a: 1 }}).observe(cbs); + handle = c.find({}, {sort: {a: 1}, fields: { a: 1 }}).observe(cbs); test.isTrue(handle.collection === c); await c.insertAsync({_id: 'foo', a: 1, b: 2}); @@ -1896,20 +1896,20 @@ Tinytest.addAsync('minimongo - observe ordered with projection', async test => { const cursor = c.find({}, {fields: {a: 1, _id: 0}}); test.throws(() => { - cursor.observeChanges({added() {}}); + cursor.observeChanges({ added() {} }); }); - await test.throwsAsync(async () => { - await cursor.observe({added() {}}); + test.throws(() => { + cursor.observe({ added() {} }); }); // test initial inserts (and backwards sort) - handle = await c.find({}, {sort: {a: -1}, fields: { a: 1 } }).observe(cbs); + handle = c.find({}, {sort: {a: -1}, fields: { a: 1 } }).observe(cbs); test.equal(operations.shift(), ['added', {a: 2}, 0, null]); test.equal(operations.shift(), ['added', {a: 1}, 1, null]); handle.stop(); // test _suppress_initial - handle = await c.find({}, {sort: {a: -1}, fields: { a: 1 }}).observe(Object.assign(cbs, {_suppress_initial: true})); + handle = c.find({}, {sort: {a: -1}, fields: { a: 1 }}).observe(Object.assign(cbs, {_suppress_initial: true})); test.equal(operations.shift(), undefined); await c.insertAsync({a: 100, b: { foo: 'bar' }}); test.equal(operations.shift(), ['added', {a: 100}, 0, idA2]); @@ -1917,7 +1917,7 @@ Tinytest.addAsync('minimongo - observe ordered with projection', async test => { // test skip and limit. await c.removeAsync({}); - handle = await c.find({}, {sort: {a: 1}, skip: 1, limit: 2, fields: { blacklisted: 0 }}).observe(cbs); + handle = c.find({}, {sort: {a: 1}, skip: 1, limit: 2, fields: { blacklisted: 0 }}).observe(cbs); test.equal(operations.shift(), undefined); await c.insertAsync({a: 1, blacklisted: 1324}); test.equal(operations.shift(), undefined); @@ -1939,7 +1939,7 @@ Tinytest.addAsync('minimongo - observe ordered with projection', async test => { // test _no_indices await c.removeAsync({}); - handle = await c.find({}, {sort: {a: 1}, fields: { a: 1 }}).observe(Object.assign(cbs, {_no_indices: true})); + handle = c.find({}, {sort: {a: 1}, fields: { a: 1 }}).observe(Object.assign(cbs, {_no_indices: true})); await c.insertAsync({_id: 'foo', a: 1, zoo: 'crazy'}); test.equal(operations.shift(), ['added', {a: 1}, -1, null]); await c.updateAsync({a: 1}, {$set: {a: 2, foobar: 'player'}}); From 5f417bf703c4167ea42d9e7cc030112cc0cd3bea Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Mon, 27 Mar 2023 11:15:25 -0300 Subject: [PATCH 09/14] tests: removed async from observe ordered --- packages/minimongo/minimongo_tests_client.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/minimongo/minimongo_tests_client.js b/packages/minimongo/minimongo_tests_client.js index c31c22e1cd..95403346b5 100644 --- a/packages/minimongo/minimongo_tests_client.js +++ b/packages/minimongo/minimongo_tests_client.js @@ -3108,7 +3108,7 @@ Tinytest.addAsync('minimongo - observe ordered', async test => { let handle; const c = new LocalCollection(); - handle = await c.find({}, {sort: {a: 1}}).observe(cbs); + handle = c.find({}, {sort: {a: 1}}).observe(cbs); test.isTrue(handle.collection === c); await c.insertAsync({_id: 'foo', a: 1}); @@ -3135,14 +3135,20 @@ Tinytest.addAsync('minimongo - observe ordered', async test => { test.equal(operations.shift(), undefined); // test initial inserts (and backwards sort) - handle = await c.find({}, {sort: {a: -1}}).observe(cbs); + handle = c.find({}, {sort: {a: -1}}).observe(cbs); test.equal(operations.shift(), ['added', {a: 2}, 0, null]); test.equal(operations.shift(), ['added', {a: 1}, 1, null]); handle.stop(); // test _suppress_initial - handle = await c.find({}, {sort: {a: -1}}).observe(Object.assign({ - _suppress_initial: true}, cbs)); + handle = c.find({}, { sort: { a: -1 } }).observe( + Object.assign( + { + _suppress_initial: true, + }, + cbs + ) + ); test.equal(operations.shift(), undefined); await c.insertAsync({a: 100}); test.equal(operations.shift(), ['added', {a: 100}, 0, idA2]); @@ -3150,7 +3156,7 @@ Tinytest.addAsync('minimongo - observe ordered', async test => { // test skip and limit. await c.removeAsync({}); - handle = await c.find({}, {sort: {a: 1}, skip: 1, limit: 2}).observe(cbs); + handle = c.find({}, { sort: { a: 1 }, skip: 1, limit: 2 }).observe(cbs); test.equal(operations.shift(), undefined); await c.insertAsync({a: 1}); test.equal(operations.shift(), undefined); @@ -3174,7 +3180,7 @@ Tinytest.addAsync('minimongo - observe ordered', async test => { await c.insertAsync({a: 1}); await c.insertAsync({_id: 'two', a: 2}); await c.insertAsync({a: 3}); - handle = await c.find({}, {sort: {a: 1}, limit: 2}).observe(cbs); + handle = c.find({}, { sort: { a: 1 }, limit: 2 }).observe(cbs); test.equal(operations.shift(), ['added', {a: 1}, 0, null]); test.equal(operations.shift(), ['added', {a: 2}, 1, null]); test.equal(operations.shift(), undefined); From 6965f6f605793a26745b3be6e28fed6dc2d02290 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Mon, 27 Mar 2023 11:16:03 -0300 Subject: [PATCH 10/14] tests: removed missing observe with await --- packages/minimongo/minimongo_tests_client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/minimongo/minimongo_tests_client.js b/packages/minimongo/minimongo_tests_client.js index 95403346b5..1c1d373d96 100644 --- a/packages/minimongo/minimongo_tests_client.js +++ b/packages/minimongo/minimongo_tests_client.js @@ -3193,7 +3193,7 @@ Tinytest.addAsync('minimongo - observe ordered', async test => { // test _no_indices await c.removeAsync({}); - handle = await c.find({}, {sort: {a: 1}}).observe(Object.assign(cbs, {_no_indices: true})); + handle = c.find({}, {sort: {a: 1}}).observe(Object.assign(cbs, {_no_indices: true})); await c.insertAsync({_id: 'foo', a: 1}); test.equal(operations.shift(), ['added', {a: 1}, -1, null]); await c.updateAsync({a: 1}, {$set: {a: 2}}); From 1ace7e1da9234d557d1a8cbc8d8425315fcee1dd Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Mon, 27 Mar 2023 11:16:57 -0300 Subject: [PATCH 11/14] tests: removed await from observe ordered false/true --- packages/minimongo/minimongo_tests_client.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/minimongo/minimongo_tests_client.js b/packages/minimongo/minimongo_tests_client.js index 1c1d373d96..668cfc7d83 100644 --- a/packages/minimongo/minimongo_tests_client.js +++ b/packages/minimongo/minimongo_tests_client.js @@ -3252,7 +3252,7 @@ Tinytest.addAsync('minimongo - observe ordered', async test => { // This should work equally well for ordered and unordered observations // (because the callbacks don't look at indices and there's no 'moved' // callback). - let handle = await c.find({ tags: "flower" }).observe(makecb("a")); + let handle = c.find({ tags: "flower" }).observe(makecb("a")); expect("aa3_"); await c.updateAsync( { name: "rose" }, @@ -3276,14 +3276,14 @@ Tinytest.addAsync('minimongo - observe ordered', async test => { expect(""); // Test that observing a lookup by ID works. - handle = await c.find(4).observe(makecb("b")); + handle = c.find(4).observe(makecb("b")); expect("ab4_"); await c.updateAsync(4, { $set: { eek: 5 } }); expect("cb4_"); handle.stop(); // Test observe with reactive: false. - handle = await c + handle = c .find({ tags: "flower" }, { reactive: false }) .observe(makecb("c")); // TODO: think about this one below. From c4e768f315a0365c19f4788dff1d92591398b50a Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Mon, 27 Mar 2023 11:19:08 -0300 Subject: [PATCH 12/14] tests: removed not needed await from in pause test --- packages/minimongo/minimongo_tests_client.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/minimongo/minimongo_tests_client.js b/packages/minimongo/minimongo_tests_client.js index 668cfc7d83..80e238d5f8 100644 --- a/packages/minimongo/minimongo_tests_client.js +++ b/packages/minimongo/minimongo_tests_client.js @@ -3394,7 +3394,7 @@ Tinytest.addAsync('minimongo - pause', async test => { const cbs = log_callbacks(operations); const c = new LocalCollection(); - const h = await c.find({}).observe(cbs); + const h = c.find({}).observe(cbs); // remove and add cancel out. await c.insertAsync({_id: 1, a: 1}); @@ -3407,7 +3407,7 @@ Tinytest.addAsync('minimongo - pause', async test => { await c.insertAsync({_id: 1, a: 1}); test.length(operations, 0); - await c.resumeObserversClient(); + c.resumeObserversClient(); test.length(operations, 0); @@ -3417,7 +3417,7 @@ Tinytest.addAsync('minimongo - pause', async test => { await c.updateAsync({_id: 1}, {a: 2}); await c.updateAsync({_id: 1}, {a: 3}); - await c.resumeObserversClient(); + c.resumeObserversClient(); test.equal(operations.shift(), ['changed', {a: 3}, 0, {a: 1}]); test.length(operations, 0); @@ -3425,7 +3425,7 @@ Tinytest.addAsync('minimongo - pause', async test => { c.pauseObservers(); test.equal(await c.removeAsync({}), 1); test.length(operations, 0); - await c.resumeObserversClient(); + c.resumeObserversClient(); test.equal(operations.shift(), ['removed', 1, 0, {a: 3}]); test.length(operations, 0); From fa728aea445c711223baa64fe10c506bcdb7dfeb Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Mon, 27 Mar 2023 11:23:10 -0300 Subject: [PATCH 13/14] test: solved $near operator tests --- packages/minimongo/minimongo_tests_client.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/minimongo/minimongo_tests_client.js b/packages/minimongo/minimongo_tests_client.js index 80e238d5f8..9ea65c0555 100644 --- a/packages/minimongo/minimongo_tests_client.js +++ b/packages/minimongo/minimongo_tests_client.js @@ -3585,8 +3585,8 @@ Tinytest.addAsync('minimongo - $near operator tests', async test => { await coll.insertAsync({ rest: { loc: [-3, 3] } }); await coll.insertAsync({ rest: { loc: [5, 5] } }); - test.equal(coll.find({ 'rest.loc': { $near: [0, 0], $maxDistance: 30 } }).count(), 3); - test.equal(coll.find({ 'rest.loc': { $near: [0, 0], $maxDistance: 4 } }).count(), 1); + test.equal(await coll.find({ 'rest.loc': { $near: [0, 0], $maxDistance: 30 } }).count(), 3); + test.equal(await coll.find({ 'rest.loc': { $near: [0, 0], $maxDistance: 4 } }).count(), 1); const points = await coll.find({ 'rest.loc': { $near: [0, 0], $maxDistance: 6 } }).fetchAsync(); points.forEach((point, i, points) => { test.isTrue(!i || distance([0, 0], point.rest.loc) >= distance([0, 0], points[i - 1].rest.loc)); @@ -3722,7 +3722,7 @@ Tinytest.addAsync('minimongo - $near operator tests', async test => { const operations = []; const cbs = log_callbacks(operations); - const handle = await coll.find({'a.b': {$near: [7, 7]}}).observe(cbs); + const handle = coll.find({'a.b': {$near: [7, 7]}}).observe(cbs); test.length(operations, 2); test.equal(operations.shift(), ['added', {k: 9, a: {b: [5, 5]}}, 0, null]); From 16e82fda23ebf64b21ba561ebd236375d52fbb03 Mon Sep 17 00:00:00 2001 From: Gabriel Grubba Date: Mon, 27 Mar 2023 11:24:52 -0300 Subject: [PATCH 14/14] tests: fetch in observe added await to test --- packages/minimongo/minimongo_tests_client.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/minimongo/minimongo_tests_client.js b/packages/minimongo/minimongo_tests_client.js index 9ea65c0555..cf7135c0b2 100644 --- a/packages/minimongo/minimongo_tests_client.js +++ b/packages/minimongo/minimongo_tests_client.js @@ -3781,10 +3781,10 @@ Tinytest.add('minimongo - fetch in observe', test => { const coll = new LocalCollection; let callbackInvoked = false; const observe = coll.find().observeChanges({ - added(id, fields) { + async added(id, fields) { callbackInvoked = true; - test.equal(fields, {foo: 1}); - const doc = coll.findOne({foo: 1}); + test.equal(fields, { foo: 1 }); + const doc = await coll.findOne({ foo: 1 }); test.isTrue(doc); test.equal(doc.foo, 1); },