Compare commits
17 Commits
cdeery/AA-
...
feat--remo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbca354df7 | ||
|
|
2230173da8 | ||
|
|
09072f318b | ||
|
|
1f7cb2cc28 | ||
|
|
c6ad7c51d3 | ||
|
|
20d4de09d7 | ||
|
|
5aa857f1de | ||
|
|
3fcc0d87c9 | ||
|
|
0bc7faaa56 | ||
|
|
0889b17e85 | ||
|
|
f57f39a787 | ||
|
|
20390d1e33 | ||
|
|
55b3396acd | ||
|
|
dae0c8931c | ||
|
|
dd6a499cfc | ||
|
|
0c006e28de | ||
|
|
bdba0d2c3c |
2
.env
2
.env
@@ -37,4 +37,4 @@ TWITTER_HASHTAG=''
|
||||
TWITTER_URL=''
|
||||
USER_INFO_COOKIE_NAME=''
|
||||
SESSION_COOKIE_DOMAIN=''
|
||||
ENABLE_JUMPNAV='true'
|
||||
ENABLE_NOTICES=''
|
||||
|
||||
@@ -37,4 +37,4 @@ TWITTER_HASHTAG='myedxjourney'
|
||||
TWITTER_URL='https://twitter.com/edXOnline'
|
||||
USER_INFO_COOKIE_NAME='edx-user-info'
|
||||
SESSION_COOKIE_DOMAIN='localhost'
|
||||
ENABLE_JUMPNAV='true'
|
||||
ENABLE_NOTICES=''
|
||||
|
||||
@@ -36,4 +36,4 @@ TERMS_OF_SERVICE_URL='https://www.edx.org/edx-terms-service'
|
||||
TWITTER_HASHTAG='myedxjourney'
|
||||
TWITTER_URL='https://twitter.com/edXOnline'
|
||||
USER_INFO_COOKIE_NAME='edx-user-info'
|
||||
ENABLE_JUMPNAV='true'
|
||||
ENABLE_NOTICES=''
|
||||
|
||||
10
.github/workflows/commitlint.yml
vendored
Normal file
10
.github/workflows/commitlint.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Run commitlint on the commit messages in a pull request.
|
||||
|
||||
name: Lint Commit Messages
|
||||
|
||||
on:
|
||||
- pull_request
|
||||
|
||||
jobs:
|
||||
commitlint:
|
||||
uses: edx/.github/.github/workflows/commitlint.yml@master
|
||||
@@ -109,9 +109,3 @@ TWITTER_URL
|
||||
unless this is set. Optional.
|
||||
|
||||
Example: https://twitter.com/edXOnline
|
||||
|
||||
ENABLE_JUMPNAV
|
||||
Enables the new Jump Navigation feature in the course breadcrumbs, defaulted to the string 'true'.
|
||||
Disable to have simple hyperlinks for breadcrumbs. Setting it to any other value but 'true' ('false','I love flags', 'etc' would disable the Jumpnav).
|
||||
This feature flag is slated to be removed as jumpnav becomes default. Follow the progress of this ticket here:
|
||||
https://openedx.atlassian.net/browse/TNL-8678
|
||||
|
||||
252
package-lock.json
generated
252
package-lock.json
generated
@@ -3663,9 +3663,9 @@
|
||||
}
|
||||
},
|
||||
"@edx/frontend-lib-special-exams": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-lib-special-exams/-/frontend-lib-special-exams-1.13.2.tgz",
|
||||
"integrity": "sha512-NzMgyVAg63x6vg0vSe00MhREyeRSyXE16aBt/34XQHXQKG0ieEVnu3o3oQdlgzu2JWzGxxVmZr4gGeYB3qA7hQ==",
|
||||
"version": "1.13.3",
|
||||
"resolved": "https://registry.npmjs.org/@edx/frontend-lib-special-exams/-/frontend-lib-special-exams-1.13.3.tgz",
|
||||
"integrity": "sha512-WTjOPh/Rr6wAKImRdmJaO4g2u+Q0pxw/FLzS7PJ0cE63hoMM8VsVL6diS1Alg01mG5DYXuiX8QyHb9lk0pJzdw==",
|
||||
"requires": {
|
||||
"@fortawesome/fontawesome-svg-core": "1.2.34",
|
||||
"@fortawesome/free-brands-svg-icons": "5.11.2",
|
||||
@@ -4499,11 +4499,11 @@
|
||||
}
|
||||
},
|
||||
"@pact-foundation/pact": {
|
||||
"version": "9.16.1",
|
||||
"resolved": "https://registry.npmjs.org/@pact-foundation/pact/-/pact-9.16.1.tgz",
|
||||
"integrity": "sha512-hknXmKy3uvZsJ2rJlazyUk1hJWnxRuxAFbMHZ/edWjxF2gmQO3xyA7SKFjgEhbghORcgLnK3308q/5rJFOfbQg==",
|
||||
"version": "9.16.3",
|
||||
"resolved": "https://registry.npmjs.org/@pact-foundation/pact/-/pact-9.16.3.tgz",
|
||||
"integrity": "sha512-26uhezEbBAbW7gQ0V2QTJp8iSTmgxf9A65J7lCQyTd6P3Sk7omqTL4faio1/UnPlzMaogQjaa8OpmFpSbfXOFg==",
|
||||
"requires": {
|
||||
"@pact-foundation/pact-node": "^10.13.7",
|
||||
"@pact-foundation/pact-node": "^10.13.8",
|
||||
"@types/bluebird": "^3.5.20",
|
||||
"@types/express": "^4.17.11",
|
||||
"bluebird": "~3.5.1",
|
||||
@@ -4515,7 +4515,6 @@
|
||||
"graphql": "^14.0.0",
|
||||
"graphql-tag": "^2.9.1",
|
||||
"http-proxy": "^1.18.1",
|
||||
"http-proxy-middleware": "^0.19.0",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash.isfunction": "3.0.8",
|
||||
"lodash.isnil": "4.0.0",
|
||||
@@ -4536,9 +4535,9 @@
|
||||
}
|
||||
},
|
||||
"@pact-foundation/pact-node": {
|
||||
"version": "10.13.7",
|
||||
"resolved": "https://registry.npmjs.org/@pact-foundation/pact-node/-/pact-node-10.13.7.tgz",
|
||||
"integrity": "sha512-EhSo5t0QCW5CXdqXPtLo/tkAmAn0Phm7qNgPibh5p5+38Mdrjee77Muk1LVd/MjlW6NV5dH+zLAlD40z4CRelw==",
|
||||
"version": "10.13.8",
|
||||
"resolved": "https://registry.npmjs.org/@pact-foundation/pact-node/-/pact-node-10.13.8.tgz",
|
||||
"integrity": "sha512-0Jo9b2UNB/qEcsn+fT3+7M68x6DX5lYq82zFIczgbNxVIbuCGkR+xO7u6LnKuO1eyrGfT2WwP7LVLHEJSfMxTw==",
|
||||
"requires": {
|
||||
"@types/needle": "^2.5.1",
|
||||
"@types/pino": "^6.3.5",
|
||||
@@ -4670,11 +4669,11 @@
|
||||
"integrity": "sha512-HnUhk1Sy9IuKrxEMdIRCxpIqPw6BFsbYSEUO9p/hNw5sMld/+3OLMWQP80F8/db9qsv3qUjs7ZR5bS/R+iinXw=="
|
||||
},
|
||||
"@reduxjs/toolkit": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.6.1.tgz",
|
||||
"integrity": "sha512-pa3nqclCJaZPAyBhruQtiRwtTjottRrVJqziVZcWzI73i6L3miLTtUyWfauwv08HWtiXLx1xGyGt+yLFfW/d0A==",
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.6.2.tgz",
|
||||
"integrity": "sha512-HbfI/hOVrAcMGAYsMWxw3UJyIoAS9JTdwddsjlr5w3S50tXhWb+EMyhIw+IAvCVCLETkzdjgH91RjDSYZekVBA==",
|
||||
"requires": {
|
||||
"immer": "^9.0.1",
|
||||
"immer": "^9.0.6",
|
||||
"redux": "^4.1.0",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"reselect": "^4.0.0"
|
||||
@@ -6750,17 +6749,20 @@
|
||||
"arr-diff": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
|
||||
"integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
|
||||
"integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
|
||||
"dev": true
|
||||
},
|
||||
"arr-flatten": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
|
||||
"integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg=="
|
||||
"integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
|
||||
"dev": true
|
||||
},
|
||||
"arr-union": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
|
||||
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
|
||||
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
|
||||
"dev": true
|
||||
},
|
||||
"array-find-index": {
|
||||
"version": "1.0.2",
|
||||
@@ -6805,7 +6807,8 @@
|
||||
"array-unique": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
|
||||
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
|
||||
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
|
||||
"dev": true
|
||||
},
|
||||
"array.prototype.find": {
|
||||
"version": "2.1.1",
|
||||
@@ -6835,7 +6838,8 @@
|
||||
"assign-symbols": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
|
||||
"integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
|
||||
"integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
|
||||
"dev": true
|
||||
},
|
||||
"ast-types-flow": {
|
||||
"version": "0.0.7",
|
||||
@@ -6884,7 +6888,8 @@
|
||||
"atob": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
||||
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
|
||||
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
|
||||
"dev": true
|
||||
},
|
||||
"atomic-sleep": {
|
||||
"version": "1.0.0",
|
||||
@@ -7274,6 +7279,7 @@
|
||||
"version": "0.11.2",
|
||||
"resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
|
||||
"integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cache-base": "^1.0.1",
|
||||
"class-utils": "^0.3.5",
|
||||
@@ -7288,6 +7294,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
|
||||
"integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^1.0.0"
|
||||
}
|
||||
@@ -7296,6 +7303,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
}
|
||||
@@ -7304,6 +7312,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
}
|
||||
@@ -7312,6 +7321,7 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
|
||||
"integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-accessor-descriptor": "^1.0.0",
|
||||
"is-data-descriptor": "^1.0.0",
|
||||
@@ -7346,9 +7356,9 @@
|
||||
}
|
||||
},
|
||||
"big-integer": {
|
||||
"version": "1.6.48",
|
||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz",
|
||||
"integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w=="
|
||||
"version": "1.6.49",
|
||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.49.tgz",
|
||||
"integrity": "sha512-KJ7VhqH+f/BOt9a3yMwJNmcZjG53ijWMTjSAGMveQWyLwqIiwkjNP5PFgDob3Snnx86SjDj6I89fIbv0dkQeNw=="
|
||||
},
|
||||
"big.js": {
|
||||
"version": "5.2.2",
|
||||
@@ -7837,6 +7847,7 @@
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
|
||||
"integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arr-flatten": "^1.1.0",
|
||||
"array-unique": "^0.3.2",
|
||||
@@ -7854,6 +7865,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
@@ -7974,6 +7986,7 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
|
||||
"integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"collection-visit": "^1.0.0",
|
||||
"component-emitter": "^1.2.1",
|
||||
@@ -8334,6 +8347,7 @@
|
||||
"version": "0.3.6",
|
||||
"resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
|
||||
"integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arr-union": "^3.1.0",
|
||||
"define-property": "^0.2.5",
|
||||
@@ -8345,6 +8359,7 @@
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
|
||||
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^0.1.0"
|
||||
}
|
||||
@@ -8538,6 +8553,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
|
||||
"integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"map-visit": "^1.0.0",
|
||||
"object-visit": "^1.0.0"
|
||||
@@ -8597,7 +8613,8 @@
|
||||
"component-emitter": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
|
||||
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
|
||||
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
|
||||
"dev": true
|
||||
},
|
||||
"compressible": {
|
||||
"version": "2.0.18",
|
||||
@@ -8779,7 +8796,8 @@
|
||||
"copy-descriptor": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
|
||||
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
|
||||
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
|
||||
"dev": true
|
||||
},
|
||||
"core-js": {
|
||||
"version": "3.16.4",
|
||||
@@ -9113,9 +9131,9 @@
|
||||
}
|
||||
},
|
||||
"dateformat": {
|
||||
"version": "4.5.1",
|
||||
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.5.1.tgz",
|
||||
"integrity": "sha512-OD0TZ+B7yP7ZgpJf5K2DIbj3FZvFvxgFUuaqA/V5zTjAtAAXZ1E8bktHxmAGs4x5b7PflqA9LeQ84Og7wYtF7Q=="
|
||||
"version": "4.6.3",
|
||||
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz",
|
||||
"integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
@@ -9442,6 +9460,7 @@
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
|
||||
"integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^1.0.2",
|
||||
"isobject": "^3.0.1"
|
||||
@@ -9451,6 +9470,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
}
|
||||
@@ -9459,6 +9479,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
}
|
||||
@@ -9467,6 +9488,7 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
|
||||
"integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-accessor-descriptor": "^1.0.0",
|
||||
"is-data-descriptor": "^1.0.0",
|
||||
@@ -10667,6 +10689,7 @@
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
|
||||
"integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "^2.3.3",
|
||||
"define-property": "^0.2.5",
|
||||
@@ -10681,6 +10704,7 @@
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
|
||||
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^0.1.0"
|
||||
}
|
||||
@@ -10689,6 +10713,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
@@ -10795,9 +10820,9 @@
|
||||
}
|
||||
},
|
||||
"ext": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/ext/-/ext-1.5.0.tgz",
|
||||
"integrity": "sha512-+ONcYoWj/SoQwUofMr94aGu05Ou4FepKi7N7b+O8T4jVfyIsZQV1/xeS8jpaBzF0csAk0KLXoHCxU7cKYZjo1Q==",
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz",
|
||||
"integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==",
|
||||
"requires": {
|
||||
"type": "^2.5.0"
|
||||
},
|
||||
@@ -10840,6 +10865,7 @@
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
|
||||
"integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assign-symbols": "^1.0.0",
|
||||
"is-extendable": "^1.0.1"
|
||||
@@ -10849,6 +10875,7 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
|
||||
"integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-plain-object": "^2.0.4"
|
||||
}
|
||||
@@ -10870,6 +10897,7 @@
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
|
||||
"integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"array-unique": "^0.3.2",
|
||||
"define-property": "^1.0.0",
|
||||
@@ -10885,6 +10913,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
|
||||
"integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^1.0.0"
|
||||
}
|
||||
@@ -10893,6 +10922,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
@@ -10901,6 +10931,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
}
|
||||
@@ -10909,6 +10940,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
}
|
||||
@@ -10917,6 +10949,7 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
|
||||
"integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-accessor-descriptor": "^1.0.0",
|
||||
"is-data-descriptor": "^1.0.0",
|
||||
@@ -11173,6 +11206,7 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
|
||||
"integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^2.0.1",
|
||||
"is-number": "^3.0.0",
|
||||
@@ -11184,6 +11218,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
@@ -11296,7 +11331,8 @@
|
||||
"for-in": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
|
||||
"integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
|
||||
"integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
|
||||
"dev": true
|
||||
},
|
||||
"foreach": {
|
||||
"version": "2.0.5",
|
||||
@@ -11362,6 +11398,7 @@
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
|
||||
"integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"map-cache": "^0.2.2"
|
||||
}
|
||||
@@ -11592,7 +11629,8 @@
|
||||
"get-value": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
|
||||
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
|
||||
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
|
||||
"dev": true
|
||||
},
|
||||
"gifsicle": {
|
||||
"version": "5.2.0",
|
||||
@@ -11948,6 +11986,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
|
||||
"integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"get-value": "^2.0.6",
|
||||
"has-values": "^1.0.0",
|
||||
@@ -11958,6 +11997,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
|
||||
"integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-number": "^3.0.0",
|
||||
"kind-of": "^4.0.0"
|
||||
@@ -11967,6 +12007,7 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
|
||||
"integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
@@ -12235,17 +12276,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"http-proxy-middleware": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.2.tgz",
|
||||
"integrity": "sha512-aYk1rTKqLTus23X3L96LGNCGNgWpG4cG0XoZIT1GUPhhulEHX/QalnO6Vbo+WmKWi4AL2IidjuC0wZtbpg0yhQ==",
|
||||
"requires": {
|
||||
"http-proxy": "^1.18.1",
|
||||
"is-glob": "^4.0.0",
|
||||
"lodash": "^4.17.11",
|
||||
"micromatch": "^3.1.10"
|
||||
}
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
|
||||
@@ -12719,9 +12749,9 @@
|
||||
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
|
||||
},
|
||||
"immer": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.5.tgz",
|
||||
"integrity": "sha512-2WuIehr2y4lmYz9gaQzetPR2ECniCifk4ORaQbU3g5EalLt+0IVTosEPJ5BoYl/75ky2mivzdRzV8wWgQGOSYQ=="
|
||||
"version": "9.0.6",
|
||||
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.6.tgz",
|
||||
"integrity": "sha512-G95ivKpy+EvVAnAab4fVa4YGYn24J1SpEktnJX7JJ45Bd7xqME/SCplFzYFmTbrkwZbQ4xJK1xMTUYBkN6pWsQ=="
|
||||
},
|
||||
"import-fresh": {
|
||||
"version": "3.3.0",
|
||||
@@ -12973,6 +13003,7 @@
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
|
||||
"integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^3.0.2"
|
||||
},
|
||||
@@ -12981,6 +13012,7 @@
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
@@ -13081,6 +13113,7 @@
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
|
||||
"integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^3.0.2"
|
||||
},
|
||||
@@ -13089,6 +13122,7 @@
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
@@ -13104,6 +13138,7 @@
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
|
||||
"integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-accessor-descriptor": "^0.1.6",
|
||||
"is-data-descriptor": "^0.1.4",
|
||||
@@ -13113,7 +13148,8 @@
|
||||
"kind-of": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
|
||||
"integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
|
||||
"integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -13126,12 +13162,14 @@
|
||||
"is-extendable": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
|
||||
"integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik="
|
||||
"integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
|
||||
"dev": true
|
||||
},
|
||||
"is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
|
||||
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
|
||||
"dev": true
|
||||
},
|
||||
"is-finite": {
|
||||
"version": "1.1.0",
|
||||
@@ -13183,6 +13221,7 @@
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
|
||||
"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extglob": "^2.1.1"
|
||||
}
|
||||
@@ -13245,6 +13284,7 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
|
||||
"integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^3.0.2"
|
||||
},
|
||||
@@ -13253,6 +13293,7 @@
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
@@ -13306,6 +13347,7 @@
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
|
||||
"integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isobject": "^3.0.1"
|
||||
}
|
||||
@@ -13453,7 +13495,8 @@
|
||||
"is-windows": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
|
||||
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
|
||||
"integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
|
||||
"dev": true
|
||||
},
|
||||
"is-wsl": {
|
||||
"version": "2.2.0",
|
||||
@@ -13477,7 +13520,8 @@
|
||||
"isobject": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
|
||||
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
|
||||
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
|
||||
"dev": true
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
@@ -16789,7 +16833,8 @@
|
||||
"kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
|
||||
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
|
||||
"dev": true
|
||||
},
|
||||
"kleur": {
|
||||
"version": "3.0.3",
|
||||
@@ -17280,7 +17325,8 @@
|
||||
"map-cache": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
|
||||
"integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8="
|
||||
"integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
|
||||
"dev": true
|
||||
},
|
||||
"map-obj": {
|
||||
"version": "1.0.1",
|
||||
@@ -17293,6 +17339,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
|
||||
"integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"object-visit": "^1.0.0"
|
||||
}
|
||||
@@ -17525,6 +17572,7 @@
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
|
||||
"integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arr-diff": "^4.0.0",
|
||||
"array-unique": "^0.3.2",
|
||||
@@ -17627,9 +17675,9 @@
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"minipass": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
|
||||
"integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz",
|
||||
"integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==",
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
@@ -17647,6 +17695,7 @@
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
|
||||
"integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"for-in": "^1.0.2",
|
||||
"is-extendable": "^1.0.1"
|
||||
@@ -17656,6 +17705,7 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
|
||||
"integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-plain-object": "^2.0.4"
|
||||
}
|
||||
@@ -17731,6 +17781,7 @@
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
|
||||
"integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arr-diff": "^4.0.0",
|
||||
"array-unique": "^0.3.2",
|
||||
@@ -17989,6 +18040,7 @@
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
|
||||
"integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"copy-descriptor": "^0.1.0",
|
||||
"define-property": "^0.2.5",
|
||||
@@ -17999,6 +18051,7 @@
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
|
||||
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^0.1.0"
|
||||
}
|
||||
@@ -18007,6 +18060,7 @@
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
@@ -18041,6 +18095,7 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
|
||||
"integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isobject": "^3.0.0"
|
||||
}
|
||||
@@ -18094,6 +18149,7 @@
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
|
||||
"integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isobject": "^3.0.1"
|
||||
}
|
||||
@@ -18446,7 +18502,8 @@
|
||||
"pascalcase": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
|
||||
"integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ="
|
||||
"integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
|
||||
"dev": true
|
||||
},
|
||||
"path-dirname": {
|
||||
"version": "1.0.2",
|
||||
@@ -18532,9 +18589,9 @@
|
||||
}
|
||||
},
|
||||
"pino": {
|
||||
"version": "6.13.2",
|
||||
"resolved": "https://registry.npmjs.org/pino/-/pino-6.13.2.tgz",
|
||||
"integrity": "sha512-vmD/cabJ4xKqo9GVuAoAEeQhra8XJ7YydPV/JyIP+0zDtFTu5JSKdtt8eksGVWKtTSrNGcRrzJ4/IzvUWep3FA==",
|
||||
"version": "6.13.3",
|
||||
"resolved": "https://registry.npmjs.org/pino/-/pino-6.13.3.tgz",
|
||||
"integrity": "sha512-tJy6qVgkh9MwNgqX1/oYi3ehfl2Y9H0uHyEEMsBe74KinESIjdMrMQDWpcZPpPicg3VV35d/GLQZmo4QgU2Xkg==",
|
||||
"requires": {
|
||||
"fast-redact": "^3.0.0",
|
||||
"fast-safe-stringify": "^2.0.8",
|
||||
@@ -18882,7 +18939,8 @@
|
||||
"posix-character-classes": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
|
||||
"integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
|
||||
"integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
|
||||
"dev": true
|
||||
},
|
||||
"postcss": {
|
||||
"version": "8.3.5",
|
||||
@@ -19535,9 +19593,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"quick-format-unescaped": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.3.tgz",
|
||||
"integrity": "sha512-MaL/oqh02mhEo5m5J2rwsVL23Iw2PEaGVHgT2vFt8AAsr0lfvQA5dpXo9TPu0rz7tSBdUPgkbam0j/fj5ZM8yg=="
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
|
||||
"integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="
|
||||
},
|
||||
"randombytes": {
|
||||
"version": "2.1.0",
|
||||
@@ -20230,6 +20288,7 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
|
||||
"integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^3.0.2",
|
||||
"safe-regex": "^1.1.0"
|
||||
@@ -20394,12 +20453,14 @@
|
||||
"repeat-element": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz",
|
||||
"integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ=="
|
||||
"integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==",
|
||||
"dev": true
|
||||
},
|
||||
"repeat-string": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
|
||||
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
|
||||
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
|
||||
"dev": true
|
||||
},
|
||||
"repeating": {
|
||||
"version": "2.0.1",
|
||||
@@ -20480,7 +20541,8 @@
|
||||
"resolve-url": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
|
||||
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
|
||||
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
|
||||
"dev": true
|
||||
},
|
||||
"resolve-url-loader": {
|
||||
"version": "5.0.0-beta.1",
|
||||
@@ -20518,7 +20580,8 @@
|
||||
"ret": {
|
||||
"version": "0.1.15",
|
||||
"resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
|
||||
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
|
||||
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
|
||||
"dev": true
|
||||
},
|
||||
"retry": {
|
||||
"version": "0.13.1",
|
||||
@@ -20688,6 +20751,7 @@
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
|
||||
"integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ret": "~0.1.10"
|
||||
}
|
||||
@@ -20936,6 +21000,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
|
||||
"integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^2.0.1",
|
||||
"is-extendable": "^0.1.1",
|
||||
@@ -20947,6 +21012,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
@@ -21056,6 +21122,7 @@
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
||||
"integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"base": "^0.11.1",
|
||||
"debug": "^2.2.0",
|
||||
@@ -21071,6 +21138,7 @@
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
|
||||
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^0.1.0"
|
||||
}
|
||||
@@ -21079,6 +21147,7 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
@@ -21086,7 +21155,8 @@
|
||||
"source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
|
||||
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -21094,6 +21164,7 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
|
||||
"integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"define-property": "^1.0.0",
|
||||
"isobject": "^3.0.0",
|
||||
@@ -21104,6 +21175,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
|
||||
"integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^1.0.0"
|
||||
}
|
||||
@@ -21112,6 +21184,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
}
|
||||
@@ -21120,6 +21193,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
|
||||
"integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^6.0.0"
|
||||
}
|
||||
@@ -21128,6 +21202,7 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
|
||||
"integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-accessor-descriptor": "^1.0.0",
|
||||
"is-data-descriptor": "^1.0.0",
|
||||
@@ -21140,6 +21215,7 @@
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
|
||||
"integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^3.2.0"
|
||||
},
|
||||
@@ -21148,6 +21224,7 @@
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
@@ -21166,9 +21243,9 @@
|
||||
}
|
||||
},
|
||||
"sonic-boom": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.2.3.tgz",
|
||||
"integrity": "sha512-dm32bzlBchhXoJZe0yLY/kdYsHtXhZphidIcCzJib1aEjfciZyvHJ3NjA1zh6jJCO/OBLfdjc5iw6jLS/Go2fg==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.3.0.tgz",
|
||||
"integrity": "sha512-lEPaw654/4/rCJHz/TNzV4GIthqCq4inO+O3aFhbdOvR1bE+2//sVkcS+xlqPdb8gdjQCEE0hE9BuvnVixbnWQ==",
|
||||
"requires": {
|
||||
"atomic-sleep": "^1.0.0"
|
||||
}
|
||||
@@ -21247,6 +21324,7 @@
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
|
||||
"integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"atob": "^2.1.2",
|
||||
"decode-uri-component": "^0.2.0",
|
||||
@@ -21268,7 +21346,8 @@
|
||||
"source-map-url": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz",
|
||||
"integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw=="
|
||||
"integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==",
|
||||
"dev": true
|
||||
},
|
||||
"spawn-sync": {
|
||||
"version": "1.0.15",
|
||||
@@ -21377,6 +21456,7 @@
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
|
||||
"integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^3.0.0"
|
||||
}
|
||||
@@ -21493,6 +21573,7 @@
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
|
||||
"integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"define-property": "^0.2.5",
|
||||
"object-copy": "^0.1.0"
|
||||
@@ -21502,6 +21583,7 @@
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
|
||||
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-descriptor": "^0.1.0"
|
||||
}
|
||||
@@ -22464,6 +22546,7 @@
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
|
||||
"integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"kind-of": "^3.0.2"
|
||||
},
|
||||
@@ -22472,6 +22555,7 @@
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
@@ -22482,6 +22566,7 @@
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
|
||||
"integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"define-property": "^2.0.2",
|
||||
"extend-shallow": "^3.0.2",
|
||||
@@ -22493,6 +22578,7 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
|
||||
"integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-number": "^3.0.0",
|
||||
"repeat-string": "^1.6.1"
|
||||
@@ -22719,6 +22805,7 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
|
||||
"integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arr-union": "^3.1.0",
|
||||
"get-value": "^2.0.6",
|
||||
@@ -22780,6 +22867,7 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
|
||||
"integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-value": "^0.3.1",
|
||||
"isobject": "^3.0.0"
|
||||
@@ -22789,6 +22877,7 @@
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
|
||||
"integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"get-value": "^2.0.3",
|
||||
"has-values": "^0.1.4",
|
||||
@@ -22799,6 +22888,7 @@
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
|
||||
"integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isarray": "1.0.0"
|
||||
}
|
||||
@@ -22808,12 +22898,14 @@
|
||||
"has-values": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
|
||||
"integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E="
|
||||
"integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
|
||||
"dev": true
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -22891,7 +22983,8 @@
|
||||
"urix": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
|
||||
"integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI="
|
||||
"integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
|
||||
"dev": true
|
||||
},
|
||||
"url": {
|
||||
"version": "0.11.0",
|
||||
@@ -22956,7 +23049,8 @@
|
||||
"use": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
|
||||
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
|
||||
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
|
||||
"dev": true
|
||||
},
|
||||
"use-callback-ref": {
|
||||
"version": "1.2.5",
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"@edx/brand": "npm:@edx/brand-openedx@1.1.0",
|
||||
"@edx/frontend-component-footer": "10.1.6",
|
||||
"@edx/frontend-enterprise-utils": "1.0.0",
|
||||
"@edx/frontend-lib-special-exams": "1.13.2",
|
||||
"@edx/frontend-lib-special-exams": "1.13.3",
|
||||
"@edx/frontend-platform": "1.12.7",
|
||||
"@edx/paragon": "16.13.3",
|
||||
"@fortawesome/fontawesome-svg-core": "1.2.36",
|
||||
@@ -42,8 +42,8 @@
|
||||
"@fortawesome/free-regular-svg-icons": "5.15.4",
|
||||
"@fortawesome/free-solid-svg-icons": "5.15.4",
|
||||
"@fortawesome/react-fontawesome": "0.1.15",
|
||||
"@pact-foundation/pact": "9.16.1",
|
||||
"@reduxjs/toolkit": "1.6.1",
|
||||
"@pact-foundation/pact": "9.16.3",
|
||||
"@reduxjs/toolkit": "1.6.2",
|
||||
"classnames": "2.3.1",
|
||||
"core-js": "3.16.4",
|
||||
"js-cookie": "2.2.1",
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
<!doctype html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<title>Course | <%= process.env.SITE_NAME %></title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="shortcut icon" href="<%=htmlWebpackPlugin.options.FAVICON_URL%>" type="image/x-icon" />
|
||||
|
||||
<% if (process.env.NEW_RELIC_ACCOUNT_ID) { %>
|
||||
<!-- NewRelic agent 1209 -->
|
||||
<script>
|
||||
@@ -16,6 +11,11 @@
|
||||
</script>
|
||||
<% } %>
|
||||
|
||||
<title>Course | <%= process.env.SITE_NAME %></title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="shortcut icon" href="<%=htmlWebpackPlugin.options.FAVICON_URL%>" type="image/x-icon" />
|
||||
|
||||
<% if (htmlWebpackPlugin.options.OPTIMIZELY_PROJECT_ID) { %>
|
||||
<script src="https://www.edx.org/optimizelyjs/<%= htmlWebpackPlugin.options.OPTIMIZELY_PROJECT_ID %>.js"></script>
|
||||
<% } %>
|
||||
|
||||
@@ -90,6 +90,8 @@ function Course({
|
||||
courseId={courseId}
|
||||
sectionId={section ? section.id : null}
|
||||
sequenceId={sequenceId}
|
||||
isStaff={course ? course.isStaff : null}
|
||||
unitId={unitId}
|
||||
//* * [MM-P2P] Experiment */
|
||||
mmp2p={MMP2P}
|
||||
/>
|
||||
|
||||
@@ -1,36 +1,19 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { FormattedMessage } from '@edx/frontend-platform/i18n';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { faHome } from '@fortawesome/free-solid-svg-icons';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Hyperlink, MenuItem, SelectMenu } from '@edx/paragon';
|
||||
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
|
||||
import {
|
||||
sendTrackingLogEvent,
|
||||
sendTrackEvent,
|
||||
} from '@edx/frontend-platform/analytics';
|
||||
import { SelectMenu } from '@edx/paragon';
|
||||
import { useModel, useModels } from '../../generic/model-store';
|
||||
/** [MM-P2P] Experiment */
|
||||
import { MMP2PFlyoverTrigger } from '../../experiments/mm-p2p';
|
||||
import JumpNavMenuItem from './JumpNavMenuItem';
|
||||
|
||||
function CourseBreadcrumb({
|
||||
content, withSeparator,
|
||||
content, withSeparator, courseId, unitId, isStaff,
|
||||
}) {
|
||||
const defaultContent = content.filter(destination => destination.default)[0];
|
||||
const administrator = getAuthenticatedUser() ? getAuthenticatedUser().administrator : false;
|
||||
function logEvent(target) {
|
||||
const eventName = 'edx.ui.lms.jump_nav.selected';
|
||||
const payload = {
|
||||
target_name: target.label,
|
||||
id: target.id,
|
||||
current_id: defaultContent.id,
|
||||
widget_placement: 'breadcrumb',
|
||||
};
|
||||
sendTrackEvent(eventName, payload);
|
||||
sendTrackingLogEvent(eventName, payload);
|
||||
}
|
||||
const defaultContent = content.filter(destination => destination.default)[0] || { id: courseId, label: '' };
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -44,22 +27,22 @@ function CourseBreadcrumb({
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
{ getConfig().ENABLE_JUMPNAV !== 'true' || content.length < 2 || !administrator
|
||||
{content.length < 2 || !isStaff
|
||||
? (
|
||||
<a className="text-primary-500" href={defaultContent.url}>{defaultContent.label}
|
||||
<a className="text-primary-500" href={`/course/${courseId}/${defaultContent.id}`}>
|
||||
{defaultContent.label}
|
||||
</a>
|
||||
)
|
||||
: (
|
||||
<SelectMenu isLink defaultMessage={defaultContent.label}>
|
||||
{content.map(item => (
|
||||
<MenuItem
|
||||
as={Hyperlink}
|
||||
defaultSelected={item.default}
|
||||
destination={item.url}
|
||||
onClick={logEvent(item)}
|
||||
>
|
||||
{item.label}
|
||||
</MenuItem>
|
||||
<JumpNavMenuItem
|
||||
isDefault={item.default}
|
||||
sequences={item.sequences}
|
||||
courseId={courseId}
|
||||
title={item.label}
|
||||
currentUnit={unitId}
|
||||
/>
|
||||
))}
|
||||
</SelectMenu>
|
||||
)}
|
||||
@@ -72,58 +55,74 @@ CourseBreadcrumb.propTypes = {
|
||||
content: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
default: PropTypes.bool,
|
||||
url: PropTypes.string,
|
||||
id: PropTypes.string,
|
||||
label: PropTypes.string,
|
||||
}),
|
||||
).isRequired,
|
||||
unitId: PropTypes.string,
|
||||
withSeparator: PropTypes.bool,
|
||||
courseId: PropTypes.string,
|
||||
isStaff: PropTypes.bool,
|
||||
};
|
||||
|
||||
CourseBreadcrumb.defaultProps = {
|
||||
withSeparator: false,
|
||||
unitId: null,
|
||||
courseId: null,
|
||||
isStaff: null,
|
||||
};
|
||||
|
||||
export default function CourseBreadcrumbs({
|
||||
courseId,
|
||||
sectionId,
|
||||
sequenceId,
|
||||
unitId,
|
||||
isStaff,
|
||||
/** [MM-P2P] Experiment */
|
||||
mmp2p,
|
||||
}) {
|
||||
const course = useModel('coursewareMeta', courseId);
|
||||
const courseStatus = useSelector(state => state.courseware.courseStatus);
|
||||
const sections = course ? Object.fromEntries(useModels('sections', course.sectionIds).map(section => [section.id, section])) : null;
|
||||
const possibleSequences = sections && sectionId ? sections[sectionId].sequenceIds : [];
|
||||
const sequences = Object.fromEntries(useModels('sequences', possibleSequences).map(sequence => [sequence.id, sequence]));
|
||||
const sequenceStatus = useSelector(state => state.courseware.sequenceStatus);
|
||||
|
||||
const allSequencesInSections = Object.fromEntries(useModels('sections', course.sectionIds).map(section => [section.id, {
|
||||
default: section.id === sectionId,
|
||||
title: section.title,
|
||||
sequences: useModels('sequences', section.sequenceIds),
|
||||
}]));
|
||||
|
||||
const links = useMemo(() => {
|
||||
const temp = [];
|
||||
const chapters = [];
|
||||
const sequentials = [];
|
||||
if (courseStatus === 'loaded' && sequenceStatus === 'loaded') {
|
||||
temp.push(course.sectionIds.map(id => ({
|
||||
id,
|
||||
label: sections[id].title,
|
||||
default: (id === sectionId),
|
||||
// navigate to first sequence in section, (TODO: navigate to first incomplete sequence in section)
|
||||
url: `${getConfig().BASE_URL}/course/${courseId}/${sections[id].sequenceIds[0]}`,
|
||||
})));
|
||||
temp.push(sections[sectionId].sequenceIds.map(id => ({
|
||||
id,
|
||||
label: sequences[id].title,
|
||||
default: id === sequenceId,
|
||||
// first unit it section (TODO: navigate to first incomplete in sequence)
|
||||
url: `${getConfig().BASE_URL}/course/${courseId}/${sequences[id].id}/${sequences[id].unitIds[0]}`,
|
||||
})));
|
||||
Object.entries(allSequencesInSections).forEach(([id, section]) => {
|
||||
chapters.push({
|
||||
id,
|
||||
label: section.title,
|
||||
default: section.default,
|
||||
sequences: section.sequences,
|
||||
});
|
||||
if (section.default) {
|
||||
section.sequences.forEach(sequence => {
|
||||
sequentials.push({
|
||||
id: sequence.id,
|
||||
label: sequence.title,
|
||||
default: sequence.id === sequenceId,
|
||||
sequences: [sequence],
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return temp;
|
||||
}, [courseStatus, sections, sequences]);
|
||||
return [chapters, sequentials];
|
||||
}, [courseStatus, sequenceStatus, allSequencesInSections]);
|
||||
|
||||
return (
|
||||
<nav aria-label="breadcrumb" className="my-4 d-inline-block col-sm-10">
|
||||
<ol className="list-unstyled d-flex align-items-center m-0">
|
||||
<li>
|
||||
<ol className="list-unstyled d-flex flex-nowrap align-items-center m-0">
|
||||
<li className="list-unstyled d-flex m-0">
|
||||
<a
|
||||
href={`${getConfig().LMS_BASE_URL}/courses/${courseId}/course/`}
|
||||
href={`/course/${courseId}/home`}
|
||||
className="flex-shrink-0 text-primary"
|
||||
>
|
||||
<FontAwesomeIcon icon={faHome} className="mr-2" />
|
||||
@@ -136,8 +135,12 @@ export default function CourseBreadcrumbs({
|
||||
</li>
|
||||
{links.map(content => (
|
||||
<CourseBreadcrumb
|
||||
courseId={courseId}
|
||||
sequenceId={sequenceId}
|
||||
content={content}
|
||||
unitId={unitId}
|
||||
withSeparator
|
||||
isStaff={isStaff}
|
||||
/>
|
||||
))}
|
||||
{/** [MM-P2P] Experiment */}
|
||||
@@ -153,6 +156,8 @@ CourseBreadcrumbs.propTypes = {
|
||||
courseId: PropTypes.string.isRequired,
|
||||
sectionId: PropTypes.string,
|
||||
sequenceId: PropTypes.string,
|
||||
unitId: PropTypes.string,
|
||||
isStaff: PropTypes.bool,
|
||||
/** [MM-P2P] Experiment */
|
||||
mmp2p: PropTypes.shape({
|
||||
state: PropTypes.shape({
|
||||
@@ -164,6 +169,8 @@ CourseBreadcrumbs.propTypes = {
|
||||
CourseBreadcrumbs.defaultProps = {
|
||||
sectionId: null,
|
||||
sequenceId: null,
|
||||
unitId: null,
|
||||
isStaff: null,
|
||||
/** [MM-P2P] Experiment */
|
||||
mmp2p: {},
|
||||
};
|
||||
|
||||
@@ -1,23 +1,28 @@
|
||||
import React from 'react';
|
||||
import { screen, render, fireEvent } from '@testing-library/react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { screen, render } from '@testing-library/react';
|
||||
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { useModel, useModels } from '../../generic/model-store';
|
||||
import CourseBreadcrumbs from './CourseBreadcrumbs';
|
||||
|
||||
jest.mock('@edx/frontend-platform');
|
||||
jest.mock('react-redux');
|
||||
jest.mock('@edx/frontend-platform/analytics');
|
||||
|
||||
// Remove When Fully rolled out>>>
|
||||
jest.mock('../../generic/model-store');
|
||||
jest.mock('@edx/frontend-platform/auth');
|
||||
getConfig.mockImplementation(() => ({ ENABLE_JUMPNAV: 'true' }));
|
||||
getAuthenticatedUser.mockImplementation(() => ({ administrator: true }));
|
||||
// ^^^^Remove When Fully rolled out
|
||||
|
||||
useSelector.mockImplementation(() => 'loaded');
|
||||
jest.mock('react-redux', () => ({
|
||||
connect: (mapStateToProps, mapDispatchToProps) => (ReactComponent) => ({
|
||||
mapStateToProps,
|
||||
mapDispatchToProps,
|
||||
ReactComponent,
|
||||
}),
|
||||
Provider: ({ children }) => children,
|
||||
useSelector: () => 'loaded',
|
||||
}));
|
||||
|
||||
useModels.mockImplementation((name) => {
|
||||
if (name === 'sections') {
|
||||
return [
|
||||
@@ -102,16 +107,14 @@ describe('CourseBreadcrumbs', () => {
|
||||
courseId="course-v1:edX+DemoX+Demo_Course"
|
||||
sectionId="block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations"
|
||||
sequenceId="block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions"
|
||||
isStaff
|
||||
/>,
|
||||
);
|
||||
it('renders course breadcrumbs as expected, handles clicks', async () => {
|
||||
it('renders course breadcrumbs as expected', async () => {
|
||||
expect(screen.queryAllByRole('link')).toHaveLength(1);
|
||||
const courseHomeButtonDestination = screen.getAllByRole('link')[0].href;
|
||||
expect(courseHomeButtonDestination).toBe('http://localhost/course/course-v1:edX+DemoX+Demo_Course/home');
|
||||
expect(screen.getByRole('navigation', { name: 'breadcrumb' })).toBeInTheDocument();
|
||||
expect(screen.queryAllByRole('button')).toHaveLength(2);
|
||||
const sectionButton = screen.getByText('Example Week 1: Getting Started');
|
||||
expect(screen.queryAllByRole('link')).toHaveLength(1);
|
||||
fireEvent.click(sectionButton);
|
||||
expect(screen.queryAllByRole('link')).toHaveLength(2);
|
||||
const menuItem = screen.queryAllByRole('link')[0];
|
||||
fireEvent.click(menuItem);
|
||||
});
|
||||
});
|
||||
|
||||
80
src/courseware/course/JumpNavMenuItem.jsx
Normal file
80
src/courseware/course/JumpNavMenuItem.jsx
Normal file
@@ -0,0 +1,80 @@
|
||||
/* eslint-disable consistent-return */
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { history } from '@edx/frontend-platform';
|
||||
import { MenuItem } from '@edx/paragon';
|
||||
|
||||
import {
|
||||
sendTrackingLogEvent,
|
||||
sendTrackEvent,
|
||||
} from '@edx/frontend-platform/analytics';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { checkBlockCompletion } from '../data';
|
||||
|
||||
export default function JumpNavMenuItem({
|
||||
title,
|
||||
courseId,
|
||||
currentUnit,
|
||||
sequences,
|
||||
isDefault,
|
||||
|
||||
}) {
|
||||
const dispatch = useDispatch();
|
||||
function logEvent(targetUrl) {
|
||||
const eventName = 'edx.ui.lms.jump_nav.selected';
|
||||
const payload = {
|
||||
target_name: title,
|
||||
id: targetUrl,
|
||||
current_id: courseId,
|
||||
widget_placement: 'breadcrumb',
|
||||
};
|
||||
sendTrackEvent(eventName, payload);
|
||||
sendTrackingLogEvent(eventName, payload);
|
||||
}
|
||||
|
||||
function lazyloadUrl() {
|
||||
if (isDefault) {
|
||||
return `/course/${courseId}/${currentUnit}`;
|
||||
}
|
||||
const destinationString = sequences.forEach(sequence => sequence.unitIds.forEach(unitId => {
|
||||
const complete = dispatch(checkBlockCompletion(
|
||||
courseId,
|
||||
sequence.id, unitId,
|
||||
))
|
||||
.then(value => value);
|
||||
if (!complete) { return `/course/${courseId}/${unitId}`; }
|
||||
}));
|
||||
return destinationString || `/course/${courseId}/${sequences[0].unitIds[0]}`;
|
||||
}
|
||||
function handleClick() {
|
||||
const url = lazyloadUrl();
|
||||
logEvent(url);
|
||||
history.push(url);
|
||||
}
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
defaultSelected={isDefault}
|
||||
onClick={() => handleClick()}
|
||||
>
|
||||
{title}
|
||||
</MenuItem>
|
||||
);
|
||||
}
|
||||
|
||||
const sequenceShape = PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
unitIds: PropTypes.arrayOf(PropTypes.string).isRequired,
|
||||
sectionId: PropTypes.string.isRequired,
|
||||
isTimeLimited: PropTypes.bool,
|
||||
isProctored: PropTypes.bool,
|
||||
legacyWebUrl: PropTypes.string,
|
||||
});
|
||||
|
||||
JumpNavMenuItem.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
sequences: PropTypes.arrayOf(sequenceShape).isRequired,
|
||||
isDefault: PropTypes.bool.isRequired,
|
||||
courseId: PropTypes.string.isRequired,
|
||||
currentUnit: PropTypes.string.isRequired,
|
||||
};
|
||||
69
src/courseware/course/JumpNavMenuItem.test.jsx
Normal file
69
src/courseware/course/JumpNavMenuItem.test.jsx
Normal file
@@ -0,0 +1,69 @@
|
||||
import React from 'react';
|
||||
import { screen, render } from '@testing-library/react';
|
||||
import JumpNavMenuItem from './JumpNavMenuItem';
|
||||
import { fireEvent } from '../../setupTest';
|
||||
|
||||
jest.mock('@edx/frontend-platform');
|
||||
jest.mock('@edx/frontend-platform/analytics');
|
||||
|
||||
const mockCheckBlock = jest.fn(() => Promise.resolve(true)); // check all units
|
||||
|
||||
jest.mock('react-redux', () => ({
|
||||
useDispatch: () => mockCheckBlock,
|
||||
}));
|
||||
|
||||
const mockData = {
|
||||
sectionId: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations',
|
||||
sequenceId: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions',
|
||||
|
||||
title: 'Demo Menu Item',
|
||||
courseId: 'course-v1:edX+DemoX+Demo_Course',
|
||||
currentUnit: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations',
|
||||
sequences: [
|
||||
{
|
||||
id: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5',
|
||||
blockType: 'sequential',
|
||||
unitIds: [
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@867dddb6f55d410caaa9c1eb9c6743ec',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@4f6c1b4e316a419ab5b6bf30e6c708e9',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@3dc16db8d14842e38324e95d4030b8a0',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@4a1bba2a403f40bca5ec245e945b0d76',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@256f17a44983429fb1a60802203ee4e0',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@e3601c0abee6427d8c17e6d6f8fdddd1',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@134df56c516a4a0dbb24dd5facef746e',
|
||||
],
|
||||
legacyWebUrl: 'http://localhost:18000/courses/course-v1:edX+DemoX+Demo_Course/jump_to/block-v1:edX+DemoX+Demo_Course+type@sequential+block@19a30717eff543078a5d94ae9d6c18a5?experience=legacy',
|
||||
sectionId: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations',
|
||||
},
|
||||
{
|
||||
id: 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions',
|
||||
title: 'Homework - Question Styles',
|
||||
legacyWebUrl: 'http://localhost:18000/courses/course-v1:edX+DemoX+Demo_Course/jump_to/block-v1:edX+DemoX+Demo_Course+type@sequential+block@basic_questions?experience=legacy',
|
||||
unitIds: [
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@2152d4a4aadc4cb0af5256394a3d1fc7',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@47dbd5f836544e61877a483c0b75606c',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@54bb9b142c6c4c22afc62bcb628f0e68',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_0c92347a5c00',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical_1fef54c2b23b',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@2889db1677a549abb15eb4d886f95d1c',
|
||||
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@e8a5cc2aed424838853defab7be45e42',
|
||||
],
|
||||
sectionId: 'block-v1:edX+DemoX+Demo_Course+type@chapter+block@interactive_demonstrations',
|
||||
},
|
||||
],
|
||||
isDefault: false,
|
||||
};
|
||||
describe('JumpNavMenuItem', () => {
|
||||
render(
|
||||
<JumpNavMenuItem
|
||||
{...mockData}
|
||||
/>,
|
||||
);
|
||||
it('renders menu Item as expected with button and Text and handles clicks', () => {
|
||||
expect(screen.queryAllByRole('button')).toHaveLength(1);
|
||||
expect(screen.getByText('Demo Menu Item'));
|
||||
const navButton = screen.queryAllByRole('button')[0];
|
||||
fireEvent.click(navButton);
|
||||
expect(mockCheckBlock).toBeCalledTimes(14); // number of units to check on load.
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
@@ -11,6 +11,7 @@ import CourseInProgress from './CourseInProgress';
|
||||
import CourseNonPassing from './CourseNonPassing';
|
||||
import { COURSE_EXIT_MODES, getCourseExitMode } from './utils';
|
||||
import messages from './messages';
|
||||
import { unsubscribeFromGoalReminders } from './data/thunks';
|
||||
|
||||
import { useModel } from '../../../generic/model-store';
|
||||
|
||||
@@ -18,10 +19,13 @@ function CourseExit({ intl }) {
|
||||
const { courseId } = useSelector(state => state.courseware);
|
||||
const {
|
||||
certificateData,
|
||||
courseExitPageIsActive,
|
||||
courseGoals,
|
||||
enrollmentMode,
|
||||
hasScheduledContent,
|
||||
isEnrolled,
|
||||
isMasquerading,
|
||||
userHasPassingGrade,
|
||||
courseExitPageIsActive,
|
||||
} = useModel('coursewareMeta', courseId);
|
||||
|
||||
const mode = getCourseExitMode(
|
||||
@@ -32,6 +36,15 @@ function CourseExit({ intl }) {
|
||||
courseExitPageIsActive,
|
||||
);
|
||||
|
||||
// Audit users cannot fully complete a course, so we will
|
||||
// unsubscribe them from goal reminders once they reach the course exit page
|
||||
// to avoid spamming them with goal reminder emails
|
||||
if (courseGoals && enrollmentMode === 'audit' && !isMasquerading) {
|
||||
useEffect(() => {
|
||||
unsubscribeFromGoalReminders(courseId);
|
||||
}, []);
|
||||
}
|
||||
|
||||
let body = null;
|
||||
if (mode === COURSE_EXIT_MODES.nonPassing) {
|
||||
body = (<CourseNonPassing />);
|
||||
|
||||
@@ -3,6 +3,7 @@ import MockAdapter from 'axios-mock-adapter';
|
||||
import { Factory } from 'rosie';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
|
||||
import { fetchCourse } from '../../data';
|
||||
import { buildSimpleCourseBlocks } from '../../../shared/data/__factories__/courseBlocks.factory';
|
||||
@@ -377,4 +378,25 @@ describe('Course Exit Pages', () => {
|
||||
expect(screen.getByRole('link', { name: 'View course schedule' })).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('unsubscribes the user when loading the course exit page', async () => {
|
||||
setMetadata({
|
||||
enrollment: {
|
||||
mode: 'audit',
|
||||
courseGoals: {
|
||||
goal_options: [],
|
||||
selected_goal: {
|
||||
days_per_week: 1,
|
||||
subscribed_to_reminders: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
await fetchAndRender(<CourseExit />);
|
||||
const url = `${getConfig().LMS_BASE_URL}/api/course_home/save_course_goal`;
|
||||
await waitFor(() => {
|
||||
expect(axiosMock.history.post[0].url).toMatch(url);
|
||||
expect(axiosMock.history.post[0].data).toMatch(`{"course_id":"${defaultMetadata.id}","subscribed_to_reminders":false}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,7 +23,7 @@ function filterRecommendationsList(
|
||||
));
|
||||
}
|
||||
|
||||
export default async function getCourseRecommendations(courseKey) {
|
||||
export async function getCourseRecommendations(courseKey) {
|
||||
const discoveryApiUrl = getConfig().DISCOVERY_API_BASE_URL;
|
||||
if (!discoveryApiUrl) {
|
||||
return [];
|
||||
@@ -36,3 +36,11 @@ export default async function getCourseRecommendations(courseKey) {
|
||||
]);
|
||||
return filterRecommendationsList(camelCaseObject(recommendationsResponse), camelCaseObject(enrollmentsResponse));
|
||||
}
|
||||
|
||||
export async function postUnsubscribeFromGoalReminders(courseId) {
|
||||
const url = new URL(`${getConfig().LMS_BASE_URL}/api/course_home/save_course_goal`);
|
||||
return getAuthenticatedHttpClient().post(url.href, {
|
||||
course_id: courseId,
|
||||
subscribed_to_reminders: false,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5,7 +5,10 @@ import {
|
||||
fetchCourseRecommendationsRequest,
|
||||
fetchCourseRecommendationsSuccess,
|
||||
} from './slice';
|
||||
import getCourseRecommendations from './api';
|
||||
import {
|
||||
getCourseRecommendations,
|
||||
postUnsubscribeFromGoalReminders,
|
||||
} from './api';
|
||||
import { updateModel } from '../../../../generic/model-store';
|
||||
|
||||
export default function fetchCourseRecommendations(courseKey, courseId) {
|
||||
@@ -27,3 +30,7 @@ export default function fetchCourseRecommendations(courseKey, courseId) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function unsubscribeFromGoalReminders(courseId, daysPerWeek, subscribedToReminders) {
|
||||
return postUnsubscribeFromGoalReminders(courseId, daysPerWeek, subscribedToReminders);
|
||||
}
|
||||
|
||||
@@ -5,19 +5,19 @@ import { getConfig, history } from '@edx/frontend-platform';
|
||||
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
||||
import { ActionRow, Alert, Button } from '@edx/paragon';
|
||||
|
||||
import { useModel } from '../../../../generic/model-store';
|
||||
import { saveIntegritySignature } from '../../../data';
|
||||
import messages from './messages';
|
||||
|
||||
function HonorCode({ intl, courseId }) {
|
||||
const dispatch = useDispatch();
|
||||
const { isMasquerading } = useModel('coursewareMeta', courseId);
|
||||
const siteName = getConfig().SITE_NAME;
|
||||
const honorCodeUrl = `${process.env.TERMS_OF_SERVICE_URL}#honor-code`;
|
||||
const honorCodeUrl = `${getConfig().TERMS_OF_SERVICE_URL}#honor-code`;
|
||||
|
||||
const handleCancel = () => history.push(`/course/${courseId}/home`);
|
||||
|
||||
const handleAgree = () => {
|
||||
dispatch(saveIntegritySignature(courseId));
|
||||
};
|
||||
const handleAgree = () => dispatch(saveIntegritySignature(courseId, isMasquerading));
|
||||
|
||||
return (
|
||||
<Alert variant="light" aria-live="off">
|
||||
|
||||
@@ -8,6 +8,13 @@ Factory.define('courseMetadata')
|
||||
.attrs({
|
||||
content_type_gating_enabled: false,
|
||||
course_expired_message: null,
|
||||
course_goals: {
|
||||
goal_options: [],
|
||||
selected_goal: {
|
||||
days_per_week: 1,
|
||||
subscribed_to_reminders: true,
|
||||
},
|
||||
},
|
||||
end: null,
|
||||
enrollment_start: null,
|
||||
enrollment_end: null,
|
||||
|
||||
@@ -187,6 +187,7 @@ function normalizeMetadata(metadata) {
|
||||
accessExpiration: camelCaseObject(data.access_expiration),
|
||||
canShowUpgradeSock: data.can_show_upgrade_sock,
|
||||
contentTypeGatingEnabled: data.content_type_gating_enabled,
|
||||
courseGoals: data.course_goals,
|
||||
id: data.id,
|
||||
title: data.name,
|
||||
number: data.number,
|
||||
|
||||
@@ -247,7 +247,7 @@ export function checkBlockCompletion(courseId, sequenceId, unitId) {
|
||||
return async (dispatch, getState) => {
|
||||
const { models } = getState();
|
||||
if (models.units[unitId].complete) {
|
||||
return; // do nothing. Things don't get uncompleted after they are completed.
|
||||
return {}; // do nothing. Things don't get uncompleted after they are completed.
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -259,9 +259,11 @@ export function checkBlockCompletion(courseId, sequenceId, unitId) {
|
||||
complete: isComplete,
|
||||
},
|
||||
}));
|
||||
return isComplete;
|
||||
} catch (error) {
|
||||
logError(error);
|
||||
}
|
||||
return {};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -301,10 +303,15 @@ export function saveSequencePosition(courseId, sequenceId, activeUnitIndex) {
|
||||
};
|
||||
}
|
||||
|
||||
export function saveIntegritySignature(courseId) {
|
||||
export function saveIntegritySignature(courseId, isMasquerading) {
|
||||
return async (dispatch) => {
|
||||
try {
|
||||
await postIntegritySignature(courseId);
|
||||
// If the request is made by a staff user masquerading as a learner,
|
||||
// don't actually create a signature for them on the backend. Only
|
||||
// frontend state will be updated.
|
||||
if (!isMasquerading) {
|
||||
await postIntegritySignature(courseId);
|
||||
}
|
||||
dispatch(updateModel({
|
||||
modelType: 'coursewareMeta',
|
||||
model: {
|
||||
|
||||
35
src/generic/notices/NoticesProvider.jsx
Normal file
35
src/generic/notices/NoticesProvider.jsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import PropTypes from 'prop-types';
|
||||
import { getNotices } from './api';
|
||||
/**
|
||||
* This component uses the platform-plugin-notices plugin to function.
|
||||
* If the user has an unacknowledged notice, they will be rerouted off
|
||||
* course home and onto a full-screen notice page. If the plugin is not
|
||||
* installed, or there are no notices, we just passthrough this component.
|
||||
*/
|
||||
const NoticesProvider = ({ children }) => {
|
||||
const [isRedirected, setIsRedirected] = useState();
|
||||
useEffect(async () => {
|
||||
if (getConfig().ENABLE_NOTICES) {
|
||||
const data = await getNotices();
|
||||
if (data && data.results && data.results.length > 0) {
|
||||
const { results } = data;
|
||||
setIsRedirected(true);
|
||||
window.location.replace(`${results[0]}?next=${window.location.href}`);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{isRedirected === true ? null : children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
NoticesProvider.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
|
||||
export default NoticesProvider;
|
||||
61
src/generic/notices/NoticesProvider.test.jsx
Normal file
61
src/generic/notices/NoticesProvider.test.jsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import React from 'react';
|
||||
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import {
|
||||
initializeMockApp,
|
||||
render,
|
||||
act,
|
||||
} from '../../setupTest';
|
||||
import NoticesProvider from './NoticesProvider';
|
||||
import { getNotices } from './api';
|
||||
|
||||
jest.mock('./api', () => ({
|
||||
getNotices: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('@edx/frontend-platform', () => ({
|
||||
getConfig: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('NoticesProvider', () => {
|
||||
beforeAll(async () => {
|
||||
jest.resetModules();
|
||||
await initializeMockApp();
|
||||
});
|
||||
|
||||
function buildAndRender() {
|
||||
render(
|
||||
<NoticesProvider>
|
||||
<div />
|
||||
</NoticesProvider>,
|
||||
);
|
||||
}
|
||||
|
||||
it('does not call api if ENABLE_NOTICES is false', () => {
|
||||
getConfig.mockImplementation(() => ({ ENABLE_NOTICES: false }));
|
||||
buildAndRender();
|
||||
expect(getNotices).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it('redirects user on notice returned from API', async () => {
|
||||
const redirectUrl = 'http://example.com/test_route';
|
||||
getConfig.mockImplementation(() => ({ ENABLE_NOTICES: true }));
|
||||
getNotices.mockImplementation(() => ({ results: [redirectUrl] }));
|
||||
delete window.location;
|
||||
window.location = { replace: jest.fn() };
|
||||
process.env.ENABLE_NOTICES = true;
|
||||
await act(async () => buildAndRender());
|
||||
expect(window.location.replace).toHaveBeenCalledWith(`${redirectUrl}?next=${window.location.href}`);
|
||||
});
|
||||
|
||||
it('does not redirect on no data', async () => {
|
||||
getNotices.mockImplementation(() => ({}));
|
||||
getConfig.mockImplementation(() => ({ ENABLE_NOTICES: true }));
|
||||
delete window.location;
|
||||
window.location = { replace: jest.fn() };
|
||||
process.env.ENABLE_NOTICES = true;
|
||||
await act(async () => buildAndRender());
|
||||
expect(window.location.replace).toHaveBeenCalledTimes(0);
|
||||
expect(window.location.toString() === 'http://localhost/');
|
||||
});
|
||||
});
|
||||
25
src/generic/notices/api.js
Normal file
25
src/generic/notices/api.js
Normal file
@@ -0,0 +1,25 @@
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
import { getConfig } from '@edx/frontend-platform';
|
||||
import { getAuthenticatedHttpClient, getAuthenticatedUser } from '@edx/frontend-platform/auth';
|
||||
import { logError, logInfo } from '@edx/frontend-platform/logging';
|
||||
|
||||
export const getNotices = async () => {
|
||||
const authenticatedUser = getAuthenticatedUser();
|
||||
const url = new URL(`${getConfig().LMS_BASE_URL}/notices/api/v1/unacknowledged`);
|
||||
if (authenticatedUser) {
|
||||
try {
|
||||
const { data } = await getAuthenticatedHttpClient().get(url.href, {});
|
||||
return data;
|
||||
} catch (e) {
|
||||
// we will just swallow error, as that probably means the notices app is not installed.
|
||||
// Notices are not necessary for the rest of courseware to function.
|
||||
const { customAttributes: { httpErrorStatus } } = e;
|
||||
if (httpErrorStatus === 404) {
|
||||
logInfo(`${e}. This probably happened because the notices plugin is not installed on platform.`);
|
||||
} else {
|
||||
logError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
1
src/generic/notices/index.js
Normal file
1
src/generic/notices/index.js
Normal file
@@ -0,0 +1 @@
|
||||
export { default } from './NoticesProvider';
|
||||
@@ -28,54 +28,57 @@ import { TabContainer } from './tab-page';
|
||||
import { fetchDatesTab, fetchOutlineTab, fetchProgressTab } from './course-home/data';
|
||||
import { fetchCourse } from './courseware/data';
|
||||
import initializeStore from './store';
|
||||
import NoticesProvider from './generic/notices';
|
||||
|
||||
subscribe(APP_READY, () => {
|
||||
ReactDOM.render(
|
||||
<AppProvider store={initializeStore()}>
|
||||
<UserMessagesProvider>
|
||||
<Switch>
|
||||
<PageRoute exact path="/goal-unsubscribe/:token" component={GoalUnsubscribe} />
|
||||
<PageRoute path="/redirect" component={CoursewareRedirectLandingPage} />
|
||||
<PageRoute path="/course/:courseId/home">
|
||||
<TabContainer tab="outline" fetch={fetchOutlineTab} slice="courseHome">
|
||||
<OutlineTab />
|
||||
</TabContainer>
|
||||
</PageRoute>
|
||||
<PageRoute path="/course/:courseId/dates">
|
||||
<TabContainer tab="dates" fetch={fetchDatesTab} slice="courseHome">
|
||||
<DatesTab />
|
||||
</TabContainer>
|
||||
</PageRoute>
|
||||
<PageRoute
|
||||
path={[
|
||||
'/course/:courseId/progress/:targetUserId/',
|
||||
'/course/:courseId/progress',
|
||||
]}
|
||||
render={({ match }) => (
|
||||
<TabContainer
|
||||
tab="progress"
|
||||
fetch={(courseId) => fetchProgressTab(courseId, match.params.targetUserId)}
|
||||
slice="courseHome"
|
||||
>
|
||||
<ProgressTab />
|
||||
<NoticesProvider>
|
||||
<UserMessagesProvider>
|
||||
<Switch>
|
||||
<PageRoute exact path="/goal-unsubscribe/:token" component={GoalUnsubscribe} />
|
||||
<PageRoute path="/redirect" component={CoursewareRedirectLandingPage} />
|
||||
<PageRoute path="/course/:courseId/home">
|
||||
<TabContainer tab="outline" fetch={fetchOutlineTab} slice="courseHome">
|
||||
<OutlineTab />
|
||||
</TabContainer>
|
||||
)}
|
||||
/>
|
||||
<PageRoute path="/course/:courseId/course-end">
|
||||
<TabContainer tab="courseware" fetch={fetchCourse} slice="courseware">
|
||||
<CourseExit />
|
||||
</TabContainer>
|
||||
</PageRoute>
|
||||
<PageRoute
|
||||
path={[
|
||||
'/course/:courseId/:sequenceId/:unitId',
|
||||
'/course/:courseId/:sequenceId',
|
||||
'/course/:courseId',
|
||||
]}
|
||||
component={CoursewareContainer}
|
||||
/>
|
||||
</Switch>
|
||||
</UserMessagesProvider>
|
||||
</PageRoute>
|
||||
<PageRoute path="/course/:courseId/dates">
|
||||
<TabContainer tab="dates" fetch={fetchDatesTab} slice="courseHome">
|
||||
<DatesTab />
|
||||
</TabContainer>
|
||||
</PageRoute>
|
||||
<PageRoute
|
||||
path={[
|
||||
'/course/:courseId/progress/:targetUserId/',
|
||||
'/course/:courseId/progress',
|
||||
]}
|
||||
render={({ match }) => (
|
||||
<TabContainer
|
||||
tab="progress"
|
||||
fetch={(courseId) => fetchProgressTab(courseId, match.params.targetUserId)}
|
||||
slice="courseHome"
|
||||
>
|
||||
<ProgressTab />
|
||||
</TabContainer>
|
||||
)}
|
||||
/>
|
||||
<PageRoute path="/course/:courseId/course-end">
|
||||
<TabContainer tab="courseware" fetch={fetchCourse} slice="courseware">
|
||||
<CourseExit />
|
||||
</TabContainer>
|
||||
</PageRoute>
|
||||
<PageRoute
|
||||
path={[
|
||||
'/course/:courseId/:sequenceId/:unitId',
|
||||
'/course/:courseId/:sequenceId',
|
||||
'/course/:courseId',
|
||||
]}
|
||||
component={CoursewareContainer}
|
||||
/>
|
||||
</Switch>
|
||||
</UserMessagesProvider>
|
||||
</NoticesProvider>
|
||||
</AppProvider>,
|
||||
document.getElementById('root'),
|
||||
);
|
||||
@@ -92,7 +95,7 @@ initialize({
|
||||
CONTACT_URL: process.env.CONTACT_URL || null,
|
||||
CREDENTIALS_BASE_URL: process.env.CREDENTIALS_BASE_URL || null,
|
||||
ENTERPRISE_LEARNER_PORTAL_HOSTNAME: process.env.ENTERPRISE_LEARNER_PORTAL_HOSTNAME || null,
|
||||
ENABLE_JUMPNAV: process.env.ENABLE_JUMPNAV || null,
|
||||
ENABLE_NOTICES: process.env.ENABLE_NOTICES || null,
|
||||
INSIGHTS_BASE_URL: process.env.INSIGHTS_BASE_URL || null,
|
||||
SEARCH_CATALOG_URL: process.env.SEARCH_CATALOG_URL || null,
|
||||
SOCIAL_UTM_MILESTONE_CAMPAIGN: process.env.SOCIAL_UTM_MILESTONE_CAMPAIGN || null,
|
||||
@@ -101,6 +104,7 @@ initialize({
|
||||
SUPPORT_URL_CALCULATOR_MATH: process.env.SUPPORT_URL_CALCULATOR_MATH || null,
|
||||
SUPPORT_URL_ID_VERIFICATION: process.env.SUPPORT_URL_ID_VERIFICATION || null,
|
||||
SUPPORT_URL_VERIFIED_CERTIFICATE: process.env.SUPPORT_URL_VERIFIED_CERTIFICATE || null,
|
||||
TERMS_OF_SERVICE_URL: process.env.TERMS_OF_SERVICE_URL || null,
|
||||
TWITTER_HASHTAG: process.env.TWITTER_HASHTAG || null,
|
||||
TWITTER_URL: process.env.TWITTER_URL || null,
|
||||
}, 'LearnerAppConfig');
|
||||
|
||||
Reference in New Issue
Block a user