diff --git a/meetings/2023-10-24.md b/meetings/2023-10-24.md new file mode 100644 index 0000000000..b8822d054e --- /dev/null +++ b/meetings/2023-10-24.md @@ -0,0 +1,277 @@ + +## Oct 24th, 2023 + +### FLIPs + +#### 134: Relax interface conformance restrictions + +* FLIP: [https://github.com/onflow/flips/pull/134](https://github.com/onflow/flips/pull/134) + +* Overview: + + * Follow up on interface conformance improvements ([https://github.com/onflow/flips/pull/83](https://github.com/onflow/flips/pull/83)). + + * Proposes to allow empty function declaration defined in one interface to coexist with a default function implementation defined in another interface. + + * Currently the same is allowed if the empty declaration has a pre/post condition. + + * When interface default functions were introduced, interface inheritance did not exist yet + + * Current behavior was intentional, tried to avoid interface author breaking implementations by adding function implementation (default function) + +* Status: + + * FLIP is waiting for a final decision + + * Reference implementation is complete: [https://github.com/onflow/cadence/pull/2725](https://github.com/onflow/cadence/pull/2725) + +* Next steps: + + * Would like to get more feedback + + * Provide means / explanation to try out + +* Notes: + + * Accepted + +#### 210: Improvement to entitlement mapping syntax + +* FLIP: [https://github.com/onflow/flips/pull/210](https://github.com/onflow/flips/pull/210) + +* Overview: + + * Got some feedback that visually entitlements and entitlement mappings appear too similar when used in an `access` modifier. This can be confusing to developers because the former cannot be accessed on an unentitled reference, while the latter can be (and produces an unentitled output) + + * Proposed needing a `mapping` keyword in access modifiers: e.g. `access(mapping M)` + +* Status: + + * FLIP proposed, has general approval + +* Next Steps: + + * Accept FLIP, merge implementation? + +* Notes: + + * Approved + +#### 196: Restrict Capabilities Publish + +* FLIP: [https://github.com/onflow/flips/pull/197](https://github.com/onflow/flips/pull/197) + +* Overview: + + * Current Cap Cons API allows publishing capabilities of another account + + * Was not possible with linking API + + * Could lead to confusion for developers (e.g. query balance, but balance is from another account) + +* Status: + + * Ready for vote + +* Next Steps: + +* Notes: + + * Approved + +#### 212: Reject references to references + +* FLIP: [https://github.com/onflow/flips/pull/212](https://github.com/onflow/flips/pull/212) + +* Overview: + + * It is currently possible to create references to references, e.g. &&T + + * Such references are not useful + + * In Cadence 1.0, additional work is requires to keep them working + + * Proposal is to forbid them + +* Status: + + * Ready for vote + +* Next Steps: + +* Notes: + + * Approved + +#### 131: Remove custom destructors + +* FLIP: [https://github.com/onflow/flips/pull/131](https://github.com/onflow/flips/pull/131) + +* Overview: + + * Proposal to address inability for users to destroy resources they own + + * One of the discussed options (others: try/catch, etc.) + + * Originated from attachments feature (attachment might prevent destruction of whole resource) + + * Remove destroy + + * Allows users to always destroy resources + +* Status: + + * Updated FLIP with default events + + * Discovered that introduction of attachments would require additional code in e.g. Vault.deposit to prevent exploit + + * FLIP ready for another round of discussion + +* Open problems: + + * Philosophical question (sending to "burner account") + + * Existing code / applications + + * "Migration" path for use-cases like FT total supply + + * Tombstoning implementation + +* Next steps: + + * Need to discuss implementation approach more + + * Implementation is not blocking Stable Cadence release, but can vote on change itself, removal of custom destructors + + * Do not need a solution for "large resource deletion" problem + + * Breakout session next week, after giving time to read through updated proposal + +* Feedback: + + * Non-mutable contraction mainnet using custom destructor + + * Overhead creating workaround + + * Will USDC implement a workaround ? + +* Notes: + + * Approved + +#### 95: Entitlements migration + +* FLIP: [https://github.com/onflow/flips/pull/95](https://github.com/onflow/flips/pull/95) + +* Overview: + +* Status: + +* Next Steps: + +#### 179: Staged Contract Updates + +* FLIP: [https://github.com/onflow/flips/pull/179](https://github.com/onflow/flips/pull/179) + +* Overview: + + * Contract mechanism to define contract update deployments and execute updates in stages at/beyond a block height. Execution can also be delegated to a third party via Capabilities + +* Status: + + * Proposed & approved by Jerome & Josh + + * Was hoping for community approval on the FLIP before moving to approval, but only feedback provided so far + +* Next Steps: + + * Approve unless recent feedback is opposed + + * Merge tryUpdate() to finalize v0 implementation & build out tests + + * Design automated update solution so delegated updates can be executed immediately post-spork + + * Begin to address callouts around: + + * Creating update configuration + + * Emulating configured updates + + * Monitoring update status + +### Other + +#### Discuss changes to attachments + +* Overview + + * Problem: + + * Attachments are able to declare what entitlements they need, to perform operations on base + + * A *third-party* might prepare a value with an attachment. With the transfer of the value, also the attachment and thus the permissions on the base, are transferred + + * The receiver might not realize + + * Reference to base stays "alive" beyond TX/script + + * Running example: + + * Currency converter on vault, can deposit and withdraw + + * Proposal: + + * Remove support for requirement of entitlements + + * Only allow public access to begin with + + * Later: Add support for entitled access, + + * e.g. through + + * Entitlement mapping + + * `access(M) attachment A for S {}` + + * Privilege escalation through mapping? + E.g. Deposit → Withdraw + + * ```cadence + mapping M { + X -> Y + } + + access(Y) fun foo() { + // can use X on base + } + ``` + + * Maybe hardcode to Identity mapping? + + * `access(X) fun foo() { … }` + + * no mapping + + * Requirements on per-function level (instead of whole attachment) + + * Do not want to require splitting attachments into parts + + * Alternative: Sanitization + + * Doesn’t scale, too easy to forget, footgun ("malicious USB stick") + +* Status: + + * Decide if this / what should be proposed in a FLIP + +* Next steps: + + * Propose FLIP for + + * Requirement removal + + * Propose unentitled access to start with + + * Can add entitled access later (see above) + + * Examples for proposals which allow entitlements diff --git a/npm-packages/cadence-parser/package-lock.json b/npm-packages/cadence-parser/package-lock.json new file mode 100644 index 0000000000..63ff9bc3ea --- /dev/null +++ b/npm-packages/cadence-parser/package-lock.json @@ -0,0 +1,3822 @@ +{ + "name": "@onflow/cadence-parser", + "version": "0.41.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@onflow/cadence-parser", + "version": "0.41.1", + "license": "Apache-2.0", + "dependencies": { + "get-random-values": "^2.0.0" + }, + "devDependencies": { + "@types/jest": "^28.1.4", + "@types/node": "^18.0.3", + "esbuild": "0.19.4", + "jest": "^28.1.2", + "node-fetch": "^2.6.1", + "ts-jest": "^28.0.5", + "typescript": "^4.7.4" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/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==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/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==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/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==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.20.tgz", + "integrity": "sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.0.tgz", + "integrity": "sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helpers": "^7.23.0", + "@babel/parser": "^7.23.0", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.0", + "@babel/types": "^7.23.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@babel/generator": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", + "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", + "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", + "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", + "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.1.tgz", + "integrity": "sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.0", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/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==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/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==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/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==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", + "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.0.tgz", + "integrity": "sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.4.tgz", + "integrity": "sha512-Lviw8EzxsVQKpbS+rSt6/6zjn9ashUZ7Tbuvc2YENgRl0yZTktGlachZ9KMJUsVjZEGFVu336kl5lBgDN6PmpA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/core": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz", + "integrity": "sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==", + "dev": true, + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/reporters": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^28.1.3", + "jest-config": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-resolve-dependencies": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "jest-watcher": "^28.1.3", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "jest-mock": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==", + "dev": true, + "dependencies": { + "expect": "^28.1.3", + "jest-snapshot": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", + "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", + "dev": true, + "dependencies": { + "jest-get-type": "^28.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", + "@types/node": "*", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz", + "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==", + "dev": true, + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/types": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz", + "integrity": "sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.24.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "28.1.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz", + "integrity": "sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.13", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", + "dev": true, + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz", + "integrity": "sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^28.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz", + "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.3", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/types": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@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==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", + "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.2.tgz", + "integrity": "sha512-pNpr1T1xLUc2l3xJKuPtsEky3ybxN3m4fJkknfIpTCTfIZCDW57oAg+EfCgIIp2rvCe0Wn++/FfodDS4YXxBwA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.5", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.5.tgz", + "integrity": "sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.2.tgz", + "integrity": "sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.2.tgz", + "integrity": "sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.7.tgz", + "integrity": "sha512-MhzcwU8aUygZroVwL2jeYk6JisJrPl/oov/gsgGCue9mkgl9wjGbzReYQClxiUgFDnib9FuHqTndccKeZKxTRw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-gPQuzaPR5h/djlAv2apEG1HVOyj1IUs7GpfMZixU0/0KXT3pm64ylHuMUI1/Akh+sq/iikxg6Z2j+fcMDXaaTQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-kv43F9eb3Lhj+lr/Hn6OcLCs/sSM8bt+fIaP11rCYngfV6NVjzWXJ17owQtDQTL9tQ8WSLUrGsSJ6rJz0F1w1A==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "28.1.8", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-28.1.8.tgz", + "integrity": "sha512-8TJkV++s7B6XqnDrzR1m/TT0A0h948Pnl/097veySPN67VRAgQ4gZ7n2KfJo2rVq6njQjdxU3GCCyDvAeuHoiw==", + "dev": true, + "dependencies": { + "expect": "^28.0.0", + "pretty-format": "^28.0.0" + } + }, + "node_modules/@types/node": { + "version": "18.18.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.3.tgz", + "integrity": "sha512-0OVfGupTl3NBFr8+iXpfZ8NR7jfFO+P1Q+IO/q0wbo02wYkP5gy36phojeYWpLQ6WAMjl+VfmqUk2YbUfp0irA==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", + "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==", + "dev": true + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.26", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.26.tgz", + "integrity": "sha512-Y3vDy2X6zw/ZCumcwLpdhM5L7jmyGpmBCTYMHDLqT2IKVMYRRLdv6ZakA+wxhra6Z/3bwhNbNl9bDGXaFU+6rw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-axdPBuLuEJt0c4yI5OZssC19K2Mq1uKdrfZBzuxLvaztgqUtFYZUNw7lETExPYJR9jdEoIg4mb7RQKRQzOkeGQ==", + "dev": true + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/babel-jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", + "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==", + "dev": true, + "dependencies": { + "@jest/transform": "^28.1.3", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^28.1.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz", + "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz", + "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^28.1.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", + "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001546", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001546.tgz", + "integrity": "sha512-zvtSJwuQFpewSyRrI3AsftF6rM0X80mZkChIt1spBGEvRglCrjTniXvinc8JKRoqTwXAgvqTImaN9igfSMtUBw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", + "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==", + "dev": true + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/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==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", + "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.542", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.542.tgz", + "integrity": "sha512-6+cpa00G09N3sfh2joln4VUXHquWrOFx3FLZqiVQvl45+zS9DskDBTPvob+BhvFRmTBkyDSk0vvLMMRo/qc6mQ==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/esbuild": { + "version": "0.19.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.4.tgz", + "integrity": "sha512-x7jL0tbRRpv4QUyuDMjONtWFciygUxWaUM1kMX2zWxI0X2YWOt7MSA0g4UdeSiHM8fcYVzpQhKYOycZwxTdZkA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.19.4", + "@esbuild/android-arm64": "0.19.4", + "@esbuild/android-x64": "0.19.4", + "@esbuild/darwin-arm64": "0.19.4", + "@esbuild/darwin-x64": "0.19.4", + "@esbuild/freebsd-arm64": "0.19.4", + "@esbuild/freebsd-x64": "0.19.4", + "@esbuild/linux-arm": "0.19.4", + "@esbuild/linux-arm64": "0.19.4", + "@esbuild/linux-ia32": "0.19.4", + "@esbuild/linux-loong64": "0.19.4", + "@esbuild/linux-mips64el": "0.19.4", + "@esbuild/linux-ppc64": "0.19.4", + "@esbuild/linux-riscv64": "0.19.4", + "@esbuild/linux-s390x": "0.19.4", + "@esbuild/linux-x64": "0.19.4", + "@esbuild/netbsd-x64": "0.19.4", + "@esbuild/openbsd-x64": "0.19.4", + "@esbuild/sunos-x64": "0.19.4", + "@esbuild/win32-arm64": "0.19.4", + "@esbuild/win32-ia32": "0.19.4", + "@esbuild/win32-x64": "0.19.4" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/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==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/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==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-random-values": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/get-random-values/-/get-random-values-2.1.0.tgz", + "integrity": "sha512-q2yOLpLyA8f9unfv2LV8KVRUFeOIrQVS5cnqpbv6N+ea9j1rmW5dFKj/2Q7CK3juEfDYQgPxGt941VJcmw0jKg==", + "dependencies": { + "global": "^4.4.0" + }, + "engines": { + "node": "14 || 16 || >=18" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz", + "integrity": "sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz", + "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==", + "dev": true, + "dependencies": { + "@jest/core": "^28.1.3", + "@jest/types": "^28.1.3", + "import-local": "^3.0.2", + "jest-cli": "^28.1.3" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz", + "integrity": "sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-circus": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz", + "integrity": "sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==", + "dev": true, + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "p-limit": "^3.1.0", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-cli": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz", + "integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==", + "dev": true, + "dependencies": { + "@jest/core": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz", + "integrity": "sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^28.1.3", + "@jest/types": "^28.1.3", + "babel-jest": "^28.1.3", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^28.1.3", + "jest-environment-node": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^28.1.1", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz", + "integrity": "sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-each": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz", + "integrity": "sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "jest-util": "^28.1.3", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz", + "integrity": "sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==", + "dev": true, + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz", + "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz", + "integrity": "sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==", + "dev": true, + "dependencies": { + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", + "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-mock": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz", + "integrity": "sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz", + "integrity": "sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==", + "dev": true, + "dependencies": { + "jest-regex-util": "^28.0.2", + "jest-snapshot": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-runner": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz", + "integrity": "sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==", + "dev": true, + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/environment": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "graceful-fs": "^4.2.9", + "jest-docblock": "^28.1.1", + "jest-environment-node": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-leak-detector": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-resolve": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-util": "^28.1.3", + "jest-watcher": "^28.1.3", + "jest-worker": "^28.1.3", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz", + "integrity": "sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==", + "dev": true, + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/globals": "^28.1.3", + "@jest/source-map": "^28.1.2", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz", + "integrity": "sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^28.1.3", + "graceful-fs": "^4.2.9", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-haste-map": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "natural-compare": "^1.4.0", + "pretty-format": "^28.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/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==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/jest-util": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-validate": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz", + "integrity": "sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "leven": "^3.1.0", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", + "dev": true, + "dependencies": { + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.3", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-worker": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/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==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", + "dependencies": { + "dom-walk": "^0.1.0" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", + "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/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==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", + "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", + "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/ts-jest": { + "version": "28.0.8", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.8.tgz", + "integrity": "sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^28.0.0", + "json5": "^2.2.1", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^28.0.0", + "babel-jest": "^28.0.0", + "jest": "^28.0.0", + "typescript": ">=4.3" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/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==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz", + "integrity": "sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/npm-packages/cadence-parser/package.json b/npm-packages/cadence-parser/package.json index e3c4b8f8ea..1ffb0dc10b 100644 --- a/npm-packages/cadence-parser/package.json +++ b/npm-packages/cadence-parser/package.json @@ -8,19 +8,19 @@ "url": "https://github.com/onflow/cadence.git" }, "main": "./dist/cjs/index.js", - "module": "./dist/esm/index.js", + "module": "./dist/esm/index.mjs", "types": "./dist/types/index.d.ts", "exports": { ".": { "require": "./dist/cjs/index.js", - "import": "./dist/esm/index.js", + "import": "./dist/esm/index.mjs", "types": "./dist/types/index.d.ts" } }, "scripts": { "build": "npm run build:types && npm run build:esm && npm run build:cjs && GOARCH=wasm GOOS=js go build -o ./dist/cadence-parser.wasm ../../runtime/cmd/parse", "build:types": "tsc --emitDeclarationOnly --module system --outDir dist/types", - "build:esm": "tsc --module es6 --target es6 --outDir dist/esm --declaration false", + "build:esm": "esbuild src/index.ts --bundle --sourcemap --format=esm --outfile=dist/esm/index.mjs", "build:cjs": "tsc --module commonjs --target es6 --outDir dist/cjs --declaration false", "test": "jest" }, @@ -28,6 +28,7 @@ "devDependencies": { "@types/jest": "^28.1.4", "@types/node": "^18.0.3", + "esbuild": "0.19.4", "jest": "^28.1.2", "node-fetch": "^2.6.1", "ts-jest": "^28.0.5", diff --git a/runtime/cmd/cmd.go b/runtime/cmd/cmd.go index 80f808594b..6bb61b86b8 100644 --- a/runtime/cmd/cmd.go +++ b/runtime/cmd/cmd.go @@ -88,8 +88,10 @@ func DefaultCheckerConfig( } return &sema.Config{ - BaseValueActivation: baseValueActivation, - AccessCheckMode: sema.AccessCheckModeStrict, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AccessCheckMode: sema.AccessCheckModeStrict, ImportHandler: func( checker *sema.Checker, importedLocation common.Location, @@ -200,8 +202,10 @@ func PrepareInterpreter(filename string, debugger *interpreter.Debugger) (*inter } config := &interpreter.Config{ - BaseActivation: baseActivation, - Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, + Storage: storage, UUIDHandler: func() (uint64, error) { defer func() { uuid++ }() return uuid, nil diff --git a/runtime/convertValues.go b/runtime/convertValues.go index a71ccc151b..0d1dc30f35 100644 --- a/runtime/convertValues.go +++ b/runtime/convertValues.go @@ -406,10 +406,8 @@ func exportCompositeValue( case *interpreter.CompositeValue: fieldValue = v.GetField(inter, locationRange, fieldName) - if fieldValue == nil && v.ComputedFields != nil { - if computedField, ok := v.ComputedFields[fieldName]; ok { - fieldValue = computedField(inter, locationRange) - } + if fieldValue == nil { + fieldValue = v.GetComputedField(inter, locationRange, fieldName) } } @@ -1449,8 +1447,6 @@ func (i valueImporter) importPublicKey( publicKeyValue, signAlgoValue, i.standardLibraryHandler, - i.standardLibraryHandler, - i.standardLibraryHandler, ), nil } diff --git a/runtime/convertValues_test.go b/runtime/convertValues_test.go index c7ebb5bdc4..52eda546de 100644 --- a/runtime/convertValues_test.go +++ b/runtime/convertValues_test.go @@ -441,8 +441,6 @@ func TestRuntimeExportValue(t *testing.T) { PublicKey: []byte{1, 2, 3}, SignAlgo: 2, }, - nil, - nil, ), hashAlgorithm, interpreter.NewUnmeteredUFix64ValueWithInteger(10, interpreter.EmptyLocationRange), diff --git a/runtime/coverage.go b/runtime/coverage.go index f73f5da11a..1e37040d35 100644 --- a/runtime/coverage.go +++ b/runtime/coverage.go @@ -112,14 +112,17 @@ type LocationFilter func(location Location) bool // locations from coverage collection. type CoverageReport struct { // Contains a *LocationCoverage per location. - Coverage map[common.Location]*LocationCoverage `json:"-"` + Coverage map[common.Location]*LocationCoverage // Contains locations whose programs are already inspected. - Locations map[common.Location]struct{} `json:"-"` + Locations map[common.Location]struct{} // Contains locations excluded from coverage collection. - ExcludedLocations map[common.Location]struct{} `json:"-"` + ExcludedLocations map[common.Location]struct{} // This filter can be used to inject custom logic on // each location/program inspection. - LocationFilter LocationFilter `json:"-"` + locationFilter LocationFilter + // Contains a mapping with source paths for each + // location. + locationMappings map[string]string } // WithLocationFilter sets the LocationFilter for the current @@ -127,7 +130,15 @@ type CoverageReport struct { func (r *CoverageReport) WithLocationFilter( locationFilter LocationFilter, ) { - r.LocationFilter = locationFilter + r.locationFilter = locationFilter +} + +// WithLocationMappings sets the LocationMappings for the current +// CoverageReport. +func (r *CoverageReport) WithLocationMappings( + locationMappings map[string]string, +) { + r.locationMappings = locationMappings } // ExcludeLocation adds the given location to the map of excluded @@ -167,7 +178,7 @@ func (r *CoverageReport) AddLineHit(location Location, line int) { // If the CoverageReport.LocationFilter is present, and calling it with the given // location results to false, the method call also results in a NO-OP. func (r *CoverageReport) InspectProgram(location Location, program *ast.Program) { - if r.LocationFilter != nil && !r.LocationFilter(location) { + if r.locationFilter != nil && !r.locationFilter(location) { return } if r.IsLocationExcluded(location) { @@ -405,8 +416,6 @@ func NewCoverageReport() *CoverageReport { } } -type crAlias CoverageReport - // To avoid the overhead of having the Percentage & MissedLines // as fields in the LocationCoverage struct, we simply populate // this lcAlias struct, with the corresponding methods, upon marshalling. @@ -423,7 +432,8 @@ type lcAlias struct { func (r *CoverageReport) MarshalJSON() ([]byte, error) { coverage := make(map[string]lcAlias, len(r.Coverage)) for location, locationCoverage := range r.Coverage { // nolint:maprange - coverage[location.ID()] = lcAlias{ + locationSource := r.sourcePathForLocation(location) + coverage[locationSource] = lcAlias{ LineHits: locationCoverage.LineHits, MissedLines: locationCoverage.MissedLines(), Statements: locationCoverage.Statements, @@ -433,11 +443,9 @@ func (r *CoverageReport) MarshalJSON() ([]byte, error) { return json.Marshal(&struct { Coverage map[string]lcAlias `json:"coverage"` ExcludedLocations []string `json:"excluded_locations"` - *crAlias }{ Coverage: coverage, ExcludedLocations: r.ExcludedLocationIDs(), - crAlias: (*crAlias)(r), }) } @@ -448,10 +456,7 @@ func (r *CoverageReport) UnmarshalJSON(data []byte) error { cr := &struct { Coverage map[string]lcAlias `json:"coverage"` ExcludedLocations []string `json:"excluded_locations"` - *crAlias - }{ - crAlias: (*crAlias)(r), - } + }{} if err := json.Unmarshal(data, cr); err != nil { return err @@ -505,7 +510,8 @@ func (r *CoverageReport) MarshalLCOV() ([]byte, error) { buf := new(bytes.Buffer) for _, location := range locations { coverage := r.Coverage[location] - _, err := fmt.Fprintf(buf, "TN:\nSF:%s\n", location.ID()) + locationSource := r.sourcePathForLocation(location) + _, err := fmt.Fprintf(buf, "TN:\nSF:%s\n", locationSource) if err != nil { return nil, err } @@ -539,3 +545,27 @@ func (r *CoverageReport) MarshalLCOV() ([]byte, error) { return buf.Bytes(), nil } + +// Given a common.Location, returns its mapped source, if any. +// Defaults to the location's ID(). +func (r *CoverageReport) sourcePathForLocation(location common.Location) string { + var locationIdentifier string + + switch loc := location.(type) { + case common.AddressLocation: + locationIdentifier = loc.Name + case common.StringLocation: + locationIdentifier = loc.String() + case common.IdentifierLocation: + locationIdentifier = loc.String() + default: + locationIdentifier = loc.ID() + } + + locationSource, ok := r.locationMappings[locationIdentifier] + if !ok { + locationSource = location.ID() + } + + return locationSource +} diff --git a/runtime/coverage_test.go b/runtime/coverage_test.go index e8b304e733..7d9b3c71a7 100644 --- a/runtime/coverage_test.go +++ b/runtime/coverage_test.go @@ -623,6 +623,117 @@ func TestRuntimeCoverageReportWithAddressLocation(t *testing.T) { require.JSONEq(t, expected, string(actual)) } +func TestCoverageReportWithLocationMappings(t *testing.T) { + + t.Parallel() + + script := []byte(` + access(all) fun answer(): Int { + var i = 0 + while i < 42 { + i = i + 1 + } + return i + } + `) + + program, err := parser.ParseProgram(nil, script, parser.Config{}) + require.NoError(t, err) + + locationMappings := map[string]string{ + "Answer": "cadence/scripts/answer.cdc", + } + coverageReport := NewCoverageReport() + coverageReport.WithLocationMappings(locationMappings) + + t.Run("with AddressLocation", func(t *testing.T) { + location := common.AddressLocation{ + Address: common.MustBytesToAddress([]byte{1, 2}), + Name: "Answer", + } + coverageReport.InspectProgram(location, program) + + actual, err := json.Marshal(coverageReport) + require.NoError(t, err) + + expected := ` + { + "coverage": { + "cadence/scripts/answer.cdc": { + "line_hits": { + "3": 0, + "4": 0, + "5": 0, + "7": 0 + }, + "missed_lines": [3, 4, 5, 7], + "statements": 4, + "percentage": "0.0%" + } + }, + "excluded_locations": [] + } + ` + require.JSONEq(t, expected, string(actual)) + }) + + t.Run("with StringLocation", func(t *testing.T) { + location := common.StringLocation("Answer") + coverageReport.InspectProgram(location, program) + + actual, err := json.Marshal(coverageReport) + require.NoError(t, err) + + expected := ` + { + "coverage": { + "cadence/scripts/answer.cdc": { + "line_hits": { + "3": 0, + "4": 0, + "5": 0, + "7": 0 + }, + "missed_lines": [3, 4, 5, 7], + "statements": 4, + "percentage": "0.0%" + } + }, + "excluded_locations": [] + } + ` + require.JSONEq(t, expected, string(actual)) + }) + + t.Run("with IdentifierLocation", func(t *testing.T) { + location := common.IdentifierLocation("Answer") + coverageReport.InspectProgram(location, program) + + actual, err := json.Marshal(coverageReport) + require.NoError(t, err) + + expected := ` + { + "coverage": { + "cadence/scripts/answer.cdc": { + "line_hits": { + "3": 0, + "4": 0, + "5": 0, + "7": 0 + }, + "missed_lines": [3, 4, 5, 7], + "statements": 4, + "percentage": "0.0%" + } + }, + "excluded_locations": [] + } + ` + require.JSONEq(t, expected, string(actual)) + }) +} + func TestRuntimeCoverageReportReset(t *testing.T) { t.Parallel() @@ -1794,44 +1905,116 @@ func TestRuntimeCoverageReportLCOVFormat(t *testing.T) { } `) - coverageReport := NewCoverageReport() - scriptlocation := common.ScriptLocation{} - coverageReport.ExcludeLocation(scriptlocation) - - runtimeInterface := &TestRuntimeInterface{ - OnGetCode: func(location Location) (bytes []byte, err error) { - switch location { - case common.StringLocation("IntegerTraits"): - return integerTraits, nil - default: - return nil, fmt.Errorf("unknown import location: %s", location) - } - }, - } - - config := DefaultTestInterpreterConfig - config.CoverageReport = coverageReport - runtime := NewTestInterpreterRuntimeWithConfig(config) - - value, err := runtime.ExecuteScript( - Script{ - Source: script, - }, - Context{ - Interface: runtimeInterface, - Location: scriptlocation, - CoverageReport: coverageReport, - }, - ) - require.NoError(t, err) + t.Run("without location mappings", func(t *testing.T) { + coverageReport := NewCoverageReport() + scriptlocation := common.ScriptLocation{} + coverageReport.ExcludeLocation(scriptlocation) + + runtimeInterface := &TestRuntimeInterface{ + OnGetCode: func(location Location) (bytes []byte, err error) { + switch location { + case common.StringLocation("IntegerTraits"): + return integerTraits, nil + default: + return nil, fmt.Errorf("unknown import location: %s", location) + } + }, + } + + config := DefaultTestInterpreterConfig + config.CoverageReport = coverageReport + runtime := NewTestInterpreterRuntimeWithConfig(config) + + value, err := runtime.ExecuteScript( + Script{ + Source: script, + }, + Context{ + Interface: runtimeInterface, + Location: scriptlocation, + CoverageReport: coverageReport, + }, + ) + require.NoError(t, err) + + assert.Equal(t, cadence.NewInt(42), value) + + actual, err := coverageReport.MarshalLCOV() + require.NoError(t, err) + + expected := `TN: +SF:S.IntegerTraits +DA:9,1 +DA:13,10 +DA:14,1 +DA:15,9 +DA:16,1 +DA:17,8 +DA:18,1 +DA:19,7 +DA:20,1 +DA:21,6 +DA:22,1 +DA:25,5 +DA:26,4 +DA:29,1 +LF:14 +LH:14 +end_of_record +` - assert.Equal(t, cadence.NewInt(42), value) + require.Equal(t, expected, string(actual)) - actual, err := coverageReport.MarshalLCOV() - require.NoError(t, err) + assert.Equal( + t, + "Coverage: 100.0% of statements", + coverageReport.String(), + ) + }) - expected := `TN: -SF:S.IntegerTraits + t.Run("with location mappings", func(t *testing.T) { + locationMappings := map[string]string{ + "IntegerTraits": "cadence/contracts/IntegerTraits.cdc", + } + coverageReport := NewCoverageReport() + coverageReport.WithLocationMappings(locationMappings) + scriptlocation := common.ScriptLocation{} + coverageReport.ExcludeLocation(scriptlocation) + + runtimeInterface := &TestRuntimeInterface{ + OnGetCode: func(location Location) (bytes []byte, err error) { + switch location { + case common.StringLocation("IntegerTraits"): + return integerTraits, nil + default: + return nil, fmt.Errorf("unknown import location: %s", location) + } + }, + } + + config := DefaultTestInterpreterConfig + config.CoverageReport = coverageReport + runtime := NewTestInterpreterRuntimeWithConfig(config) + + value, err := runtime.ExecuteScript( + Script{ + Source: script, + }, + Context{ + Interface: runtimeInterface, + Location: scriptlocation, + CoverageReport: coverageReport, + }, + ) + require.NoError(t, err) + + assert.Equal(t, cadence.NewInt(42), value) + + actual, err := coverageReport.MarshalLCOV() + require.NoError(t, err) + + expected := `TN: +SF:cadence/contracts/IntegerTraits.cdc DA:9,1 DA:13,10 DA:14,1 @@ -1850,11 +2033,13 @@ LF:14 LH:14 end_of_record ` - require.Equal(t, expected, string(actual)) + require.Equal(t, expected, string(actual)) + + assert.Equal( + t, + "Coverage: 100.0% of statements", + coverageReport.String(), + ) + }) - assert.Equal( - t, - "Coverage: 100.0% of statements", - coverageReport.String(), - ) } diff --git a/runtime/environment.go b/runtime/environment.go index c768073f4f..9c1e40bb7c 100644 --- a/runtime/environment.go +++ b/runtime/environment.go @@ -38,8 +38,18 @@ import ( type Environment interface { ArgumentDecoder - DeclareValue(valueDeclaration stdlib.StandardLibraryValue) - DeclareType(typeDeclaration stdlib.StandardLibraryType) + SetCompositeValueFunctionsHandler( + typeID common.TypeID, + handler stdlib.CompositeValueFunctionsHandler, + ) + DeclareValue( + valueDeclaration stdlib.StandardLibraryValue, + location common.Location, + ) + DeclareType( + typeDeclaration stdlib.StandardLibraryType, + location common.Location, + ) Configure( runtimeInterface Interface, codesAndPrograms CodesAndPrograms, @@ -78,14 +88,43 @@ type interpreterEnvironmentReconfigured struct { type interpreterEnvironment struct { interpreterEnvironmentReconfigured - baseTypeActivation *sema.VariableActivation - baseValueActivation *sema.VariableActivation - baseActivation *interpreter.VariableActivation + + // defaultBaseTypeActivation is the base type activation that applies to all locations by default. + defaultBaseTypeActivation *sema.VariableActivation + // The base type activations for individual locations. + // location == nil is the base type activation that applies to all locations, + // unless there is a base type activation for the given location. + // + // Base type activations are lazily / implicitly created + // by DeclareType / semaBaseActivationFor + baseTypeActivationsByLocation map[common.Location]*sema.VariableActivation + + // defaultBaseValueActivation is the base value activation that applies to all locations by default. + defaultBaseValueActivation *sema.VariableActivation + // The base value activations for individual locations. + // location == nil is the base value activation that applies to all locations, + // unless there is a base value activation for the given location. + // + // Base value activations are lazily / implicitly created + // by DeclareValue / semaBaseActivationFor + baseValueActivationsByLocation map[common.Location]*sema.VariableActivation + + // defaultBaseActivation is the base activation that applies to all locations by default + defaultBaseActivation *interpreter.VariableActivation + // The base activations for individual locations. + // location == nil is the base activation that applies to all locations, + // unless there is a base activation for the given location. + // + // Base activations are lazily / implicitly created + // by DeclareValue / interpreterBaseActivationFor + baseActivationsByLocation map[common.Location]*interpreter.VariableActivation + InterpreterConfig *interpreter.Config CheckerConfig *sema.Config deployedContractConstructorInvocation *stdlib.DeployedContractConstructorInvocation stackDepthLimiter *stackDepthLimiter checkedImports importResolutionResults + compositeValueFunctionsHandlers stdlib.CompositeValueFunctionsHandlers config Config } @@ -107,19 +146,20 @@ var _ ArgumentDecoder = &interpreterEnvironment{} var _ common.MemoryGauge = &interpreterEnvironment{} func newInterpreterEnvironment(config Config) *interpreterEnvironment { - baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) - baseTypeActivation := sema.NewVariableActivation(sema.BaseTypeActivation) - baseActivation := activations.NewActivation[*interpreter.Variable](nil, interpreter.BaseActivation) + defaultBaseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) + defaultBaseTypeActivation := sema.NewVariableActivation(sema.BaseTypeActivation) + defaultBaseActivation := activations.NewActivation(nil, interpreter.BaseActivation) env := &interpreterEnvironment{ - config: config, - baseValueActivation: baseValueActivation, - baseTypeActivation: baseTypeActivation, - baseActivation: baseActivation, - stackDepthLimiter: newStackDepthLimiter(config.StackDepthLimit), + config: config, + defaultBaseValueActivation: defaultBaseValueActivation, + defaultBaseTypeActivation: defaultBaseTypeActivation, + defaultBaseActivation: defaultBaseActivation, + stackDepthLimiter: newStackDepthLimiter(config.StackDepthLimit), } env.InterpreterConfig = env.newInterpreterConfig() env.CheckerConfig = env.newCheckerConfig() + env.compositeValueFunctionsHandlers = stdlib.DefaultStandardLibraryCompositeValueFunctionHandlers(env) return env } @@ -127,7 +167,7 @@ func (e *interpreterEnvironment) newInterpreterConfig() *interpreter.Config { return &interpreter.Config{ InvalidatedResourceValidationEnabled: true, MemoryGauge: e, - BaseActivation: e.baseActivation, + BaseActivationHandler: e.getBaseActivation, OnEventEmitted: e.newOnEventEmittedHandler(), InjectedCompositeFieldsHandler: e.newInjectedCompositeFieldsHandler(), UUIDHandler: e.newUUIDHandler(), @@ -137,6 +177,7 @@ func (e *interpreterEnvironment) newInterpreterConfig() *interpreter.Config { OnRecordTrace: e.newOnRecordTraceHandler(), OnResourceOwnerChange: e.newResourceOwnerChangedHandler(), CompositeTypeHandler: e.newCompositeTypeHandler(), + CompositeValueFunctionsHandler: e.newCompositeValueFunctionsHandler(), TracingEnabled: e.config.TracingEnabled, AtreeValueValidationEnabled: e.config.AtreeValidationEnabled, // NOTE: ignore e.config.AtreeValidationEnabled here, @@ -157,8 +198,8 @@ func (e *interpreterEnvironment) newInterpreterConfig() *interpreter.Config { func (e *interpreterEnvironment) newCheckerConfig() *sema.Config { return &sema.Config{ AccessCheckMode: sema.AccessCheckModeStrict, - BaseValueActivation: e.baseValueActivation, - BaseTypeActivation: e.baseTypeActivation, + BaseValueActivationHandler: e.getBaseValueActivation, + BaseTypeActivationHandler: e.getBaseTypeActivation, ValidTopLevelDeclarationsHandler: validTopLevelDeclarations, LocationHandler: e.newLocationHandler(), ImportHandler: e.resolveImport, @@ -170,7 +211,7 @@ func (e *interpreterEnvironment) newCheckerConfig() *sema.Config { func NewBaseInterpreterEnvironment(config Config) *interpreterEnvironment { env := newInterpreterEnvironment(config) for _, valueDeclaration := range stdlib.DefaultStandardLibraryValues(env) { - env.DeclareValue(valueDeclaration) + env.DeclareValue(valueDeclaration, nil) } return env } @@ -178,7 +219,7 @@ func NewBaseInterpreterEnvironment(config Config) *interpreterEnvironment { func NewScriptInterpreterEnvironment(config Config) Environment { env := newInterpreterEnvironment(config) for _, valueDeclaration := range stdlib.DefaultScriptStandardLibraryValues(env) { - env.DeclareValue(valueDeclaration) + env.DeclareValue(valueDeclaration, nil) } return env } @@ -197,13 +238,70 @@ func (e *interpreterEnvironment) Configure( e.stackDepthLimiter.depth = 0 } -func (e *interpreterEnvironment) DeclareValue(valueDeclaration stdlib.StandardLibraryValue) { - e.baseValueActivation.DeclareValue(valueDeclaration) - interpreter.Declare(e.baseActivation, valueDeclaration) +func (e *interpreterEnvironment) DeclareValue(valueDeclaration stdlib.StandardLibraryValue, location common.Location) { + e.semaBaseActivationFor( + location, + &e.baseValueActivationsByLocation, + e.defaultBaseValueActivation, + ).DeclareValue(valueDeclaration) + + activation := e.interpreterBaseActivationFor(location) + interpreter.Declare(activation, valueDeclaration) +} + +func (e *interpreterEnvironment) DeclareType(typeDeclaration stdlib.StandardLibraryType, location common.Location) { + e.semaBaseActivationFor( + location, + &e.baseTypeActivationsByLocation, + e.defaultBaseTypeActivation, + ).DeclareType(typeDeclaration) +} + +func (e *interpreterEnvironment) semaBaseActivationFor( + location common.Location, + baseActivationsByLocation *map[Location]*sema.VariableActivation, + defaultBaseActivation *sema.VariableActivation, +) (baseActivation *sema.VariableActivation) { + if location == nil { + return defaultBaseActivation + } + + if *baseActivationsByLocation == nil { + *baseActivationsByLocation = map[Location]*sema.VariableActivation{} + } else { + baseActivation = (*baseActivationsByLocation)[location] + } + if baseActivation == nil { + baseActivation = sema.NewVariableActivation(defaultBaseActivation) + (*baseActivationsByLocation)[location] = baseActivation + } + return baseActivation +} + +func (e *interpreterEnvironment) interpreterBaseActivationFor( + location common.Location, +) *interpreter.VariableActivation { + defaultBaseActivation := e.defaultBaseActivation + if location == nil { + return defaultBaseActivation + } + + baseActivation := e.baseActivationsByLocation[location] + if baseActivation == nil { + baseActivation = activations.NewActivation[*interpreter.Variable](nil, defaultBaseActivation) + if e.baseActivationsByLocation == nil { + e.baseActivationsByLocation = map[common.Location]*interpreter.VariableActivation{} + } + e.baseActivationsByLocation[location] = baseActivation + } + return baseActivation } -func (e *interpreterEnvironment) DeclareType(typeDeclaration stdlib.StandardLibraryType) { - e.baseTypeActivation.DeclareType(typeDeclaration) +func (e *interpreterEnvironment) SetCompositeValueFunctionsHandler( + typeID common.TypeID, + handler stdlib.CompositeValueFunctionsHandler, +) { + e.compositeValueFunctionsHandlers[typeID] = handler } func (e *interpreterEnvironment) MeterMemory(usage common.MemoryUsage) error { @@ -863,7 +961,8 @@ func (e *interpreterEnvironment) newCompositeTypeHandler() interpreter.Composite case nil: qualifiedIdentifier := string(typeID) - ty := sema.TypeActivationNestedType(e.baseTypeActivation, qualifiedIdentifier) + baseTypeActivation := e.getBaseTypeActivation(location) + ty := sema.TypeActivationNestedType(baseTypeActivation, qualifiedIdentifier) if ty == nil { return nil } @@ -877,6 +976,22 @@ func (e *interpreterEnvironment) newCompositeTypeHandler() interpreter.Composite } } +func (e *interpreterEnvironment) newCompositeValueFunctionsHandler() interpreter.CompositeValueFunctionsHandlerFunc { + return func( + inter *interpreter.Interpreter, + locationRange interpreter.LocationRange, + compositeValue *interpreter.CompositeValue, + ) map[string]interpreter.FunctionValue { + + handler := e.compositeValueFunctionsHandlers[compositeValue.TypeID()] + if handler == nil { + return nil + } + + return handler(inter, locationRange, compositeValue) + } +} + func (e *interpreterEnvironment) loadContract( inter *interpreter.Interpreter, compositeType *sema.CompositeType, @@ -1051,3 +1166,70 @@ func (e *interpreterEnvironment) CommitStorage(inter *interpreter.Interpreter) e return nil } + +// getBaseValueActivation returns the base activation for the given location. +// If a value was declared for the location (using DeclareValue), +// then the specific base value activation for this location is returned. +// Otherwise, the default base activation that applies for all locations is returned. +func (e *interpreterEnvironment) getBaseValueActivation( + location common.Location, +) ( + baseValueActivation *sema.VariableActivation, +) { + baseValueActivationsByLocation := e.baseValueActivationsByLocation + // Use the base value activation for the location, if any + // (previously implicitly created using DeclareValue) + baseValueActivation = baseValueActivationsByLocation[location] + if baseValueActivation == nil { + // If no base value activation for the location exists + // (no value was previously, specifically declared for the location using DeclareValue), + // return the base value activation that applies to all locations by default + baseValueActivation = e.defaultBaseValueActivation + } + return + +} + +// getBaseTypeActivation returns the base activation for the given location. +// If a type was declared for the location (using DeclareType), +// then the specific base type activation for this location is returned. +// Otherwise, the default base activation that applies for all locations is returned. +func (e *interpreterEnvironment) getBaseTypeActivation( + location common.Location, +) ( + baseTypeActivation *sema.VariableActivation, +) { + // Use the base type activation for the location, if any + // (previously implicitly created using DeclareType) + baseTypeActivationsByLocation := e.baseTypeActivationsByLocation + baseTypeActivation = baseTypeActivationsByLocation[location] + if baseTypeActivation == nil { + // If no base type activation for the location exists + // (no type was previously, specifically declared for the location using DeclareType), + // return the base type activation that applies to all locations by default + baseTypeActivation = e.defaultBaseTypeActivation + } + return +} + +// getBaseActivation returns the base activation for the given location. +// If a value was declared for the location (using DeclareValue), +// then the specific base activation for this location is returned. +// Otherwise, the default base activation that applies for all locations is returned. +func (e *interpreterEnvironment) getBaseActivation( + location common.Location, +) ( + baseActivation *interpreter.VariableActivation, +) { + // Use the base activation for the location, if any + // (previously implicitly created using DeclareValue) + baseActivationsByLocation := e.baseActivationsByLocation + baseActivation = baseActivationsByLocation[location] + if baseActivation == nil { + // If no base activation for the location exists + // (no value was previously, specifically declared for the location using DeclareValue), + // return the base activation that applies to all locations by default + baseActivation = e.defaultBaseActivation + } + return +} diff --git a/runtime/inbox_test.go b/runtime/inbox_test.go index c3c5583b8c..8be68cfd06 100644 --- a/runtime/inbox_test.go +++ b/runtime/inbox_test.go @@ -19,13 +19,16 @@ package runtime_test import ( + "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/onflow/cadence" + "github.com/onflow/cadence/encoding/json" . "github.com/onflow/cadence/runtime" + "github.com/onflow/cadence/runtime/common" . "github.com/onflow/cadence/runtime/tests/runtime_utils" ) @@ -111,8 +114,8 @@ func TestRuntimeAccountInboxPublishUnpublish(t *testing.T) { require.Equal(t, []string{ - "flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: \"foo\", type: Type>())", - "flow.InboxValueUnpublished(provider: 0x0000000000000001, name: \"foo\")", + `flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: "foo", type: Type>())`, + `flow.InboxValueUnpublished(provider: 0x0000000000000001, name: "foo")`, }, events, ) @@ -191,7 +194,7 @@ func TestRuntimeAccountInboxUnpublishWrongType(t *testing.T) { require.Equal(t, []string{ - "flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: \"foo\", type: Type>())", + `flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: "foo", type: Type>())`, }, events, ) @@ -280,7 +283,7 @@ func TestRuntimeAccountInboxUnpublishAbsent(t *testing.T) { require.Equal(t, []string{ - "flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: \"foo\", type: Type>())", + `flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: "foo", type: Type>())`, }, events, ) @@ -296,26 +299,28 @@ func TestRuntimeAccountInboxUnpublishRemove(t *testing.T) { var events []string transaction1 := []byte(` - transaction { + transaction(name: String) { prepare(signer: auth(Storage, Capabilities, Inbox) &Account) { signer.storage.save([3], to: /storage/foo) let cap = signer.capabilities.storage.issue<&[Int]>(/storage/foo) - log(signer.inbox.publish(cap, name: "foo", recipient: 0x2)) + log(signer.inbox.publish(cap, name: name, recipient: 0x2)) } } `) transaction2 := []byte(` - transaction { + transaction(name: String) { prepare(signer: auth(Inbox) &Account) { - let cap = signer.inbox.unpublish<&[Int]>("foo")! + let cap = signer.inbox.unpublish<&[Int]>(name)! log(cap.borrow()![0]) - let cap2 = signer.inbox.unpublish<&[Int]>("foo") + let cap2 = signer.inbox.unpublish<&[Int]>(name) log(cap2) } } `) + address := common.MustBytesToAddress([]byte{0x1}) + runtimeInterface1 := &TestRuntimeInterface{ Storage: storage, OnProgramLog: func(message string) { @@ -326,35 +331,45 @@ func TestRuntimeAccountInboxUnpublishRemove(t *testing.T) { return nil }, OnGetSigningAccounts: func() ([]Address, error) { - return []Address{[8]byte{0, 0, 0, 0, 0, 0, 0, 1}}, nil + return []Address{address}, nil + }, + OnDecodeArgument: func(b []byte, t cadence.Type) (value cadence.Value, err error) { + return json.Decode(nil, b) }, } + // NOTE: generate a long name + nameArgument, err := cadence.NewString(strings.Repeat("x", 10_000)) + require.NoError(t, err) + + args := encodeArgs([]cadence.Value{nameArgument}) + nextTransactionLocation := NewTransactionLocationGenerator() // publish from 1 to 2 - err := rt.ExecuteTransaction( + err = rt.ExecuteTransaction( Script{ - Source: transaction1, + Source: transaction1, + Arguments: args, }, Context{ Interface: runtimeInterface1, Location: nextTransactionLocation(), }, ) - require.NoError(t, err) // unpublish from 1 + err = rt.ExecuteTransaction( Script{ - Source: transaction2, + Source: transaction2, + Arguments: args, }, Context{ Interface: runtimeInterface1, Location: nextTransactionLocation(), }, ) - require.NoError(t, err) require.Equal(t, @@ -373,8 +388,12 @@ func TestRuntimeAccountInboxUnpublishRemove(t *testing.T) { require.Equal(t, []string{ - "flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: \"foo\", type: Type>())", - "flow.InboxValueUnpublished(provider: 0x0000000000000001, name: \"foo\")", + `flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: ` + + nameArgument.String() + + `, type: Type>())`, + `flow.InboxValueUnpublished(provider: 0x0000000000000001, name: ` + + nameArgument.String() + + `)`, }, events, ) @@ -417,6 +436,8 @@ func TestRuntimeAccountInboxUnpublishWrongAccount(t *testing.T) { } `) + address1 := common.MustBytesToAddress([]byte{0x1}) + runtimeInterface1 := &TestRuntimeInterface{ Storage: storage, OnProgramLog: func(message string) { @@ -427,10 +448,12 @@ func TestRuntimeAccountInboxUnpublishWrongAccount(t *testing.T) { return nil }, OnGetSigningAccounts: func() ([]Address, error) { - return []Address{[8]byte{0, 0, 0, 0, 0, 0, 0, 1}}, nil + return []Address{address1}, nil }, } + address2 := common.MustBytesToAddress([]byte{0x2}) + runtimeInterface2 := &TestRuntimeInterface{ Storage: storage, OnProgramLog: func(message string) { @@ -441,7 +464,7 @@ func TestRuntimeAccountInboxUnpublishWrongAccount(t *testing.T) { return nil }, OnGetSigningAccounts: func() ([]Address, error) { - return []Address{[8]byte{0, 0, 0, 0, 0, 0, 0, 2}}, nil + return []Address{address2}, nil }, } @@ -500,8 +523,8 @@ func TestRuntimeAccountInboxUnpublishWrongAccount(t *testing.T) { require.Equal(t, []string{ - "flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: \"foo\", type: Type>())", - "flow.InboxValueUnpublished(provider: 0x0000000000000001, name: \"foo\")", + `flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: "foo", type: Type>())`, + `flow.InboxValueUnpublished(provider: 0x0000000000000001, name: "foo")`, }, events, ) @@ -535,6 +558,8 @@ func TestRuntimeAccountInboxPublishClaim(t *testing.T) { } `) + address1 := common.MustBytesToAddress([]byte{0x1}) + runtimeInterface1 := &TestRuntimeInterface{ Storage: storage, OnProgramLog: func(message string) { @@ -545,13 +570,16 @@ func TestRuntimeAccountInboxPublishClaim(t *testing.T) { return nil }, OnGetSigningAccounts: func() ([]Address, error) { - return []Address{[8]byte{0, 0, 0, 0, 0, 0, 0, 1}}, nil + return []Address{address1}, nil }, } + address2 := common.MustBytesToAddress([]byte{0x2}) + runtimeInterface2 := &TestRuntimeInterface{ Storage: storage, OnProgramLog: func(message string) { + logs = append(logs, message) }, OnEmitEvent: func(event cadence.Event) error { @@ -559,7 +587,7 @@ func TestRuntimeAccountInboxPublishClaim(t *testing.T) { return nil }, OnGetSigningAccounts: func() ([]Address, error) { - return []Address{[8]byte{0, 0, 0, 0, 0, 0, 0, 2}}, nil + return []Address{address2}, nil }, } @@ -604,8 +632,8 @@ func TestRuntimeAccountInboxPublishClaim(t *testing.T) { require.Equal(t, []string{ - "flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: \"foo\", type: Type>())", - "flow.InboxValueClaimed(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: \"foo\")", + `flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: "foo", type: Type>())`, + `flow.InboxValueClaimed(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: "foo")`, }, events, ) @@ -706,7 +734,7 @@ func TestRuntimeAccountInboxPublishClaimWrongType(t *testing.T) { require.Equal(t, []string{ - "flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: \"foo\", type: Type>())", + `flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: "foo", type: Type>())`, }, events, ) @@ -808,7 +836,7 @@ func TestRuntimeAccountInboxPublishClaimWrongName(t *testing.T) { require.Equal(t, []string{ - "flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: \"foo\", type: Type>())", + `flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: "foo", type: Type>())`, }, events, ) @@ -934,8 +962,8 @@ func TestRuntimeAccountInboxPublishClaimRemove(t *testing.T) { require.Equal(t, []string{ - "flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: \"foo\", type: Type>())", - "flow.InboxValueClaimed(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: \"foo\")", + `flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: "foo", type: Type>())`, + `flow.InboxValueClaimed(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: "foo")`, }, events, ) @@ -1075,8 +1103,8 @@ func TestRuntimeAccountInboxPublishClaimWrongAccount(t *testing.T) { require.Equal(t, []string{ - "flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: \"foo\", type: Type>())", - "flow.InboxValueClaimed(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: \"foo\")", + `flow.InboxValuePublished(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: "foo", type: Type>())`, + `flow.InboxValueClaimed(provider: 0x0000000000000001, recipient: 0x0000000000000002, name: "foo")`, }, events, ) diff --git a/runtime/interpreter/config.go b/runtime/interpreter/config.go index c04e8ca59b..56de3ec830 100644 --- a/runtime/interpreter/config.go +++ b/runtime/interpreter/config.go @@ -49,8 +49,10 @@ type Config struct { UUIDHandler UUIDHandlerFunc // CompositeTypeHandler is used to load composite types CompositeTypeHandler CompositeTypeHandlerFunc - BaseActivation *VariableActivation - Debugger *Debugger + // CompositeValueFunctionsHandler is used to load composite value functions + CompositeValueFunctionsHandler CompositeValueFunctionsHandlerFunc + BaseActivationHandler func(location common.Location) *VariableActivation + Debugger *Debugger // OnStatement is triggered when a statement is about to be executed OnStatement OnStatementFunc // OnLoopIteration is triggered when a loop iteration is about to be executed diff --git a/runtime/interpreter/interpreter.go b/runtime/interpreter/interpreter.go index 66233c2369..a4a89bf36e 100644 --- a/runtime/interpreter/interpreter.go +++ b/runtime/interpreter/interpreter.go @@ -168,6 +168,13 @@ type UUIDHandlerFunc func() (uint64, error) // CompositeTypeHandlerFunc is a function that loads composite types. type CompositeTypeHandlerFunc func(location common.Location, typeID TypeID) *sema.CompositeType +// CompositeValueFunctionsHandlerFunc is a function that loads composite value functions. +type CompositeValueFunctionsHandlerFunc func( + inter *Interpreter, + locationRange LocationRange, + compositeValue *CompositeValue, +) map[string]FunctionValue + // CompositeTypeCode contains the "prepared" / "callable" "code" // for the functions and the destructor of a composite // (contract, struct, resource, event). @@ -277,9 +284,15 @@ func NewInterpreterWithSharedState( sharedState.allInterpreters[location] = interpreter } + // Initialize activations + interpreter.activations = activations.NewActivations[*Variable](interpreter) - baseActivation := sharedState.Config.BaseActivation + var baseActivation *VariableActivation + baseActivationHandler := sharedState.Config.BaseActivationHandler + if baseActivationHandler != nil { + baseActivation = baseActivationHandler(location) + } if baseActivation == nil { baseActivation = BaseActivation } @@ -1273,7 +1286,7 @@ func (interpreter *Interpreter) declareNonEnumCompositeValue( address, ) - value.InjectedFields = injectedFields + value.injectedFields = injectedFields value.Functions = functions value.Destructor = destructorFunction @@ -4555,6 +4568,80 @@ func (interpreter *Interpreter) GetContractComposite(contractLocation common.Add return contractValue, nil } +func GetNativeCompositeValueComputedFields(v *CompositeValue) map[string]ComputedField { + switch v.QualifiedIdentifier { + case sema.PublicKeyType.Identifier: + return map[string]ComputedField{ + sema.PublicKeyTypePublicKeyFieldName: func(interpreter *Interpreter, locationRange LocationRange) Value { + publicKeyValue := v.GetField(interpreter, locationRange, sema.PublicKeyTypePublicKeyFieldName) + return publicKeyValue.Transfer( + interpreter, + locationRange, + atree.Address{}, + false, + nil, + nil, + ) + }, + } + } + + return nil +} + +func (interpreter *Interpreter) GetCompositeValueComputedFields(v *CompositeValue) map[string]ComputedField { + + var computedFields map[string]ComputedField + if v.Location == nil { + computedFields = GetNativeCompositeValueComputedFields(v) + if computedFields != nil { + return computedFields + } + } + + // TODO: add handler to config + + return nil +} + +func (interpreter *Interpreter) GetCompositeValueInjectedFields(v *CompositeValue) map[string]Value { + config := interpreter.SharedState.Config + injectedCompositeFieldsHandler := config.InjectedCompositeFieldsHandler + if injectedCompositeFieldsHandler == nil { + return nil + } + + return injectedCompositeFieldsHandler( + interpreter, + v.Location, + v.QualifiedIdentifier, + v.Kind, + ) +} + +func (interpreter *Interpreter) GetCompositeValueFunctions( + v *CompositeValue, + locationRange LocationRange, +) map[string]FunctionValue { + + var functions map[string]FunctionValue + + typeID := v.TypeID() + + sharedState := interpreter.SharedState + + compositeValueFunctionsHandler := sharedState.Config.CompositeValueFunctionsHandler + if compositeValueFunctionsHandler != nil { + functions = compositeValueFunctionsHandler(interpreter, locationRange, v) + if functions != nil { + return functions + } + } + + compositeCodes := sharedState.typeCodes.CompositeCodes + return compositeCodes[typeID].CompositeFunctions +} + func (interpreter *Interpreter) GetCompositeType( location common.Location, qualifiedIdentifier string, diff --git a/runtime/interpreter/stringatreevalue.go b/runtime/interpreter/stringatreevalue.go index 98e7fcf2f9..b482c49de3 100644 --- a/runtime/interpreter/stringatreevalue.go +++ b/runtime/interpreter/stringatreevalue.go @@ -61,7 +61,11 @@ func StringAtreeValueHashInput(v atree.Value, _ []byte) ([]byte, error) { return []byte(v.(StringAtreeValue)), nil } -func StringAtreeValueComparator(_ atree.SlabStorage, value atree.Value, otherStorable atree.Storable) (bool, error) { - result := value.(StringAtreeValue) == otherStorable.(StringAtreeValue) +func StringAtreeValueComparator(storage atree.SlabStorage, value atree.Value, otherStorable atree.Storable) (bool, error) { + otherValue, err := otherStorable.StoredValue(storage) + if err != nil { + return false, err + } + result := value.(StringAtreeValue) == otherValue.(StringAtreeValue) return result, nil } diff --git a/runtime/interpreter/stringatreevalue_test.go b/runtime/interpreter/stringatreevalue_test.go new file mode 100644 index 0000000000..4d0d574390 --- /dev/null +++ b/runtime/interpreter/stringatreevalue_test.go @@ -0,0 +1,65 @@ +/* + * Cadence - The resource-oriented smart contract programming language + * + * Copyright Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package interpreter + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/onflow/cadence/runtime/common" +) + +func TestLargeStringAtreeValueInSeparateSlab(t *testing.T) { + + t.Parallel() + + // Ensure that StringAtreeValue handles the case where it is stored in a separate slab, + // when the string is very large + + storage := NewInMemoryStorage(nil) + + storageMap := storage.GetStorageMap( + common.MustBytesToAddress([]byte{0x1}), + common.PathDomainStorage.Identifier(), + true, + ) + + inter, err := NewInterpreter( + nil, + common.StringLocation("test"), + &Config{ + Storage: storage, + }, + ) + require.NoError(t, err) + + // Generate a large key to force the string to get stored in a separate slab + keyValue := NewStringAtreeValue(nil, strings.Repeat("x", 10_000)) + + key := StringStorageMapKey(keyValue) + + expected := NewUnmeteredUInt8Value(42) + storageMap.SetValue(inter, key, expected) + + actual := storageMap.ReadValue(nil, key) + + require.Equal(t, expected, actual) +} diff --git a/runtime/interpreter/value.go b/runtime/interpreter/value.go index 01126bbaa7..8e46111afa 100644 --- a/runtime/interpreter/value.go +++ b/runtime/interpreter/value.go @@ -3100,6 +3100,9 @@ func (v *ArrayValue) Reverse( return nil } + // Meter computation for iterating the array. + interpreter.ReportComputation(common.ComputationKindLoop, 1) + value := v.Get(interpreter, locationRange, index) index-- @@ -3151,6 +3154,9 @@ func (v *ArrayValue) Filter( var value Value for { + // Meter computation for iterating the array. + interpreter.ReportComputation(common.ComputationKindLoop, 1) + atreeValue, err := iterator.Next() if err != nil { panic(errors.NewExternalError(err)) @@ -3245,6 +3251,9 @@ func (v *ArrayValue) Map( uint64(v.Count()), func() Value { + // Meter computation for iterating the array. + interpreter.ReportComputation(common.ComputationKindLoop, 1) + atreeValue, err := iterator.Next() if err != nil { panic(errors.NewExternalError(err)) @@ -16346,8 +16355,8 @@ type CompositeValue struct { Location common.Location staticType StaticType Stringer func(gauge common.MemoryGauge, value *CompositeValue, seenReferences SeenReferences) string - InjectedFields map[string]Value - ComputedFields map[string]ComputedField + injectedFields map[string]Value + computedFields map[string]ComputedField NestedVariables map[string]*Variable Functions map[string]FunctionValue dictionary *atree.OrderedMap @@ -16708,19 +16717,15 @@ func (v *CompositeValue) GetMember(interpreter *Interpreter, locationRange Locat return builtin } - storable, err := v.dictionary.Get( - StringAtreeValueComparator, - StringAtreeValueHashInput, - StringAtreeValue(name), - ) - if err != nil { - var keyNotFoundError *atree.KeyNotFoundError - if !goerrors.As(err, &keyNotFoundError) { - panic(errors.NewExternalError(err)) + // Give computed fields precedence over stored fields for built-in types + if v.Location == nil { + if computedField := v.GetComputedField(interpreter, locationRange, name); computedField != nil { + return computedField } } - if storable != nil { - return StoredValue(interpreter, storable, config.Storage) + + if field := v.GetField(interpreter, locationRange, name); field != nil { + return field } if v.NestedVariables != nil { @@ -16732,42 +16737,18 @@ func (v *CompositeValue) GetMember(interpreter *Interpreter, locationRange Locat interpreter = v.getInterpreter(interpreter) - if v.ComputedFields != nil { - if computedField, ok := v.ComputedFields[name]; ok { - return computedField(interpreter, locationRange) - } - } + // Dynamically link in the computed fields, injected fields, and functions - // If the composite value was deserialized, dynamically link in the functions - // and get injected fields - - v.InitializeFunctions(interpreter) - - injectedCompositeFieldsHandler := config.InjectedCompositeFieldsHandler - if v.InjectedFields == nil && injectedCompositeFieldsHandler != nil { - v.InjectedFields = injectedCompositeFieldsHandler( - interpreter, - v.Location, - v.QualifiedIdentifier, - v.Kind, - ) + if computedField := v.GetComputedField(interpreter, locationRange, name); computedField != nil { + return computedField } - if v.InjectedFields != nil { - value, ok := v.InjectedFields[name] - if ok { - return value - } + if injectedField := v.GetInjectedField(interpreter, name); injectedField != nil { + return injectedField } - function, ok := v.Functions[name] - if ok { - var base *EphemeralReferenceValue - var self MemberAccessibleValue = v - if v.Kind == common.CompositeKindAttachment { - base, self = attachmentBaseAndSelfValues(interpreter, v) - } - return NewBoundFunctionValue(interpreter, function, &self, base, nil) + if function := v.GetFunction(interpreter, locationRange, name); function != nil { + return function } return nil @@ -16799,12 +16780,53 @@ func (v *CompositeValue) getInterpreter(interpreter *Interpreter) *Interpreter { return interpreter.EnsureLoaded(v.Location) } -func (v *CompositeValue) InitializeFunctions(interpreter *Interpreter) { - if v.Functions != nil { - return +func (v *CompositeValue) GetComputedFields(interpreter *Interpreter) map[string]ComputedField { + if v.computedFields == nil { + v.computedFields = interpreter.GetCompositeValueComputedFields(v) + } + return v.computedFields +} + +func (v *CompositeValue) GetComputedField(interpreter *Interpreter, locationRange LocationRange, name string) Value { + computedFields := v.GetComputedFields(interpreter) + + computedField, ok := computedFields[name] + if !ok { + return nil } - v.Functions = interpreter.SharedState.typeCodes.CompositeCodes[v.TypeID()].CompositeFunctions + return computedField(interpreter, locationRange) +} + +func (v *CompositeValue) GetInjectedField(interpreter *Interpreter, name string) Value { + if v.injectedFields == nil { + v.injectedFields = interpreter.GetCompositeValueInjectedFields(v) + } + + value, ok := v.injectedFields[name] + if !ok { + return nil + } + + return value +} + +func (v *CompositeValue) GetFunction(interpreter *Interpreter, locationRange LocationRange, name string) FunctionValue { + if v.Functions == nil { + v.Functions = interpreter.GetCompositeValueFunctions(v, locationRange) + } + + function, ok := v.Functions[name] + if !ok { + return nil + } + + var base *EphemeralReferenceValue + var self MemberAccessibleValue = v + if v.Kind == common.CompositeKindAttachment { + base, self = attachmentBaseAndSelfValues(interpreter, v) + } + return NewBoundFunctionValue(interpreter, function, &self, base, nil) } func (v *CompositeValue) OwnerValue(interpreter *Interpreter, locationRange LocationRange) OptionalValue { @@ -17190,22 +17212,26 @@ func (v *CompositeValue) ConformsToStaticType( } fieldsLen := int(v.dictionary.Count()) - if v.ComputedFields != nil { - fieldsLen += len(v.ComputedFields) + + computedFields := v.GetComputedFields(interpreter) + if computedFields != nil { + fieldsLen += len(computedFields) } - if fieldsLen != len(compositeType.Fields) { + // The composite might store additional fields + // which are not statically declared in the composite type. + if fieldsLen < len(compositeType.Fields) { return false } for _, fieldName := range compositeType.Fields { value := v.GetField(interpreter, locationRange, fieldName) if value == nil { - if v.ComputedFields == nil { + if computedFields == nil { return false } - fieldGetter, ok := v.ComputedFields[fieldName] + fieldGetter, ok := computedFields[fieldName] if !ok { return false } @@ -17455,8 +17481,8 @@ func (v *CompositeValue) Transfer( dictionary, ) - res.InjectedFields = v.InjectedFields - res.ComputedFields = v.ComputedFields + res.injectedFields = v.injectedFields + res.computedFields = v.computedFields res.NestedVariables = v.NestedVariables res.Functions = v.Functions res.Destructor = v.Destructor @@ -17538,8 +17564,8 @@ func (v *CompositeValue) Clone(interpreter *Interpreter) Value { Location: v.Location, QualifiedIdentifier: v.QualifiedIdentifier, Kind: v.Kind, - InjectedFields: v.InjectedFields, - ComputedFields: v.ComputedFields, + injectedFields: v.injectedFields, + computedFields: v.computedFields, NestedVariables: v.NestedVariables, Functions: v.Functions, Destructor: v.Destructor, @@ -19584,7 +19610,7 @@ func (v *SomeValue) RecursiveString(seenReferences SeenReferences) string { return v.value.RecursiveString(seenReferences) } -func (v SomeValue) MeteredString(memoryGauge common.MemoryGauge, seenReferences SeenReferences) string { +func (v *SomeValue) MeteredString(memoryGauge common.MemoryGauge, seenReferences SeenReferences) string { return v.value.MeteredString(memoryGauge, seenReferences) } diff --git a/runtime/interpreter/value_publickey.go b/runtime/interpreter/value_publickey.go index 9193ed3253..e842feec82 100644 --- a/runtime/interpreter/value_publickey.go +++ b/runtime/interpreter/value_publickey.go @@ -19,8 +19,6 @@ package interpreter import ( - "github.com/onflow/atree" - "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/sema" ) @@ -41,18 +39,19 @@ func NewPublicKeyValue( publicKey *ArrayValue, signAlgo Value, validatePublicKey PublicKeyValidationHandlerFunc, - publicKeyVerifySignatureFunction FunctionValue, - publicKeyVerifyPoPFunction FunctionValue, ) *CompositeValue { fields := []CompositeField{ + { + Name: sema.PublicKeyTypePublicKeyFieldName, + Value: publicKey, + }, { Name: sema.PublicKeyTypeSignAlgoFieldName, Value: signAlgo, }, } - // TODO: refactor to SimpleCompositeValue publicKeyValue := NewCompositeValue( interpreter, locationRange, @@ -63,23 +62,6 @@ func NewPublicKeyValue( common.ZeroAddress, ) - publicKeyValue.ComputedFields = map[string]ComputedField{ - sema.PublicKeyTypePublicKeyFieldName: func(interpreter *Interpreter, locationRange LocationRange) Value { - return publicKey.Transfer( - interpreter, - locationRange, - atree.Address{}, - false, - nil, - nil, - ) - }, - } - publicKeyValue.Functions = map[string]FunctionValue{ - sema.PublicKeyTypeVerifyFunctionName: publicKeyVerifySignatureFunction, - sema.PublicKeyTypeVerifyPoPFunctionName: publicKeyVerifyPoPFunction, - } - err := validatePublicKey(interpreter, locationRange, publicKeyValue) if err != nil { panic(InvalidPublicKeyError{ @@ -89,32 +71,5 @@ func NewPublicKeyValue( }) } - // Public key value to string should include the key even though it is a computed field - publicKeyValue.Stringer = func( - memoryGauge common.MemoryGauge, - publicKeyValue *CompositeValue, - seenReferences SeenReferences, - ) string { - - stringerFields := []CompositeField{ - { - Name: sema.PublicKeyTypePublicKeyFieldName, - Value: publicKey, - }, - { - Name: sema.PublicKeyTypeSignAlgoFieldName, - // TODO: provide proper location range - Value: publicKeyValue.GetField(interpreter, EmptyLocationRange, sema.PublicKeyTypeSignAlgoFieldName), - }, - } - - return formatComposite( - memoryGauge, - string(publicKeyValue.TypeID()), - stringerFields, - seenReferences, - ) - } - return publicKeyValue } diff --git a/runtime/interpreter/value_string.go b/runtime/interpreter/value_string.go index de8f342297..5b2501a945 100644 --- a/runtime/interpreter/value_string.go +++ b/runtime/interpreter/value_string.go @@ -132,6 +132,10 @@ func stringFunctionJoin(invocation Invocation) Value { first := true stringArray.Iterate(inter, func(element Value) (resume bool) { + + // Meter computation for iterating the array. + inter.ReportComputation(common.ComputationKindLoop, 1) + // Add separator if !first { // Construct directly instead of using NewStringMemoryUsage to avoid diff --git a/runtime/interpreter/value_test.go b/runtime/interpreter/value_test.go index 516d4fd950..cf79dfed79 100644 --- a/runtime/interpreter/value_test.go +++ b/runtime/interpreter/value_test.go @@ -3205,8 +3205,6 @@ func TestPublicKeyValue(t *testing.T) { func(interpreter *Interpreter, locationRange LocationRange, publicKey *CompositeValue) error { return nil }, - nil, - nil, ) require.Equal(t, @@ -3261,8 +3259,6 @@ func TestPublicKeyValue(t *testing.T) { func(interpreter *Interpreter, locationRange LocationRange, publicKey *CompositeValue) error { return fakeError }, - nil, - nil, ) }) }) diff --git a/runtime/predeclaredvalues_test.go b/runtime/predeclaredvalues_test.go index 0c75774781..b2f4e6cbbb 100644 --- a/runtime/predeclaredvalues_test.go +++ b/runtime/predeclaredvalues_test.go @@ -20,8 +20,10 @@ package runtime_test import ( "math/big" + "strconv" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/onflow/cadence" @@ -30,6 +32,7 @@ import ( "github.com/onflow/cadence/runtime/interpreter" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" + "github.com/onflow/cadence/runtime/tests/checker" . "github.com/onflow/cadence/runtime/tests/runtime_utils" . "github.com/onflow/cadence/runtime/tests/utils" ) @@ -38,96 +41,218 @@ func TestRuntimePredeclaredValues(t *testing.T) { t.Parallel() - valueDeclaration := stdlib.StandardLibraryValue{ - Name: "foo", - Type: sema.IntType, - Kind: common.DeclarationKindConstant, - Value: interpreter.NewUnmeteredIntValueFromInt64(2), + const contractName = "C" + address := common.MustBytesToAddress([]byte{0x1}) + contractLocation := common.AddressLocation{ + Address: address, + Name: contractName, } - contract := []byte(` - access(all) contract C { - access(all) fun foo(): Int { - return foo - } - } - `) + test := func( + t *testing.T, + contract string, + script string, + valueDeclarations map[common.Location]stdlib.StandardLibraryValue, + checkTransaction func(err error) bool, + checkScript func(result cadence.Value, err error), + ) { - script := []byte(` - import C from 0x1 + runtime := NewTestInterpreterRuntime() - access(all) fun main(): Int { - return foo + C.foo() - } - `) + deploy := DeploymentTransaction(contractName, []byte(contract)) - runtime := NewTestInterpreterRuntime() + var accountCode []byte + var events []cadence.Event - deploy := DeploymentTransaction("C", contract) + runtimeInterface := &TestRuntimeInterface{ + OnGetCode: func(_ Location) (bytes []byte, err error) { + return accountCode, nil + }, + Storage: NewTestLedger(nil, nil), + OnGetSigningAccounts: func() ([]Address, error) { + return []Address{address}, nil + }, + OnResolveLocation: NewSingleIdentifierLocationResolver(t), + OnGetAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) { + return accountCode, nil + }, + OnUpdateAccountContractCode: func(_ common.AddressLocation, code []byte) error { + accountCode = code + return nil + }, + OnEmitEvent: func(event cadence.Event) error { + events = append(events, event) + return nil + }, + } - var accountCode []byte - var events []cadence.Event + prepareEnvironment := func(env Environment) { + for location, valueDeclaration := range valueDeclarations { + env.DeclareValue(valueDeclaration, location) + } + } - runtimeInterface := &TestRuntimeInterface{ - OnGetCode: func(_ Location) (bytes []byte, err error) { - return accountCode, nil - }, - Storage: NewTestLedger(nil, nil), - OnGetSigningAccounts: func() ([]Address, error) { - return []Address{common.MustBytesToAddress([]byte{0x1})}, nil - }, - OnResolveLocation: NewSingleIdentifierLocationResolver(t), - OnGetAccountContractCode: func(_ common.AddressLocation) (code []byte, err error) { - return accountCode, nil - }, - OnUpdateAccountContractCode: func(_ common.AddressLocation, code []byte) error { - accountCode = code - return nil - }, - OnEmitEvent: func(event cadence.Event) error { - events = append(events, event) - return nil - }, + // Run deploy transaction + + transactionEnvironment := NewBaseInterpreterEnvironment(Config{}) + prepareEnvironment(transactionEnvironment) + + err := runtime.ExecuteTransaction( + Script{ + Source: deploy, + }, + Context{ + Interface: runtimeInterface, + Location: common.TransactionLocation{}, + Environment: transactionEnvironment, + }, + ) + + if checkTransaction(err) { + + scriptEnvironment := NewScriptInterpreterEnvironment(Config{}) + prepareEnvironment(scriptEnvironment) + + checkScript(runtime.ExecuteScript( + Script{ + Source: []byte(script), + }, + Context{ + Interface: runtimeInterface, + Location: common.ScriptLocation{}, + Environment: scriptEnvironment, + }, + )) + } } - // Run transaction + t.Run("everywhere", func(t *testing.T) { + t.Parallel() - transactionEnvironment := NewBaseInterpreterEnvironment(Config{}) - transactionEnvironment.DeclareValue(valueDeclaration) + test(t, + ` + access(all) contract C { + access(all) fun foo(): Int { + return foo + } + } + `, + ` + import C from 0x1 + + access(all) fun main(): Int { + return foo + C.foo() + } + `, + map[common.Location]stdlib.StandardLibraryValue{ + nil: { + Name: "foo", + Type: sema.IntType, + Kind: common.DeclarationKindConstant, + Value: interpreter.NewUnmeteredIntValueFromInt64(2), + }, + }, + func(err error) bool { + return assert.NoError(t, err) + }, + func(result cadence.Value, err error) { - err := runtime.ExecuteTransaction( - Script{ - Source: deploy, - }, - Context{ - Interface: runtimeInterface, - Location: common.TransactionLocation{}, - Environment: transactionEnvironment, - }, - ) - require.NoError(t, err) + require.NoError(t, err) - // Run script + require.Equal(t, + cadence.Int{Value: big.NewInt(4)}, + result, + ) + }, + ) + }) - scriptEnvironment := NewScriptInterpreterEnvironment(Config{}) - scriptEnvironment.DeclareValue(valueDeclaration) + t.Run("only contract, no use in script", func(t *testing.T) { + t.Parallel() - result, err := runtime.ExecuteScript( - Script{ - Source: script, - }, - Context{ - Interface: runtimeInterface, - Location: common.ScriptLocation{}, - Environment: scriptEnvironment, - }, - ) - require.NoError(t, err) + test(t, + ` + access(all) contract C { + access(all) fun foo(): Int { + return foo + } + } + `, + ` + import C from 0x1 + + access(all) fun main(): Int { + return C.foo() + } + `, + map[common.Location]stdlib.StandardLibraryValue{ + contractLocation: { + Name: "foo", + Type: sema.IntType, + Kind: common.DeclarationKindConstant, + Value: interpreter.NewUnmeteredIntValueFromInt64(2), + }, + }, + func(err error) bool { + return assert.NoError(t, err) + }, + func(result cadence.Value, err error) { + + require.NoError(t, err) + + require.Equal(t, + cadence.Int{Value: big.NewInt(2)}, + result, + ) + }, + ) + }) + + t.Run("only contract, use in script", func(t *testing.T) { + t.Parallel() + + test(t, + ` + access(all) contract C { + access(all) fun foo(): Int { + return foo + } + } + `, + ` + import C from 0x1 + + access(all) fun main(): Int { + return foo + C.foo() + } + `, + map[common.Location]stdlib.StandardLibraryValue{ + contractLocation: { + Name: "foo", + Type: sema.IntType, + Kind: common.DeclarationKindConstant, + Value: interpreter.NewUnmeteredIntValueFromInt64(2), + }, + }, + func(err error) bool { + return assert.NoError(t, err) + }, + func(result cadence.Value, err error) { + RequireError(t, err) + + var checkerErr *sema.CheckerError + require.ErrorAs(t, err, &checkerErr) + assert.Equal(t, common.ScriptLocation{}, checkerErr.Location) + + errs := checker.RequireCheckerErrors(t, err, 1) + + var notDeclaredErr *sema.NotDeclaredError + require.ErrorAs(t, errs[0], ¬DeclaredErr) + require.Equal(t, "foo", notDeclaredErr.Name) + }, + ) + }) - require.Equal(t, - cadence.Int{Value: big.NewInt(4)}, - result, - ) } func TestRuntimePredeclaredTypes(t *testing.T) { @@ -172,8 +297,8 @@ func TestRuntimePredeclaredTypes(t *testing.T) { // Run script scriptEnvironment := NewScriptInterpreterEnvironment(Config{}) - scriptEnvironment.DeclareValue(valueDeclaration) - scriptEnvironment.DeclareType(typeDeclaration) + scriptEnvironment.DeclareValue(valueDeclaration, nil) + scriptEnvironment.DeclareType(typeDeclaration, nil) result, err := runtime.ExecuteScript( Script{ @@ -243,8 +368,8 @@ func TestRuntimePredeclaredTypes(t *testing.T) { // Run script scriptEnvironment := NewScriptInterpreterEnvironment(Config{}) - scriptEnvironment.DeclareValue(valueDeclaration) - scriptEnvironment.DeclareType(typeDeclaration) + scriptEnvironment.DeclareValue(valueDeclaration, nil) + scriptEnvironment.DeclareType(typeDeclaration, nil) result, err := runtime.ExecuteScript( Script{ @@ -311,7 +436,7 @@ func TestRuntimePredeclaredTypes(t *testing.T) { // Run script scriptEnvironment := NewScriptInterpreterEnvironment(Config{}) - scriptEnvironment.DeclareValue(valueDeclaration) + scriptEnvironment.DeclareValue(valueDeclaration, nil) _, err := runtime.ExecuteScript( Script{ @@ -387,8 +512,8 @@ func TestRuntimePredeclaredTypes(t *testing.T) { // Run script scriptEnvironment := NewScriptInterpreterEnvironment(Config{}) - scriptEnvironment.DeclareValue(valueDeclaration) - scriptEnvironment.DeclareType(typeDeclaration) + scriptEnvironment.DeclareValue(valueDeclaration, nil) + scriptEnvironment.DeclareType(typeDeclaration, nil) result, err := runtime.ExecuteScript( Script{ @@ -463,7 +588,7 @@ func TestRuntimePredeclaredTypes(t *testing.T) { // Run script scriptEnvironment := NewScriptInterpreterEnvironment(Config{}) - scriptEnvironment.DeclareValue(valueDeclaration) + scriptEnvironment.DeclareValue(valueDeclaration, nil) _, err := runtime.ExecuteScript( Script{ @@ -482,3 +607,129 @@ func TestRuntimePredeclaredTypes(t *testing.T) { }) } + +func TestRuntimePredeclaredTypeWithInjectedFunctions(t *testing.T) { + + t.Parallel() + + xType := &sema.CompositeType{ + Identifier: "X", + Kind: common.CompositeKindStructure, + Members: &sema.StringMemberOrderedMap{}, + } + + const fooFunctionName = "foo" + fooFunctionType := &sema.FunctionType{ + Parameters: []sema.Parameter{ + { + Identifier: "bar", + TypeAnnotation: sema.NewTypeAnnotation(sema.UInt8Type), + }, + }, + ReturnTypeAnnotation: sema.NewTypeAnnotation(sema.StringType), + } + + fooFunctionMember := sema.NewPublicFunctionMember( + nil, + xType, + fooFunctionName, + fooFunctionType, + "", + ) + xType.Members.Set(fooFunctionName, fooFunctionMember) + + xConstructorType := &sema.FunctionType{ + ReturnTypeAnnotation: sema.NewTypeAnnotation(xType), + } + + xConstructorDeclaration := stdlib.StandardLibraryValue{ + Name: "X", + Type: xConstructorType, + Kind: common.DeclarationKindConstant, + Value: interpreter.NewHostFunctionValue( + nil, + xConstructorType, + func(invocation interpreter.Invocation) interpreter.Value { + return interpreter.NewCompositeValue( + invocation.Interpreter, + invocation.LocationRange, + xType.Location, + xType.QualifiedIdentifier(), + xType.Kind, + nil, + common.ZeroAddress, + ) + }, + ), + } + + xTypeDeclaration := stdlib.StandardLibraryType{ + Name: "X", + Type: xType, + Kind: common.DeclarationKindType, + } + + script := []byte(` + access(all) + fun main(): String { + return X().foo(bar: 1) + } + `) + + runtime := NewTestInterpreterRuntime() + + runtimeInterface := &TestRuntimeInterface{ + Storage: NewTestLedger(nil, nil), + OnGetSigningAccounts: func() ([]Address, error) { + return []Address{common.MustBytesToAddress([]byte{0x1})}, nil + }, + OnResolveLocation: NewSingleIdentifierLocationResolver(t), + } + + // Run script + + scriptEnvironment := NewScriptInterpreterEnvironment(Config{}) + scriptEnvironment.DeclareValue(xConstructorDeclaration, nil) + scriptEnvironment.DeclareType(xTypeDeclaration, nil) + scriptEnvironment.SetCompositeValueFunctionsHandler( + xType.ID(), + func( + inter *interpreter.Interpreter, + locationRange interpreter.LocationRange, + compositeValue *interpreter.CompositeValue, + ) map[string]interpreter.FunctionValue { + require.NotNil(t, compositeValue) + + return map[string]interpreter.FunctionValue{ + fooFunctionName: interpreter.NewHostFunctionValue( + inter, + fooFunctionType, + func(invocation interpreter.Invocation) interpreter.Value { + arg := invocation.Arguments[0] + require.IsType(t, interpreter.UInt8Value(0), arg) + + return interpreter.NewUnmeteredStringValue(strconv.Itoa(int(arg.(interpreter.UInt8Value) + 1))) + }, + ), + } + }, + ) + + result, err := runtime.ExecuteScript( + Script{ + Source: script, + }, + Context{ + Interface: runtimeInterface, + Location: common.ScriptLocation{}, + Environment: scriptEnvironment, + }, + ) + require.NoError(t, err) + + require.Equal(t, + cadence.String("2"), + result, + ) + +} diff --git a/runtime/repl.go b/runtime/repl.go index f48ef9b23a..135df8eb10 100644 --- a/runtime/repl.go +++ b/runtime/repl.go @@ -87,7 +87,9 @@ func NewREPL() (*REPL, error) { defer func() { uuid++ }() return uuid, nil }, - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, OnEventEmitted: standardLibraryHandler.NewOnEventEmittedHandler(), } @@ -342,7 +344,7 @@ func (r *REPL) Suggestions() (result []REPLSuggestion) { names[name] = variable.Type.String() }) - _ = r.checker.Config.BaseValueActivation.ForEach(func(name string, variable *sema.Variable) error { + _ = r.checker.Config.BaseValueActivationHandler(nil).ForEach(func(name string, variable *sema.Variable) error { if names[name] == "" { names[name] = variable.Type.String() } diff --git a/runtime/sema/check_composite_declaration.go b/runtime/sema/check_composite_declaration.go index 73545b94c9..574d6d02c9 100644 --- a/runtime/sema/check_composite_declaration.go +++ b/runtime/sema/check_composite_declaration.go @@ -1793,8 +1793,10 @@ func (checker *Checker) defaultMembersAndOrigins( functionAccess := checker.accessFromAstAccess(function.Access) functionType := checker.functionType( + function.IsNative(), function.Purity, functionAccess, + function.TypeParameterList, function.ParameterList, function.ReturnTypeAnnotation, ) diff --git a/runtime/sema/check_function.go b/runtime/sema/check_function.go index 5d706b943e..181d497b12 100644 --- a/runtime/sema/check_function.go +++ b/runtime/sema/check_function.go @@ -100,7 +100,15 @@ func (checker *Checker) visitFunctionDeclaration( access := checker.accessFromAstAccess(declaration.Access) if functionType == nil { - functionType = checker.functionType(declaration.Purity, access, declaration.ParameterList, declaration.ReturnTypeAnnotation) + + functionType = checker.functionType( + declaration.IsNative(), + declaration.Purity, + access, + declaration.TypeParameterList, + declaration.ParameterList, + declaration.ReturnTypeAnnotation, + ) if options.declareFunction { checker.declareFunctionDeclaration(declaration, functionType) @@ -493,8 +501,10 @@ func (checker *Checker) VisitFunctionExpression(expression *ast.FunctionExpressi // TODO: infer functionType := checker.functionType( + false, expression.Purity, UnauthorizedAccess, + nil, expression.ParameterList, expression.ReturnTypeAnnotation, ) diff --git a/runtime/sema/checker.go b/runtime/sema/checker.go index bbec00d501..363ee94f78 100644 --- a/runtime/sema/checker.go +++ b/runtime/sema/checker.go @@ -67,7 +67,9 @@ var beforeType = func() *FunctionType { } }() -type ValidTopLevelDeclarationsHandlerFunc = func(common.Location) common.DeclarationKindSet +type ValidTopLevelDeclarationsHandlerFunc func(common.Location) common.DeclarationKindSet + +type ActivationHandlerFunc func(common.Location) *VariableActivation type CheckHandlerFunc func(checker *Checker, check func()) @@ -134,6 +136,21 @@ var baseFunctionType = NewSimpleFunctionType( VoidTypeAnnotation, ) +func NewVariableActivationsFromHandler( + handler ActivationHandlerFunc, + location common.Location, + defaultActivation *VariableActivation, +) *VariableActivations { + var activation *VariableActivation + if handler != nil { + activation = handler(location) + } + if activation == nil { + activation = defaultActivation + } + return NewVariableActivations(activation) +} + func NewChecker( program *ast.Program, location common.Location, @@ -174,19 +191,19 @@ func NewChecker( // Initialize value activations - baseValueActivation := config.BaseValueActivation - if baseValueActivation == nil { - baseValueActivation = BaseValueActivation - } - checker.valueActivations = NewVariableActivations(baseValueActivation) + checker.valueActivations = NewVariableActivationsFromHandler( + config.BaseValueActivationHandler, + location, + BaseValueActivation, + ) // Initialize type activations - baseTypeActivation := config.BaseTypeActivation - if baseTypeActivation == nil { - baseTypeActivation = BaseTypeActivation - } - checker.typeActivations = NewVariableActivations(baseTypeActivation) + checker.typeActivations = NewVariableActivationsFromHandler( + config.BaseTypeActivationHandler, + location, + BaseTypeActivation, + ) // Initialize position info, if enabled if checker.Config.PositionInfoEnabled { @@ -492,8 +509,10 @@ func (checker *Checker) checkTopLevelDeclarationValidity( func (checker *Checker) declareGlobalFunctionDeclaration(declaration *ast.FunctionDeclaration) { functionType := checker.functionType( + declaration.IsNative(), declaration.Purity, UnauthorizedAccess, + declaration.TypeParameterList, declaration.ParameterList, declaration.ReturnTypeAnnotation, ) @@ -1256,8 +1275,10 @@ func (checker *Checker) ConvertTypeAnnotation(typeAnnotation *ast.TypeAnnotation } func (checker *Checker) functionType( + isNative bool, purity ast.FunctionPurity, access Access, + typeParameterList *ast.TypeParameterList, parameterList *ast.ParameterList, returnTypeAnnotation *ast.TypeAnnotation, ) *FunctionType { @@ -1270,8 +1291,59 @@ func (checker *Checker) functionType( } defer func() { checker.entitlementMappingInScope = oldMappedAccess }() + // Convert type parameters (if any) + + var convertedTypeParameters []*TypeParameter + if typeParameterList != nil { + + // Only native functions may have type parameters at the moment + if !isNative && !typeParameterList.IsEmpty() { + checker.report(&InvalidTypeParameterizedNonNativeFunctionError{ + Range: ast.NewRangeFromPositioned( + checker.memoryGauge, + typeParameterList, + ), + }) + } + + checker.typeActivations.Enter() + defer checker.typeActivations.Leave(func(gauge common.MemoryGauge) ast.Position { + if returnTypeAnnotation != nil { + return returnTypeAnnotation.EndPosition(gauge) + } else { + return parameterList.EndPos + } + }) + + // All type parameters are converted at once, + // so type bounds may currently not refer to previous type parameters + + convertedTypeParameters = checker.typeParameters(typeParameterList) + + for typeParameterIndex, typeParameter := range typeParameterList.TypeParameters { + convertedTypeParameter := convertedTypeParameters[typeParameterIndex] + + genericType := &GenericType{ + TypeParameter: convertedTypeParameter, + } + + _, err := checker.typeActivations.declareType(typeDeclaration{ + identifier: typeParameter.Identifier, + ty: genericType, + declarationKind: common.DeclarationKindTypeParameter, + allowOuterScopeShadowing: false, + }) + checker.report(err) + + } + } + + // Convert parameters + convertedParameters := checker.parameters(parameterList) + // Convert return type + convertedReturnTypeAnnotation := VoidTypeAnnotation if returnTypeAnnotation != nil { convertedReturnTypeAnnotation = @@ -1280,11 +1352,40 @@ func (checker *Checker) functionType( return &FunctionType{ Purity: PurityFromAnnotation(purity), + TypeParameters: convertedTypeParameters, Parameters: convertedParameters, ReturnTypeAnnotation: convertedReturnTypeAnnotation, } } +func (checker *Checker) typeParameters(typeParameterList *ast.TypeParameterList) []*TypeParameter { + + var typeParameters []*TypeParameter + + typeParameterCount := len(typeParameterList.TypeParameters) + if typeParameterCount > 0 { + typeParameters = make([]*TypeParameter, typeParameterCount) + + for i, typeParameter := range typeParameterList.TypeParameters { + + typeBoundAnnotation := typeParameter.TypeBound + var convertedTypeBound Type + if typeBoundAnnotation != nil { + convertedTypeBoundAnnotation := checker.ConvertTypeAnnotation(typeBoundAnnotation) + checker.checkTypeAnnotation(convertedTypeBoundAnnotation, typeBoundAnnotation) + convertedTypeBound = convertedTypeBoundAnnotation.Type + } + + typeParameters[i] = &TypeParameter{ + Name: typeParameter.Identifier.Identifier, + TypeBound: convertedTypeBound, + } + } + } + + return typeParameters +} + func (checker *Checker) parameters(parameterList *ast.ParameterList) []Parameter { // TODO: required for initializer conformance checking at the moment, optimize/refactor diff --git a/runtime/sema/config.go b/runtime/sema/config.go index 7221f8cad3..0aec4a095d 100644 --- a/runtime/sema/config.go +++ b/runtime/sema/config.go @@ -26,10 +26,10 @@ type Config struct { // ValidTopLevelDeclarationsHandler is used to determine the kinds of declarations // which are valid at the top-level for a given location ValidTopLevelDeclarationsHandler ValidTopLevelDeclarationsHandlerFunc - BaseTypeActivation *VariableActivation + BaseTypeActivationHandler ActivationHandlerFunc + BaseValueActivationHandler ActivationHandlerFunc // ImportHandler is used to resolve unresolved imports - ImportHandler ImportHandlerFunc - BaseValueActivation *VariableActivation + ImportHandler ImportHandlerFunc // CheckHandler is the function which is used for the checking of a program CheckHandler CheckHandlerFunc // LocationHandler is used to resolve locations diff --git a/runtime/sema/errors.go b/runtime/sema/errors.go index f61d1d0495..5c4fd92b67 100644 --- a/runtime/sema/errors.go +++ b/runtime/sema/errors.go @@ -4726,3 +4726,20 @@ func (e *InvalidAttachmentEntitlementError) StartPosition() ast.Position { func (e *InvalidAttachmentEntitlementError) EndPosition(common.MemoryGauge) ast.Position { return e.Pos } + +// InvalidTypeParameterizedNonNativeFunctionError + +type InvalidTypeParameterizedNonNativeFunctionError struct { + ast.Range +} + +var _ SemanticError = &InvalidTypeParameterizedNonNativeFunctionError{} +var _ errors.UserError = &InvalidTypeParameterizedNonNativeFunctionError{} + +func (*InvalidTypeParameterizedNonNativeFunctionError) isSemanticError() {} + +func (*InvalidTypeParameterizedNonNativeFunctionError) IsUserError() {} + +func (e *InvalidTypeParameterizedNonNativeFunctionError) Error() string { + return "invalid type parameters in non-native function" +} diff --git a/runtime/sema/gen/golden_test.go b/runtime/sema/gen/golden_test.go index 6eccdc779d..27dd86b5db 100644 --- a/runtime/sema/gen/golden_test.go +++ b/runtime/sema/gen/golden_test.go @@ -63,7 +63,9 @@ func TestConstructor(t *testing.T) { `, checker.ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -87,7 +89,9 @@ func TestContract(t *testing.T) { `, checker.ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/stdlib/account.go b/runtime/stdlib/account.go index 673fba1a78..4a60a3b369 100644 --- a/runtime/stdlib/account.go +++ b/runtime/stdlib/account.go @@ -619,8 +619,6 @@ func newAccountKeysAddFunction( locationRange, accountKey, handler, - handler, - handler, ) }, ) @@ -691,8 +689,6 @@ func newAccountKeysGetFunction( locationRange, accountKey, provider, - provider, - provider, ), ) }, @@ -743,8 +739,6 @@ func newAccountKeysForEachFunction( locationRange, key, provider, - provider, - provider, ) } @@ -893,8 +887,6 @@ func newAccountKeysRevokeFunction( locationRange, accountKey, handler, - handler, - handler, ), ) }, @@ -2082,8 +2074,6 @@ func NewAccountKeyValue( inter *interpreter.Interpreter, locationRange interpreter.LocationRange, accountKey *AccountKey, - publicKeySignatureVerifier PublicKeySignatureVerifier, - blsPoPVerifier BLSPoPVerifier, hasher Hasher, ) interpreter.Value { @@ -2100,8 +2090,6 @@ func NewAccountKeyValue( inter, locationRange, accountKey.PublicKey, - publicKeySignatureVerifier, - blsPoPVerifier, ), hashAlgorithm, interpreter.NewUFix64ValueWithInteger( diff --git a/runtime/stdlib/bls.go b/runtime/stdlib/bls.go index 62cc7ad6ae..17348cb118 100644 --- a/runtime/stdlib/bls.go +++ b/runtime/stdlib/bls.go @@ -89,8 +89,6 @@ func newBLSAggregatePublicKeysFunction( inter, locationRange, aggregatedPublicKey, - aggregator, - aggregator, ) return interpreter.NewSomeValueNonCopying( diff --git a/runtime/stdlib/builtin.go b/runtime/stdlib/builtin.go index d292eb1bef..e1f085899f 100644 --- a/runtime/stdlib/builtin.go +++ b/runtime/stdlib/builtin.go @@ -18,6 +18,12 @@ package stdlib +import ( + "github.com/onflow/cadence/runtime/common" + "github.com/onflow/cadence/runtime/interpreter" + "github.com/onflow/cadence/runtime/sema" +) + type StandardLibraryHandler interface { Logger UnsafeRandomGenerator @@ -44,7 +50,7 @@ func DefaultStandardLibraryValues(handler StandardLibraryHandler) []StandardLibr NewGetCurrentBlockFunction(handler), NewGetAccountFunction(handler), NewAccountConstructor(handler), - NewPublicKeyConstructor(handler, handler, handler), + NewPublicKeyConstructor(handler), NewBLSContract(nil, handler), NewHashAlgorithmConstructor(handler), } @@ -56,3 +62,25 @@ func DefaultScriptStandardLibraryValues(handler StandardLibraryHandler) []Standa NewGetAuthAccountFunction(handler), ) } + +type CompositeValueFunctionsHandler func( + inter *interpreter.Interpreter, + locationRange interpreter.LocationRange, + compositeValue *interpreter.CompositeValue, +) map[string]interpreter.FunctionValue + +type CompositeValueFunctionsHandlers map[common.TypeID]CompositeValueFunctionsHandler + +func DefaultStandardLibraryCompositeValueFunctionHandlers( + handler StandardLibraryHandler, +) CompositeValueFunctionsHandlers { + return CompositeValueFunctionsHandlers{ + sema.PublicKeyType.ID(): func( + inter *interpreter.Interpreter, + _ interpreter.LocationRange, + _ *interpreter.CompositeValue, + ) map[string]interpreter.FunctionValue { + return PublicKeyFunctions(inter, handler) + }, + } +} diff --git a/runtime/stdlib/builtin_test.go b/runtime/stdlib/builtin_test.go index 6ea23b815e..1a3ac6f287 100644 --- a/runtime/stdlib/builtin_test.go +++ b/runtime/stdlib/builtin_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/onflow/cadence/runtime/activations" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/tests/checker" "github.com/stretchr/testify/assert" @@ -55,8 +56,10 @@ func newInterpreter(t *testing.T, code string, valueDeclarations ...StandardLibr utils.TestLocation, nil, &sema.Config{ - BaseValueActivation: baseValueActivation, - AccessCheckMode: sema.AccessCheckModeStrict, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AccessCheckMode: sema.AccessCheckModeStrict, }, ) require.NoError(t, err) @@ -75,8 +78,10 @@ func newInterpreter(t *testing.T, code string, valueDeclarations ...StandardLibr interpreter.ProgramFromChecker(checker), checker.Location, &interpreter.Config{ - Storage: storage, - BaseActivation: baseActivation, + Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, ) require.NoError(t, err) @@ -99,7 +104,9 @@ func TestCheckAssert(t *testing.T) { code, checker.ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -215,7 +222,9 @@ func TestCheckPanic(t *testing.T) { code, checker.ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/stdlib/publickey.go b/runtime/stdlib/publickey.go index ef27bebc3a..854939269f 100644 --- a/runtime/stdlib/publickey.go +++ b/runtime/stdlib/publickey.go @@ -77,8 +77,6 @@ func newPublicKeyValidationHandler(validator PublicKeyValidator) interpreter.Pub func NewPublicKeyConstructor( publicKeyValidator PublicKeyValidator, - publicKeySignatureVerifier PublicKeySignatureVerifier, - blsPoPVerifier BLSPoPVerifier, ) StandardLibraryValue { return NewStandardLibraryFunction( sema.PublicKeyTypeName, @@ -105,8 +103,6 @@ func NewPublicKeyConstructor( publicKey, signAlgo, publicKeyValidator, - publicKeySignatureVerifier, - blsPoPVerifier, ) }, ) @@ -118,8 +114,6 @@ func NewPublicKeyFromFields( publicKey *interpreter.ArrayValue, signAlgo *interpreter.SimpleCompositeValue, publicKeyValidator PublicKeyValidator, - publicKeySignatureVerifier PublicKeySignatureVerifier, - blsPoPVerifier BLSPoPVerifier, ) *interpreter.CompositeValue { return interpreter.NewPublicKeyValue( inter, @@ -127,8 +121,6 @@ func NewPublicKeyFromFields( publicKey, signAlgo, newPublicKeyValidationHandler(publicKeyValidator), - newPublicKeyVerifySignatureFunction(inter, publicKeySignatureVerifier), - newPublicKeyVerifyPoPFunction(inter, blsPoPVerifier), ) } @@ -140,8 +132,6 @@ func NewPublicKeyValue( inter *interpreter.Interpreter, locationRange interpreter.LocationRange, publicKey *PublicKey, - publicKeySignatureVerifier PublicKeySignatureVerifier, - blsPoPVerifier BLSPoPVerifier, ) *interpreter.CompositeValue { return interpreter.NewPublicKeyValue( inter, @@ -155,8 +145,6 @@ func NewPublicKeyValue( ), // public keys converted from "native" (non-interpreter) keys are assumed to be already validated assumePublicKeyIsValid, - newPublicKeyVerifySignatureFunction(inter, publicKeySignatureVerifier), - newPublicKeyVerifyPoPFunction(inter, blsPoPVerifier), ) } @@ -224,7 +212,7 @@ type PublicKeySignatureVerifier interface { func newPublicKeyVerifySignatureFunction( gauge common.MemoryGauge, - verififier PublicKeySignatureVerifier, + verifier PublicKeySignatureVerifier, ) *interpreter.HostFunctionValue { return interpreter.NewHostFunctionValue( gauge, @@ -283,7 +271,7 @@ func newPublicKeyVerifySignatureFunction( var valid bool errors.WrapPanic(func() { - valid, err = verififier.VerifySignature( + valid, err = verifier.VerifySignature( signature, domainSeparationTag, signedData, @@ -353,3 +341,18 @@ func newPublicKeyVerifyPoPFunction( }, ) } + +type PublicKeyFunctionsHandler interface { + PublicKeySignatureVerifier + BLSPoPVerifier +} + +func PublicKeyFunctions( + gauge common.MemoryGauge, + handler PublicKeyFunctionsHandler, +) map[string]interpreter.FunctionValue { + return map[string]interpreter.FunctionValue{ + sema.PublicKeyTypeVerifyFunctionName: newPublicKeyVerifySignatureFunction(gauge, handler), + sema.PublicKeyTypeVerifyPoPFunctionName: newPublicKeyVerifyPoPFunction(gauge, handler), + } +} diff --git a/runtime/stdlib/test_contract.go b/runtime/stdlib/test_contract.go index 2467f48331..fb0737b675 100644 --- a/runtime/stdlib/test_contract.go +++ b/runtime/stdlib/test_contract.go @@ -930,8 +930,10 @@ func newTestContractType() *TestContractType { TestContractLocation, nil, &sema.Config{ - BaseValueActivation: activation, - AccessCheckMode: sema.AccessCheckModeStrict, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return activation + }, + AccessCheckMode: sema.AccessCheckModeStrict, }, ) if err != nil { diff --git a/runtime/stdlib/test_emulatorbackend.go b/runtime/stdlib/test_emulatorbackend.go index 1e087139ea..1fa3d6eef6 100644 --- a/runtime/stdlib/test_emulatorbackend.go +++ b/runtime/stdlib/test_emulatorbackend.go @@ -303,7 +303,6 @@ func (t *testEmulatorBackendType) newCreateAccountFunction( locationRange := invocation.LocationRange return newTestAccountValue( - blockchain, inter, locationRange, account, @@ -313,7 +312,6 @@ func (t *testEmulatorBackendType) newCreateAccountFunction( } func newTestAccountValue( - blockchain Blockchain, inter *interpreter.Interpreter, locationRange interpreter.LocationRange, account *Account, @@ -322,14 +320,10 @@ func newTestAccountValue( // Create address value address := interpreter.NewAddressValue(nil, account.Address) - standardLibraryHandler := blockchain.StandardLibraryHandler() - publicKey := NewPublicKeyValue( inter, locationRange, account.PublicKey, - standardLibraryHandler, - standardLibraryHandler, ) // Create an 'Account' by calling its constructor. @@ -382,7 +376,6 @@ func (t *testEmulatorBackendType) newGetAccountFunction( locationRange := invocation.LocationRange return newTestAccountValue( - blockchain, inter, locationRange, account, @@ -645,7 +638,6 @@ func (t *testEmulatorBackendType) newServiceAccountFunction( } return newTestAccountValue( - blockchain, invocation.Interpreter, invocation.LocationRange, serviceAccount, diff --git a/runtime/stdlib/test_test.go b/runtime/stdlib/test_test.go index 6a3a2e4af4..a2c00688a8 100644 --- a/runtime/stdlib/test_test.go +++ b/runtime/stdlib/test_test.go @@ -61,17 +61,19 @@ func newTestContractInterpreterWithTestFramework( ) require.NoError(t, err) - activation := sema.NewVariableActivation(sema.BaseValueActivation) - activation.DeclareValue(stdlib.AssertFunction) - activation.DeclareValue(stdlib.PanicFunction) + baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) + baseValueActivation.DeclareValue(stdlib.AssertFunction) + baseValueActivation.DeclareValue(stdlib.PanicFunction) checker, err := sema.NewChecker( program, utils.TestLocation, nil, &sema.Config{ - BaseValueActivation: activation, - AccessCheckMode: sema.AccessCheckModeStrict, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AccessCheckMode: sema.AccessCheckModeStrict, ImportHandler: func( checker *sema.Checker, importedLocation common.Location, @@ -110,8 +112,10 @@ func newTestContractInterpreterWithTestFramework( interpreter.ProgramFromChecker(checker), checker.Location, &interpreter.Config{ - Storage: storage, - BaseActivation: baseActivation, + Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, ImportLocationHandler: func(inter *interpreter.Interpreter, location common.Location) interpreter.Import { if location == stdlib.TestContractLocation { program := interpreter.ProgramFromChecker(stdlib.GetTestContractType().Checker) diff --git a/runtime/tests/checker/assert_test.go b/runtime/tests/checker/assert_test.go index c41f0b1d1b..4cc699cb05 100644 --- a/runtime/tests/checker/assert_test.go +++ b/runtime/tests/checker/assert_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" ) @@ -42,7 +43,9 @@ func TestCheckAssertWithoutMessage(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -65,7 +68,9 @@ func TestCheckAssertWithMessage(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/tests/checker/capability_controller_test.go b/runtime/tests/checker/capability_controller_test.go index 717c4436a2..ee018bdeed 100644 --- a/runtime/tests/checker/capability_controller_test.go +++ b/runtime/tests/checker/capability_controller_test.go @@ -44,7 +44,9 @@ func TestCheckStorageCapabilityController(t *testing.T) { code, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseActivation + }, }, }, ) @@ -105,7 +107,9 @@ func TestCheckAccountCapabilityController(t *testing.T) { code, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseActivation + }, }, }, ) diff --git a/runtime/tests/checker/crypto_test.go b/runtime/tests/checker/crypto_test.go index b7174e2e34..f512362247 100644 --- a/runtime/tests/checker/crypto_test.go +++ b/runtime/tests/checker/crypto_test.go @@ -24,6 +24,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" ) @@ -48,7 +49,9 @@ func TestCheckHashAlgorithmCases(t *testing.T) { ), ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -74,7 +77,9 @@ func TestCheckHashAlgorithmConstructor(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -97,7 +102,9 @@ func TestCheckHashAlgorithmHashFunctions(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -123,7 +130,9 @@ func TestCheckSignatureAlgorithmCases(t *testing.T) { ), ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -149,7 +158,9 @@ func TestCheckSignatureAlgorithmConstructor(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -176,7 +187,9 @@ func TestCheckVerifyPoP(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -203,7 +216,9 @@ func TestCheckVerifyPoPInvalidArgument(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -227,7 +242,9 @@ func TestCheckBLSAggregateSignatures(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -248,7 +265,9 @@ func TestCheckInvalidBLSAggregateSignatures(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -279,7 +298,9 @@ func TestCheckBLSAggregatePublicKeys(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -302,7 +323,9 @@ func TestCheckInvalidBLSAggregatePublicKeys(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/tests/checker/genericfunction_test.go b/runtime/tests/checker/genericfunction_test.go index a6b99e38f6..00ccd2fc5a 100644 --- a/runtime/tests/checker/genericfunction_test.go +++ b/runtime/tests/checker/genericfunction_test.go @@ -27,6 +27,7 @@ import ( "github.com/onflow/cadence/runtime/ast" "github.com/onflow/cadence/runtime/common" + "github.com/onflow/cadence/runtime/parser" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" ) @@ -44,13 +45,15 @@ func parseAndCheckWithTestValue(t *testing.T, code string, ty sema.Type) (*sema. code, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) } -func TestCheckGenericFunction(t *testing.T) { +func TestCheckGenericFunctionInvocation(t *testing.T) { t.Parallel() @@ -896,7 +899,7 @@ func TestCheckBorrowOfCapabilityWithoutTypeArgument(t *testing.T) { require.NoError(t, err) } -func TestCheckUnparameterizedTypeInstantiationE(t *testing.T) { +func TestCheckInvalidUnparameterizedTypeInstantiation(t *testing.T) { t.Parallel() @@ -910,3 +913,210 @@ func TestCheckUnparameterizedTypeInstantiationE(t *testing.T) { assert.IsType(t, &sema.UnparameterizedTypeInstantiationError{}, errs[0]) } + +func TestCheckGenericFunctionDeclaration(t *testing.T) { + + t.Parallel() + + t.Run("global, non-native", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheckWithOptions(t, ` + fun head(_ items: [T]): T? { return nil } + + let x: Int? = head([1, 2, 3]) + `, + ParseAndCheckOptions{ + Config: &sema.Config{ + AllowNativeDeclarations: false, + }, + ParseOptions: parser.Config{ + NativeModifierEnabled: false, + TypeParametersEnabled: true, + }, + }, + ) + + errs := RequireCheckerErrors(t, err, 1) + + assert.IsType(t, &sema.InvalidTypeParameterizedNonNativeFunctionError{}, errs[0]) + }) + + t.Run("global, native", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheckWithOptions(t, ` + native fun head(_ items: [T]): T? {} + + let x: Int? = head([1, 2, 3]) + `, + ParseAndCheckOptions{ + Config: &sema.Config{ + AllowNativeDeclarations: true, + }, + ParseOptions: parser.Config{ + NativeModifierEnabled: true, + TypeParametersEnabled: true, + }, + }, + ) + + require.NoError(t, err) + }) + + t.Run("composite function, non-native", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheckWithOptions(t, ` + struct S { + fun head(_ items: [T]): T? { return nil } + } + + let x: Int? = S().head([1, 2, 3]) + `, + ParseAndCheckOptions{ + Config: &sema.Config{ + AllowNativeDeclarations: false, + }, + ParseOptions: parser.Config{ + NativeModifierEnabled: false, + TypeParametersEnabled: true, + }, + }, + ) + + errs := RequireCheckerErrors(t, err, 1) + + assert.IsType(t, &sema.InvalidTypeParameterizedNonNativeFunctionError{}, errs[0]) + }) + + t.Run("composite function, non-native", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheckWithOptions(t, ` + struct S { + native fun head(_ items: [T]): T? {} + } + + let x: Int? = S().head([1, 2, 3]) + `, + ParseAndCheckOptions{ + Config: &sema.Config{ + AllowNativeDeclarations: true, + }, + ParseOptions: parser.Config{ + NativeModifierEnabled: true, + TypeParametersEnabled: true, + }, + }, + ) + + require.NoError(t, err) + }) + + t.Run("too many type arguments", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheckWithOptions(t, + ` + native fun test() {} + + let x = test() + `, + ParseAndCheckOptions{ + Config: &sema.Config{ + AllowNativeDeclarations: true, + }, + ParseOptions: parser.Config{ + NativeModifierEnabled: true, + TypeParametersEnabled: true, + }, + }, + ) + + errs := RequireCheckerErrors(t, err, 1) + + require.IsType(t, &sema.InvalidTypeArgumentCountError{}, errs[0]) + }) + + t.Run("too few type arguments", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheckWithOptions(t, + ` + native fun test() {} + + let x = test() + `, + ParseAndCheckOptions{ + Config: &sema.Config{ + AllowNativeDeclarations: true, + }, + ParseOptions: parser.Config{ + NativeModifierEnabled: true, + TypeParametersEnabled: true, + }, + }, + ) + + errs := RequireCheckerErrors(t, err, 1) + + require.IsType(t, &sema.TypeParameterTypeInferenceError{}, errs[0]) + }) + + t.Run("type parameter usage in following type parameter", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheckWithOptions(t, + ` + native fun test(_ u: U): U {} + `, + ParseAndCheckOptions{ + Config: &sema.Config{ + AllowNativeDeclarations: true, + }, + ParseOptions: parser.Config{ + NativeModifierEnabled: true, + TypeParametersEnabled: true, + }, + }, + ) + + errs := RequireCheckerErrors(t, err, 1) + + assert.IsType(t, &sema.NotDeclaredError{}, errs[0]) + }) + + t.Run("type bound is checked", func(t *testing.T) { + + t.Parallel() + + _, err := ParseAndCheckWithOptions(t, + ` + native fun test() {} + + let x = test() + `, + ParseAndCheckOptions{ + Config: &sema.Config{ + AllowNativeDeclarations: true, + }, + ParseOptions: parser.Config{ + NativeModifierEnabled: true, + TypeParametersEnabled: true, + }, + }, + ) + + errs := RequireCheckerErrors(t, err, 1) + + require.IsType(t, &sema.TypeMismatchError{}, errs[0]) + }) +} diff --git a/runtime/tests/checker/interface_test.go b/runtime/tests/checker/interface_test.go index 24446e9677..0eae0fcd4e 100644 --- a/runtime/tests/checker/interface_test.go +++ b/runtime/tests/checker/interface_test.go @@ -1695,6 +1695,13 @@ func BenchmarkCheckContractInterfaceFungibleTokenConformance(b *testing.B) { baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) baseValueActivation.DeclareValue(stdlib.PanicFunction) + config := &sema.Config{ + AccessCheckMode: sema.AccessCheckModeNotSpecifiedUnrestricted, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + } + b.ReportAllocs() b.ResetTimer() @@ -1703,10 +1710,7 @@ func BenchmarkCheckContractInterfaceFungibleTokenConformance(b *testing.B) { program, TestLocation, nil, - &sema.Config{ - AccessCheckMode: sema.AccessCheckModeNotSpecifiedUnrestricted, - BaseValueActivation: baseValueActivation, - }, + config, ) if err != nil { b.Fatal(err) diff --git a/runtime/tests/checker/invocation_test.go b/runtime/tests/checker/invocation_test.go index f084e6b198..7a19f13aa5 100644 --- a/runtime/tests/checker/invocation_test.go +++ b/runtime/tests/checker/invocation_test.go @@ -333,7 +333,9 @@ func TestCheckInvocationWithOnlyVarargs(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/tests/checker/nesting_test.go b/runtime/tests/checker/nesting_test.go index 273915aa34..47c125c638 100644 --- a/runtime/tests/checker/nesting_test.go +++ b/runtime/tests/checker/nesting_test.go @@ -328,7 +328,9 @@ func TestCheckNestedTypeInvalidChildType(t *testing.T) { `let u: T.U = nil`, ParseAndCheckOptions{ Config: &sema.Config{ - BaseTypeActivation: baseTypeActivation, + BaseTypeActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseTypeActivation + }, }, }, ) diff --git a/runtime/tests/checker/nft_test.go b/runtime/tests/checker/nft_test.go index 6be756487c..3070f26a26 100644 --- a/runtime/tests/checker/nft_test.go +++ b/runtime/tests/checker/nft_test.go @@ -997,7 +997,9 @@ access(all) contract TopShot: NonFungibleToken { Elaboration: nftChecker.Elaboration, }, nil }, - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/tests/checker/predeclaredvalues_test.go b/runtime/tests/checker/predeclaredvalues_test.go index cd69920f4f..ec9c9ceaa2 100644 --- a/runtime/tests/checker/predeclaredvalues_test.go +++ b/runtime/tests/checker/predeclaredvalues_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" ) @@ -51,7 +52,9 @@ func TestCheckPredeclaredValues(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/tests/checker/return_test.go b/runtime/tests/checker/return_test.go index 6c5ad9649c..8feb204fbb 100644 --- a/runtime/tests/checker/return_test.go +++ b/runtime/tests/checker/return_test.go @@ -25,6 +25,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" ) @@ -209,7 +210,9 @@ func testExits(t *testing.T, test exitTest) { code, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/tests/checker/rlp_test.go b/runtime/tests/checker/rlp_test.go index 65c93ef822..9b2c3950ac 100644 --- a/runtime/tests/checker/rlp_test.go +++ b/runtime/tests/checker/rlp_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" ) @@ -40,7 +41,9 @@ func TestCheckRLPDecodeString(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -60,7 +63,9 @@ func TestCheckInvalidRLPDecodeString(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -84,7 +89,9 @@ func TestCheckRLPDecodeList(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -104,7 +111,9 @@ func TestCheckInvalidRLPDecodeList(t *testing.T) { `, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/tests/checker/storable_test.go b/runtime/tests/checker/storable_test.go index 1126507fee..559da22a83 100644 --- a/runtime/tests/checker/storable_test.go +++ b/runtime/tests/checker/storable_test.go @@ -44,8 +44,10 @@ func TestCheckStorable(t *testing.T) { code, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, - AttachmentsEnabled: true, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AttachmentsEnabled: true, }, }, ) diff --git a/runtime/tests/checker/utils_test.go b/runtime/tests/checker/utils_test.go index 5e49dc708d..1c7a63804b 100644 --- a/runtime/tests/checker/utils_test.go +++ b/runtime/tests/checker/utils_test.go @@ -35,7 +35,9 @@ func ParseAndCheckWithPanic(t *testing.T, code string) (*sema.Checker, error) { code, ParseAndCheckOptions{ Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -54,7 +56,9 @@ func ParseAndCheckWithAny(t *testing.T, code string) (*sema.Checker, error) { code, ParseAndCheckOptions{ Config: &sema.Config{ - BaseTypeActivation: baseTypeActivation, + BaseTypeActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseTypeActivation + }, }, }, ) diff --git a/runtime/tests/interpreter/account_test.go b/runtime/tests/interpreter/account_test.go index 142eab408d..fb9091bb39 100644 --- a/runtime/tests/interpreter/account_test.go +++ b/runtime/tests/interpreter/account_test.go @@ -429,14 +429,15 @@ func testAccountWithErrorHandler( accountValueDeclaration.Name = "account" valueDeclarations = append(valueDeclarations, accountValueDeclaration) - if checkerConfig.BaseValueActivation == nil { - checkerConfig.BaseValueActivation = sema.BaseValueActivation - } - baseValueActivation := sema.NewVariableActivation(checkerConfig.BaseValueActivation) + baseValueActivation := sema.NewVariableActivation(sema.BaseValueActivation) for _, valueDeclaration := range valueDeclarations { baseValueActivation.DeclareValue(valueDeclaration) } - checkerConfig.BaseValueActivation = baseValueActivation + + require.Nil(t, checkerConfig.BaseValueActivationHandler) + checkerConfig.BaseValueActivationHandler = func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + } baseActivation := activations.NewActivation(nil, interpreter.BaseActivation) for _, valueDeclaration := range valueDeclarations { @@ -448,7 +449,9 @@ func testAccountWithErrorHandler( ParseCheckAndInterpretOptions{ CheckerConfig: &checkerConfig, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, ContractValueHandler: makeContractValueHandler(nil, nil, nil), InvalidatedResourceValidationEnabled: true, AccountHandler: func(address interpreter.AddressValue) interpreter.Value { diff --git a/runtime/tests/interpreter/attachments_test.go b/runtime/tests/interpreter/attachments_test.go index 616a73e92c..fc5e3b66f7 100644 --- a/runtime/tests/interpreter/attachments_test.go +++ b/runtime/tests/interpreter/attachments_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/onflow/cadence/runtime/activations" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/interpreter" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" @@ -2282,8 +2283,6 @@ func TestInterpretBuiltinCompositeAttachment(t *testing.T) { for _, valueDeclaration := range []stdlib.StandardLibraryValue{ stdlib.NewPublicKeyConstructor( assumeValidPublicKeyValidator{}, - nil, - nil, ), stdlib.SignatureAlgorithmConstructor, } { @@ -2310,11 +2309,15 @@ func TestInterpretBuiltinCompositeAttachment(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, - AttachmentsEnabled: true, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AttachmentsEnabled: true, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) diff --git a/runtime/tests/interpreter/composite_value_test.go b/runtime/tests/interpreter/composite_value_test.go index 97c824fd46..493d678d50 100644 --- a/runtime/tests/interpreter/composite_value_test.go +++ b/runtime/tests/interpreter/composite_value_test.go @@ -145,8 +145,12 @@ func testCompositeValue(t *testing.T, code string) *interpreter.Interpreter { code, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, - BaseTypeActivation: baseTypeActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + BaseTypeActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseTypeActivation + }, CheckHandler: func(checker *sema.Checker, check func()) { if checker.Location == TestLocation { checker.Elaboration.SetCompositeType( @@ -158,8 +162,10 @@ func testCompositeValue(t *testing.T, code string) *interpreter.Interpreter { }, }, Config: &interpreter.Config{ - Storage: storage, - BaseActivation: baseActivation, + Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) diff --git a/runtime/tests/interpreter/condition_test.go b/runtime/tests/interpreter/condition_test.go index 41ed2f404d..21990fc6b9 100644 --- a/runtime/tests/interpreter/condition_test.go +++ b/runtime/tests/interpreter/condition_test.go @@ -1426,10 +1426,14 @@ func TestInterpretFunctionWithPostConditionAndResourceResult(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) diff --git a/runtime/tests/interpreter/container_mutation_test.go b/runtime/tests/interpreter/container_mutation_test.go index 904ff2ece3..70842675dd 100644 --- a/runtime/tests/interpreter/container_mutation_test.go +++ b/runtime/tests/interpreter/container_mutation_test.go @@ -336,10 +336,14 @@ func TestInterpetArrayMutation(t *testing.T) { }`, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -475,10 +479,14 @@ func TestInterpetArrayMutation(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -726,10 +734,14 @@ func TestInterpretDictionaryMutation(t *testing.T) { }`, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -865,10 +877,14 @@ func TestInterpretDictionaryMutation(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) diff --git a/runtime/tests/interpreter/dynamic_casting_test.go b/runtime/tests/interpreter/dynamic_casting_test.go index 71c581cab2..36d0dd48cf 100644 --- a/runtime/tests/interpreter/dynamic_casting_test.go +++ b/runtime/tests/interpreter/dynamic_casting_test.go @@ -3384,10 +3384,14 @@ func TestInterpretDynamicCastingCapability(t *testing.T) { options := ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, } diff --git a/runtime/tests/interpreter/entitlements_test.go b/runtime/tests/interpreter/entitlements_test.go index 616faece8d..b9c4b5c40b 100644 --- a/runtime/tests/interpreter/entitlements_test.go +++ b/runtime/tests/interpreter/entitlements_test.go @@ -3099,7 +3099,7 @@ func TestInterpretIdentityMapping(t *testing.T) { }) } -func TestInterpretMappingInclude(t *testing.T) { +func NoTestInterpretMappingInclude(t *testing.T) { t.Parallel() diff --git a/runtime/tests/interpreter/equality_test.go b/runtime/tests/interpreter/equality_test.go index 834b3c91be..efe2a8d277 100644 --- a/runtime/tests/interpreter/equality_test.go +++ b/runtime/tests/interpreter/equality_test.go @@ -70,10 +70,14 @@ func TestInterpretEquality(t *testing.T) { `, ParseCheckAndInterpretOptions{ Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) diff --git a/runtime/tests/interpreter/interface_test.go b/runtime/tests/interpreter/interface_test.go index 59ffb437f2..a66b429611 100644 --- a/runtime/tests/interpreter/interface_test.go +++ b/runtime/tests/interpreter/interface_test.go @@ -25,6 +25,7 @@ import ( "github.com/stretchr/testify/require" "github.com/onflow/cadence/runtime/activations" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/interpreter" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" @@ -647,10 +648,14 @@ func TestInterpretInterfaceFunctionConditionsInheritance(t *testing.T) { }`, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(location common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -755,10 +760,14 @@ func TestInterpretInterfaceFunctionConditionsInheritance(t *testing.T) { }`, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(location common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -842,10 +851,14 @@ func TestInterpretInterfaceFunctionConditionsInheritance(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(location common.Location) *interpreter.VariableActivation { + return baseActivation + }, ContractValueHandler: makeContractValueHandler(nil, nil, nil), }, }, diff --git a/runtime/tests/interpreter/interpreter_test.go b/runtime/tests/interpreter/interpreter_test.go index 4c83de0a4c..0562b728c4 100644 --- a/runtime/tests/interpreter/interpreter_test.go +++ b/runtime/tests/interpreter/interpreter_test.go @@ -114,10 +114,14 @@ func parseCheckAndInterpretWithLogs( code, ParseCheckAndInterpretOptions{ Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, HandleCheckerError: nil, }, @@ -144,7 +148,9 @@ func parseCheckAndInterpretWithMemoryMetering( code, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, memoryGauge, @@ -2019,8 +2025,10 @@ func TestInterpretHostFunction(t *testing.T) { TestLocation, nil, &sema.Config{ - BaseValueActivation: baseValueActivation, - AccessCheckMode: sema.AccessCheckModeStrict, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AccessCheckMode: sema.AccessCheckModeStrict, }, ) require.NoError(t, err) @@ -2037,8 +2045,10 @@ func TestInterpretHostFunction(t *testing.T) { interpreter.ProgramFromChecker(checker), checker.Location, &interpreter.Config{ - Storage: storage, - BaseActivation: baseActivation, + Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, ) require.NoError(t, err) @@ -2126,8 +2136,10 @@ func TestInterpretHostFunctionWithVariableArguments(t *testing.T) { TestLocation, nil, &sema.Config{ - BaseValueActivation: baseValueActivation, - AccessCheckMode: sema.AccessCheckModeStrict, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AccessCheckMode: sema.AccessCheckModeStrict, }, ) require.NoError(t, err) @@ -2144,8 +2156,10 @@ func TestInterpretHostFunctionWithVariableArguments(t *testing.T) { interpreter.ProgramFromChecker(checker), checker.Location, &interpreter.Config{ - Storage: storage, - BaseActivation: baseActivation, + Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, ) require.NoError(t, err) @@ -2230,8 +2244,10 @@ func TestInterpretHostFunctionWithOptionalArguments(t *testing.T) { TestLocation, nil, &sema.Config{ - BaseValueActivation: baseValueActivation, - AccessCheckMode: sema.AccessCheckModeStrict, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AccessCheckMode: sema.AccessCheckModeStrict, }, ) require.NoError(t, err) @@ -2248,8 +2264,10 @@ func TestInterpretHostFunctionWithOptionalArguments(t *testing.T) { interpreter.ProgramFromChecker(checker), checker.Location, &interpreter.Config{ - Storage: storage, - BaseActivation: baseActivation, + Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, ) require.NoError(t, err) @@ -4233,7 +4251,9 @@ func TestInterpretImportError(t *testing.T) { checker.ParseAndCheckOptions{ Location: location, Config: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, ImportHandler: func(_ *sema.Checker, importedLocation common.Location, _ ast.Range) (sema.Import, error) { switch importedLocation { case importedLocation1: @@ -4293,8 +4313,10 @@ func TestInterpretImportError(t *testing.T) { interpreter.ProgramFromChecker(mainChecker), mainChecker.Location, &interpreter.Config{ - Storage: storage, - BaseActivation: baseActivation, + Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, ImportLocationHandler: func(inter *interpreter.Interpreter, location common.Location) interpreter.Import { var importedChecker *sema.Checker switch location { @@ -5247,11 +5269,15 @@ func TestInterpretReferenceFailableDowncasting(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - Storage: storage, - BaseActivation: baseActivation, + Storage: storage, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -7295,10 +7321,6 @@ func TestInterpretEmitEvent(t *testing.T) { ), } - for _, event := range expectedEvents { - event.(*interpreter.CompositeValue).InitializeFunctions(inter) - } - AssertValueSlicesEqual( t, inter, @@ -7389,17 +7411,12 @@ func TestInterpretReferenceEventParameter(t *testing.T) { ), } - for _, event := range expectedEvents { - event.(*interpreter.CompositeValue).InitializeFunctions(inter) - } - AssertValueSlicesEqual( t, inter, expectedEvents, actualEvents, ) - } type testValue struct { @@ -7687,8 +7704,12 @@ func TestInterpretEmitEventParameterTypes(t *testing.T) { inter, err := parseCheckAndInterpretWithOptions( t, code, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, - BaseTypeActivation: baseTypeActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + BaseTypeActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseTypeActivation + }, }, Config: &interpreter.Config{ Storage: storage, @@ -7730,10 +7751,6 @@ func TestInterpretEmitEventParameterTypes(t *testing.T) { ), } - for _, event := range expectedEvents { - event.(*interpreter.CompositeValue).InitializeFunctions(inter) - } - AssertValueSlicesEqual( t, inter, @@ -8275,10 +8292,14 @@ func TestInterpretOptionalChainingFieldReadAndNilCoalescing(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -8315,10 +8336,14 @@ func TestInterpretOptionalChainingFunctionCallAndNilCoalescing(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -8513,11 +8538,15 @@ func TestInterpretCompositeDeclarationNestedConstructor(t *testing.T) { code, ParseCheckAndInterpretOptions{ Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, ContractValueHandler: makeContractValueHandler(nil, nil, nil), }, CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, ) @@ -8983,10 +9012,14 @@ func TestInterpretHexDecode(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -9154,10 +9187,14 @@ func TestInterpretResourceOwnerFieldUse(t *testing.T) { code, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, AccountHandler: func(address interpreter.AddressValue) interpreter.Value { return stdlib.NewAccountValue(nil, nil, address) }, @@ -11287,10 +11324,14 @@ func TestInterpretNilCoalesceReference(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) diff --git a/runtime/tests/interpreter/invocation_test.go b/runtime/tests/interpreter/invocation_test.go index b319860e05..32ae2abf14 100644 --- a/runtime/tests/interpreter/invocation_test.go +++ b/runtime/tests/interpreter/invocation_test.go @@ -24,6 +24,7 @@ import ( "github.com/stretchr/testify/require" "github.com/onflow/cadence/runtime/activations" + "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/interpreter" "github.com/onflow/cadence/runtime/sema" "github.com/onflow/cadence/runtime/stdlib" @@ -81,12 +82,16 @@ func TestInterpretSelfDeclaration(t *testing.T) { inter, err := parseCheckAndInterpretWithOptions(t, code, ParseCheckAndInterpretOptions{ Config: &interpreter.Config{ - Storage: newUnmeteredInMemoryStorage(), - BaseActivation: baseActivation, + Storage: newUnmeteredInMemoryStorage(), + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, - AccessCheckMode: sema.AccessCheckModeNotSpecifiedUnrestricted, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AccessCheckMode: sema.AccessCheckModeNotSpecifiedUnrestricted, }, }) require.NoError(t, err) diff --git a/runtime/tests/interpreter/memory_metering_test.go b/runtime/tests/interpreter/memory_metering_test.go index 095ca5fabd..455911edb9 100644 --- a/runtime/tests/interpreter/memory_metering_test.go +++ b/runtime/tests/interpreter/memory_metering_test.go @@ -1057,10 +1057,14 @@ func TestInterpretHostFunctionMetering(t *testing.T) { script, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, meter, @@ -1091,8 +1095,6 @@ func TestInterpretHostFunctionMetering(t *testing.T) { for _, valueDeclaration := range []stdlib.StandardLibraryValue{ stdlib.NewPublicKeyConstructor( assumeValidPublicKeyValidator{}, - nil, - nil, ), stdlib.SignatureAlgorithmConstructor, } { @@ -1106,10 +1108,14 @@ func TestInterpretHostFunctionMetering(t *testing.T) { script, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, meter, @@ -1120,7 +1126,7 @@ func TestInterpretHostFunctionMetering(t *testing.T) { require.NoError(t, err) // 1 host function created for 'decodeHex' of String value - assert.Equal(t, uint64(3), meter.getMemory(common.MemoryKindHostFunctionValue)) + assert.Equal(t, uint64(1), meter.getMemory(common.MemoryKindHostFunctionValue)) }) t.Run("multiple public key creation", func(t *testing.T) { @@ -1145,8 +1151,6 @@ func TestInterpretHostFunctionMetering(t *testing.T) { for _, valueDeclaration := range []stdlib.StandardLibraryValue{ stdlib.NewPublicKeyConstructor( assumeValidPublicKeyValidator{}, - nil, - nil, ), stdlib.SignatureAlgorithmConstructor, } { @@ -1160,10 +1164,14 @@ func TestInterpretHostFunctionMetering(t *testing.T) { script, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, meter, @@ -1174,7 +1182,7 @@ func TestInterpretHostFunctionMetering(t *testing.T) { require.NoError(t, err) // 2 = 2x 1 host function created for 'decodeHex' of String value - assert.Equal(t, uint64(6), meter.getMemory(common.MemoryKindHostFunctionValue)) + assert.Equal(t, uint64(2), meter.getMemory(common.MemoryKindHostFunctionValue)) }) } @@ -8677,10 +8685,14 @@ func TestInterpretValueStringConversion(t *testing.T) { inter, err := parseCheckAndInterpretWithOptionsAndMemoryMetering(t, script, ParseCheckAndInterpretOptions{ Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, meter, @@ -9013,10 +9025,14 @@ func TestInterpretStaticTypeStringConversion(t *testing.T) { inter, err := parseCheckAndInterpretWithOptionsAndMemoryMetering(t, script, ParseCheckAndInterpretOptions{ Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, }, meter, diff --git a/runtime/tests/interpreter/metatype_test.go b/runtime/tests/interpreter/metatype_test.go index f28c252e5a..cee970ae6e 100644 --- a/runtime/tests/interpreter/metatype_test.go +++ b/runtime/tests/interpreter/metatype_test.go @@ -142,10 +142,14 @@ func TestInterpretMetaTypeEquality(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -198,10 +202,14 @@ func TestInterpretMetaTypeEquality(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -287,10 +295,14 @@ func TestInterpretMetaTypeIdentifier(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) @@ -440,10 +452,14 @@ func TestInterpretIsInstance(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { inter, err := parseCheckAndInterpretWithOptions(t, testCase.code, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }) require.NoError(t, err) @@ -580,10 +596,14 @@ func TestInterpretMetaTypeIsSubtype(t *testing.T) { t.Run(testCase.name, func(t *testing.T) { inter, err := parseCheckAndInterpretWithOptions(t, testCase.code, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseValueActivation: baseValueActivation, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }) require.NoError(t, err) @@ -801,6 +821,7 @@ func TestInterpretGetType(t *testing.T) { for _, testCase := range cases { address := interpreter.NewUnmeteredAddressValueFromBytes([]byte{42}) + t.Run(testCase.name, func(t *testing.T) { inter, _ := testAccount(t, address, true, nil, testCase.code, sema.Config{}) diff --git a/runtime/tests/interpreter/metering_test.go b/runtime/tests/interpreter/metering_test.go index f7f5d303b7..40f996d756 100644 --- a/runtime/tests/interpreter/metering_test.go +++ b/runtime/tests/interpreter/metering_test.go @@ -397,3 +397,118 @@ func TestInterpretFunctionInvocationHandler(t *testing.T) { occurrences, ) } + +func TestInterpretArrayFunctionsComputationMetering(t *testing.T) { + + t.Parallel() + + t.Run("reverse", func(t *testing.T) { + t.Parallel() + + computationMeteredValues := make(map[common.ComputationKind]uint) + inter, err := parseCheckAndInterpretWithOptions(t, ` + fun main() { + let x = [1, 2, 3] + let y = x.reverse() + }`, + ParseCheckAndInterpretOptions{ + Config: &interpreter.Config{ + OnMeterComputation: func(compKind common.ComputationKind, intensity uint) { + computationMeteredValues[compKind] += intensity + }, + }, + }, + ) + require.NoError(t, err) + + _, err = inter.Invoke("main") + require.NoError(t, err) + + assert.Equal(t, uint(3), computationMeteredValues[common.ComputationKindLoop]) + }) + + t.Run("map", func(t *testing.T) { + t.Parallel() + + computationMeteredValues := make(map[common.ComputationKind]uint) + inter, err := parseCheckAndInterpretWithOptions(t, ` + fun main() { + let x = [1, 2, 3, 4] + let trueForEven = fun (_ x: Int): Bool { + return x % 2 == 0 + } + let y = x.map(trueForEven) + }`, + ParseCheckAndInterpretOptions{ + Config: &interpreter.Config{ + OnMeterComputation: func(compKind common.ComputationKind, intensity uint) { + computationMeteredValues[compKind] += intensity + }, + }, + }, + ) + require.NoError(t, err) + + _, err = inter.Invoke("main") + require.NoError(t, err) + + assert.Equal(t, uint(5), computationMeteredValues[common.ComputationKindLoop]) + }) + + t.Run("filter", func(t *testing.T) { + t.Parallel() + + computationMeteredValues := make(map[common.ComputationKind]uint) + inter, err := parseCheckAndInterpretWithOptions(t, ` + fun main() { + let x = [1, 2, 3, 4, 5] + let onlyEven = view fun (_ x: Int): Bool { + return x % 2 == 0 + } + let y = x.filter(onlyEven) + }`, + ParseCheckAndInterpretOptions{ + Config: &interpreter.Config{ + OnMeterComputation: func(compKind common.ComputationKind, intensity uint) { + computationMeteredValues[compKind] += intensity + }, + }, + }, + ) + require.NoError(t, err) + + _, err = inter.Invoke("main") + require.NoError(t, err) + + assert.Equal(t, uint(6), computationMeteredValues[common.ComputationKindLoop]) + }) +} + +func TestInterpretStdlibComputationMetering(t *testing.T) { + + t.Parallel() + + t.Run("string join", func(t *testing.T) { + t.Parallel() + + computationMeteredValues := make(map[common.ComputationKind]uint) + inter, err := parseCheckAndInterpretWithOptions(t, ` + fun main() { + let s = String.join(["one", "two", "three", "four"], separator: ", ") + }`, + ParseCheckAndInterpretOptions{ + Config: &interpreter.Config{ + OnMeterComputation: func(compKind common.ComputationKind, intensity uint) { + computationMeteredValues[compKind] += intensity + }, + }, + }, + ) + require.NoError(t, err) + + _, err = inter.Invoke("main") + require.NoError(t, err) + + assert.Equal(t, uint(4), computationMeteredValues[common.ComputationKindLoop]) + }) +} diff --git a/runtime/tests/interpreter/transfer_test.go b/runtime/tests/interpreter/transfer_test.go index a7b4b5a4fd..ca91259d5a 100644 --- a/runtime/tests/interpreter/transfer_test.go +++ b/runtime/tests/interpreter/transfer_test.go @@ -76,11 +76,17 @@ func TestInterpretTransferCheck(t *testing.T) { `, ParseCheckAndInterpretOptions{ CheckerConfig: &sema.Config{ - BaseTypeActivation: baseTypeActivation, - BaseValueActivation: baseValueActivation, + BaseTypeActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseTypeActivation + }, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, }, Config: &interpreter.Config{ - BaseActivation: baseActivation, + BaseActivationHandler: func(_ common.Location) *interpreter.VariableActivation { + return baseActivation + }, }, }, ) diff --git a/tools/analysis/programs.go b/tools/analysis/programs.go index 99ebd821e9..4985cedd01 100644 --- a/tools/analysis/programs.go +++ b/tools/analysis/programs.go @@ -109,8 +109,10 @@ func (programs Programs) check( location, nil, &sema.Config{ - BaseValueActivation: baseValueActivation, - AccessCheckMode: sema.AccessCheckModeStrict, + BaseValueActivationHandler: func(_ common.Location) *sema.VariableActivation { + return baseValueActivation + }, + AccessCheckMode: sema.AccessCheckModeStrict, LocationHandler: sema.AddressLocationHandlerFunc( config.ResolveAddressContractNames, ),