more centralization

This commit is contained in:
2024-09-27 11:06:54 -06:00
parent ae8bd1297e
commit f990619e05
13 changed files with 205 additions and 225 deletions

129
nextjs/package-lock.json generated
View File

@@ -8,21 +8,13 @@
"name": "canvas-mangement", "name": "canvas-mangement",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@monaco-editor/react": "^4.6.0",
"@tanstack/react-query": "^5.54.1",
"axios": "^1.7.5",
"isomorphic-dompurify": "^2.15.0",
"katex": "^0.16.11",
"marked": "^14.1.2",
"marked-katex-extension": "^5.1.2",
"next": "^14.2.7", "next": "^14.2.7",
"react": "^18", "react": "^18",
"react-dom": "^18", "react-dom": "^18"
"react-error-boundary": "^4.0.13",
"react-hot-toast": "^2.4.1",
"yaml": "^2.5.0"
}, },
"devDependencies": { "devDependencies": {
"@monaco-editor/react": "^4.6.0",
"@tanstack/react-query": "^5.54.1",
"@tanstack/react-query-devtools": "^5.54.1", "@tanstack/react-query-devtools": "^5.54.1",
"@testing-library/dom": "^10.4.0", "@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.0.0", "@testing-library/react": "^16.0.0",
@@ -30,12 +22,18 @@
"@types/react": "^18", "@types/react": "^18",
"@types/react-dom": "^18", "@types/react-dom": "^18",
"@vitejs/plugin-react": "^4.3.1", "@vitejs/plugin-react": "^4.3.1",
"axios": "^1.7.5",
"eslint-config-next": "^14.2.7", "eslint-config-next": "^14.2.7",
"isomorphic-dompurify": "^2.15.0",
"jsdom": "^25.0.0", "jsdom": "^25.0.0",
"marked": "^14.1.2",
"postcss": "^8", "postcss": "^8",
"react-error-boundary": "^4.0.13",
"react-hot-toast": "^2.4.1",
"tailwindcss": "^3.4.1", "tailwindcss": "^3.4.1",
"typescript": "^5", "typescript": "^5",
"vitest": "^2.0.5" "vitest": "^2.0.5",
"yaml": "^2.5.0"
} }
}, },
"node_modules/@alloc/quick-lru": { "node_modules/@alloc/quick-lru": {
@@ -400,6 +398,7 @@
"version": "7.25.6", "version": "7.25.6",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz",
"integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==", "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"regenerator-runtime": "^0.14.0" "regenerator-runtime": "^0.14.0"
@@ -1087,6 +1086,7 @@
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz", "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz",
"integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==", "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"state-local": "^1.0.6" "state-local": "^1.0.6"
@@ -1099,6 +1099,7 @@
"version": "4.6.0", "version": "4.6.0",
"resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz", "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz",
"integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==", "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@monaco-editor/loader": "^1.4.0" "@monaco-editor/loader": "^1.4.0"
@@ -1579,6 +1580,7 @@
"version": "5.54.1", "version": "5.54.1",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.54.1.tgz", "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.54.1.tgz",
"integrity": "sha512-hKS+WRpT5zBFip21pB6Jx1C0hranWQrbv5EJ7qPoiV5MYI3C8rTCqWC9DdBseiPT1JgQWh8Y55YthuYZNiw3Xw==", "integrity": "sha512-hKS+WRpT5zBFip21pB6Jx1C0hranWQrbv5EJ7qPoiV5MYI3C8rTCqWC9DdBseiPT1JgQWh8Y55YthuYZNiw3Xw==",
"dev": true,
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"type": "github", "type": "github",
@@ -1600,6 +1602,7 @@
"version": "5.54.1", "version": "5.54.1",
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.54.1.tgz", "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.54.1.tgz",
"integrity": "sha512-SuMi4JBYv49UtmiRyqjxY7XAnE1qwLht9nlkC8sioxFXz5Uzj30lepiKf2mYXuXfC7fHYjTrAPkNx+427pRHXA==", "integrity": "sha512-SuMi4JBYv49UtmiRyqjxY7XAnE1qwLht9nlkC8sioxFXz5Uzj30lepiKf2mYXuXfC7fHYjTrAPkNx+427pRHXA==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@tanstack/query-core": "5.54.1" "@tanstack/query-core": "5.54.1"
@@ -1734,6 +1737,7 @@
"version": "3.0.5", "version": "3.0.5",
"resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz", "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz",
"integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==", "integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@types/trusted-types": "*" "@types/trusted-types": "*"
@@ -1753,12 +1757,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/katex": {
"version": "0.16.7",
"resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz",
"integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==",
"license": "MIT"
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "22.5.2", "version": "22.5.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.2.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.2.tgz",
@@ -1801,6 +1799,7 @@
"version": "2.0.7", "version": "2.0.7",
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
@@ -2094,6 +2093,7 @@
"version": "7.1.1", "version": "7.1.1",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
"integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"debug": "^4.3.4" "debug": "^4.3.4"
@@ -2381,6 +2381,7 @@
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/available-typed-arrays": { "node_modules/available-typed-arrays": {
@@ -2413,6 +2414,7 @@
"version": "1.7.7", "version": "1.7.7",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
"integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"follow-redirects": "^1.15.6", "follow-redirects": "^1.15.6",
@@ -2710,6 +2712,7 @@
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"delayed-stream": "~1.0.0" "delayed-stream": "~1.0.0"
@@ -2774,6 +2777,7 @@
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz",
"integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"rrweb-cssom": "^0.6.0" "rrweb-cssom": "^0.6.0"
@@ -2786,12 +2790,14 @@
"version": "0.6.0", "version": "0.6.0",
"resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz",
"integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/csstype": { "node_modules/csstype": {
"version": "3.1.3", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/damerau-levenshtein": { "node_modules/damerau-levenshtein": {
@@ -2805,6 +2811,7 @@
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz",
"integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"whatwg-mimetype": "^4.0.0", "whatwg-mimetype": "^4.0.0",
@@ -2872,6 +2879,7 @@
"version": "4.3.6", "version": "4.3.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
"integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"ms": "2.1.2" "ms": "2.1.2"
@@ -2889,6 +2897,7 @@
"version": "10.4.3", "version": "10.4.3",
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
"integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/deep-eql": { "node_modules/deep-eql": {
@@ -2982,6 +2991,7 @@
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=0.4.0" "node": ">=0.4.0"
@@ -3049,6 +3059,7 @@
"version": "3.1.6", "version": "3.1.6",
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz", "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz",
"integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==", "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==",
"dev": true,
"license": "(MPL-2.0 OR Apache-2.0)" "license": "(MPL-2.0 OR Apache-2.0)"
}, },
"node_modules/eastasianwidth": { "node_modules/eastasianwidth": {
@@ -3090,6 +3101,7 @@
"version": "4.5.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"dev": true,
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"engines": { "engines": {
"node": ">=0.12" "node": ">=0.12"
@@ -3977,6 +3989,7 @@
"version": "1.15.6", "version": "1.15.6",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"dev": true,
"funding": [ "funding": [
{ {
"type": "individual", "type": "individual",
@@ -4024,6 +4037,7 @@
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"asynckit": "^0.4.0", "asynckit": "^0.4.0",
@@ -4294,6 +4308,7 @@
"version": "2.1.14", "version": "2.1.14",
"resolved": "https://registry.npmjs.org/goober/-/goober-2.1.14.tgz", "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.14.tgz",
"integrity": "sha512-4UpC0NdGyAFqLNPnhCT2iHpza2q+RAY3GV85a/mRPdzyPQMsj0KmMMuetdIkzWRbJ+Hgau1EZztq8ImmiMGhsg==", "integrity": "sha512-4UpC0NdGyAFqLNPnhCT2iHpza2q+RAY3GV85a/mRPdzyPQMsj0KmMMuetdIkzWRbJ+Hgau1EZztq8ImmiMGhsg==",
"dev": true,
"license": "MIT", "license": "MIT",
"peerDependencies": { "peerDependencies": {
"csstype": "^3.0.10" "csstype": "^3.0.10"
@@ -4418,6 +4433,7 @@
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz",
"integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"whatwg-encoding": "^3.1.1" "whatwg-encoding": "^3.1.1"
@@ -4430,6 +4446,7 @@
"version": "7.0.2", "version": "7.0.2",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
"integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"agent-base": "^7.1.0", "agent-base": "^7.1.0",
@@ -4443,6 +4460,7 @@
"version": "7.0.5", "version": "7.0.5",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz",
"integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"agent-base": "^7.0.2", "agent-base": "^7.0.2",
@@ -4466,6 +4484,7 @@
"version": "0.6.3", "version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0" "safer-buffer": ">= 2.1.2 < 3.0.0"
@@ -4855,6 +4874,7 @@
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
"integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/is-regex": { "node_modules/is-regex": {
@@ -5025,6 +5045,7 @@
"version": "2.15.0", "version": "2.15.0",
"resolved": "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-2.15.0.tgz", "resolved": "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-2.15.0.tgz",
"integrity": "sha512-RDHlyeVmwEDAPZuX1VaaBzSn9RrsfvswxH7faEQK9cTHC1dXeNuK6ElUeSr7locFyeLguut8ASfhQWxHB4Ttug==", "integrity": "sha512-RDHlyeVmwEDAPZuX1VaaBzSn9RrsfvswxH7faEQK9cTHC1dXeNuK6ElUeSr7locFyeLguut8ASfhQWxHB4Ttug==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@types/dompurify": "^3.0.5", "@types/dompurify": "^3.0.5",
@@ -5102,6 +5123,7 @@
"version": "25.0.0", "version": "25.0.0",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.0.tgz", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.0.tgz",
"integrity": "sha512-OhoFVT59T7aEq75TVw9xxEfkXgacpqAhQaYgP9y/fDqWQCMB/b1H66RfmPm/MaeaAIU9nDwMOVTlPN51+ao6CQ==", "integrity": "sha512-OhoFVT59T7aEq75TVw9xxEfkXgacpqAhQaYgP9y/fDqWQCMB/b1H66RfmPm/MaeaAIU9nDwMOVTlPN51+ao6CQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"cssstyle": "^4.0.1", "cssstyle": "^4.0.1",
@@ -5204,31 +5226,6 @@
"node": ">=4.0" "node": ">=4.0"
} }
}, },
"node_modules/katex": {
"version": "0.16.11",
"resolved": "https://registry.npmjs.org/katex/-/katex-0.16.11.tgz",
"integrity": "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==",
"funding": [
"https://opencollective.com/katex",
"https://github.com/sponsors/katex"
],
"license": "MIT",
"dependencies": {
"commander": "^8.3.0"
},
"bin": {
"katex": "cli.js"
}
},
"node_modules/katex/node_modules/commander": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
"license": "MIT",
"engines": {
"node": ">= 12"
}
},
"node_modules/keyv": { "node_modules/keyv": {
"version": "4.5.4", "version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
@@ -5373,6 +5370,7 @@
"version": "14.1.2", "version": "14.1.2",
"resolved": "https://registry.npmjs.org/marked/-/marked-14.1.2.tgz", "resolved": "https://registry.npmjs.org/marked/-/marked-14.1.2.tgz",
"integrity": "sha512-f3r0yqpz31VXiDB/wj9GaOB0a2PRLQl6vJmXiFrniNwjkKdvakqJRULhjFKJpxOchlCRiG5fcacoUZY5Xa6PEQ==", "integrity": "sha512-f3r0yqpz31VXiDB/wj9GaOB0a2PRLQl6vJmXiFrniNwjkKdvakqJRULhjFKJpxOchlCRiG5fcacoUZY5Xa6PEQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"bin": { "bin": {
"marked": "bin/marked.js" "marked": "bin/marked.js"
@@ -5381,19 +5379,6 @@
"node": ">= 18" "node": ">= 18"
} }
}, },
"node_modules/marked-katex-extension": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/marked-katex-extension/-/marked-katex-extension-5.1.2.tgz",
"integrity": "sha512-jRtacvDAPULKBWArDno0IGpzzpUw12yb8OaEsv3dTlvcIr21+mF9kD+Bxo2m/ErX/2ZIml6zFVMnpxCpqx3stw==",
"license": "MIT",
"dependencies": {
"@types/katex": "^0.16.7"
},
"peerDependencies": {
"katex": ">=0.16 <0.17",
"marked": ">=4 <15"
}
},
"node_modules/merge-stream": { "node_modules/merge-stream": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -5429,6 +5414,7 @@
"version": "1.52.0", "version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 0.6" "node": ">= 0.6"
@@ -5438,6 +5424,7 @@
"version": "2.1.35", "version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"mime-db": "1.52.0" "mime-db": "1.52.0"
@@ -5496,6 +5483,7 @@
"version": "0.50.0", "version": "0.50.0",
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.50.0.tgz", "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.50.0.tgz",
"integrity": "sha512-8CclLCmrRRh+sul7C08BmPBP3P8wVWfBHomsTcndxg5NRCEPfu/mc2AGU8k37ajjDVXcXFc12ORAMUkmk+lkFA==", "integrity": "sha512-8CclLCmrRRh+sul7C08BmPBP3P8wVWfBHomsTcndxg5NRCEPfu/mc2AGU8k37ajjDVXcXFc12ORAMUkmk+lkFA==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true "peer": true
}, },
@@ -5503,6 +5491,7 @@
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/mz": { "node_modules/mz": {
@@ -5671,6 +5660,7 @@
"version": "2.2.12", "version": "2.2.12",
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz",
"integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==", "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/object-assign": { "node_modules/object-assign": {
@@ -5917,6 +5907,7 @@
"version": "7.1.2", "version": "7.1.2",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
"integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"entities": "^4.4.0" "entities": "^4.4.0"
@@ -6289,18 +6280,21 @@
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/psl": { "node_modules/psl": {
"version": "1.9.0", "version": "1.9.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
"integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/punycode": { "node_modules/punycode": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=6" "node": ">=6"
@@ -6310,6 +6304,7 @@
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/queue-microtask": { "node_modules/queue-microtask": {
@@ -6362,6 +6357,7 @@
"version": "4.0.13", "version": "4.0.13",
"resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.13.tgz", "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.13.tgz",
"integrity": "sha512-b6PwbdSv8XeOSYvjt8LpgpKrZ0yGdtZokYwkwV2wlcZbxgopHX/hgPl5VgpnoVOWd868n1hktM8Qm4b+02MiLQ==", "integrity": "sha512-b6PwbdSv8XeOSYvjt8LpgpKrZ0yGdtZokYwkwV2wlcZbxgopHX/hgPl5VgpnoVOWd868n1hktM8Qm4b+02MiLQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.12.5" "@babel/runtime": "^7.12.5"
@@ -6374,6 +6370,7 @@
"version": "2.4.1", "version": "2.4.1",
"resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.4.1.tgz", "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.4.1.tgz",
"integrity": "sha512-j8z+cQbWIM5LY37pR6uZR6D4LfseplqnuAO4co4u8917hBUvXlEqyP1ZzqVLcqoyUesZZv/ImreoCeHVDpE5pQ==", "integrity": "sha512-j8z+cQbWIM5LY37pR6uZR6D4LfseplqnuAO4co4u8917hBUvXlEqyP1ZzqVLcqoyUesZZv/ImreoCeHVDpE5pQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"goober": "^2.1.10" "goober": "^2.1.10"
@@ -6452,6 +6449,7 @@
"version": "0.14.1", "version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/regexp.prototype.flags": { "node_modules/regexp.prototype.flags": {
@@ -6477,6 +6475,7 @@
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/resolve": { "node_modules/resolve": {
@@ -6610,6 +6609,7 @@
"version": "0.7.1", "version": "0.7.1",
"resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz",
"integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/run-parallel": { "node_modules/run-parallel": {
@@ -6677,12 +6677,14 @@
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/saxes": { "node_modules/saxes": {
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
"integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
"dev": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"xmlchars": "^2.2.0" "xmlchars": "^2.2.0"
@@ -6861,6 +6863,7 @@
"version": "1.0.7", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz",
"integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==", "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/std-env": { "node_modules/std-env": {
@@ -7202,6 +7205,7 @@
"version": "3.2.4", "version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/tailwindcss": { "node_modules/tailwindcss": {
@@ -7377,6 +7381,7 @@
"version": "4.1.4", "version": "4.1.4",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
"integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
"dev": true,
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"dependencies": { "dependencies": {
"psl": "^1.1.33", "psl": "^1.1.33",
@@ -7392,6 +7397,7 @@
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz",
"integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"punycode": "^2.3.1" "punycode": "^2.3.1"
@@ -7598,6 +7604,7 @@
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
"integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 4.0.0" "node": ">= 4.0.0"
@@ -7649,6 +7656,7 @@
"version": "1.5.10", "version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"querystringify": "^2.1.1", "querystringify": "^2.1.1",
@@ -7814,6 +7822,7 @@
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
"integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"xml-name-validator": "^5.0.0" "xml-name-validator": "^5.0.0"
@@ -7826,6 +7835,7 @@
"version": "7.0.0", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
"integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
"dev": true,
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"engines": { "engines": {
"node": ">=12" "node": ">=12"
@@ -7835,6 +7845,7 @@
"version": "3.1.1", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
"integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"iconv-lite": "0.6.3" "iconv-lite": "0.6.3"
@@ -7847,6 +7858,7 @@
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
"integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=18" "node": ">=18"
@@ -7856,6 +7868,7 @@
"version": "14.0.0", "version": "14.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz",
"integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"tr46": "^5.0.0", "tr46": "^5.0.0",
@@ -8105,6 +8118,7 @@
"version": "8.18.0", "version": "8.18.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0"
@@ -8126,6 +8140,7 @@
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz",
"integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==",
"dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"engines": { "engines": {
"node": ">=18" "node": ">=18"
@@ -8135,6 +8150,7 @@
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/yallist": { "node_modules/yallist": {
@@ -8148,6 +8164,7 @@
"version": "2.5.0", "version": "2.5.0",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz",
"integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==",
"dev": true,
"license": "ISC", "license": "ISC",
"bin": { "bin": {
"yaml": "bin.mjs" "yaml": "bin.mjs"

View File

@@ -6,7 +6,7 @@
"dev": "next dev", "dev": "next dev",
"build": "next build", "build": "next build",
"start": "next start", "start": "next start",
"lint": "next lint", "lint": "tsc && next lint",
"test": "vitest" "test": "vitest"
}, },
"dependencies": { "dependencies": {

View File

@@ -8,9 +8,9 @@ export const GET = async (
}: { params: { courseName: string; moduleName: string } } }: { params: { courseName: string; moduleName: string } }
) => ) =>
await withErrorHandling(async () => { await withErrorHandling(async () => {
const settings = await fileStorageService.pages.getPageNames( const pages = await fileStorageService.pages.getPages(
courseName, courseName,
moduleName moduleName
); );
return Response.json(settings); return Response.json(pages);
}); });

View File

@@ -8,9 +8,9 @@ export const GET = async (
}: { params: { courseName: string; moduleName: string } } }: { params: { courseName: string; moduleName: string } }
) => ) =>
await withErrorHandling(async () => { await withErrorHandling(async () => {
const settings = await fileStorageService.quizzes.getQuizNames( const quizzes = await fileStorageService.quizzes.getQuizzes(
courseName, courseName,
moduleName moduleName
); );
return Response.json(settings); return Response.json(quizzes);
}); });

View File

@@ -1,13 +1,9 @@
"use client"; "use client";
import { useAssignmentsQueries } from "@/hooks/localCourse/assignmentHooks";
import { import {
useAssignmentsQueries,
} from "@/hooks/localCourse/assignmentHooks";
import {
usePageNamesQuery,
usePagesQueries, usePagesQueries,
} from "@/hooks/localCourse/pageHooks"; } from "@/hooks/localCourse/pageHooks";
import { import {
useQuizNamesQuery,
useQuizzesQueries, useQuizzesQueries,
} from "@/hooks/localCourse/quizHooks"; } from "@/hooks/localCourse/quizHooks";
import { IModuleItem } from "@/models/local/IModuleItem"; import { IModuleItem } from "@/models/local/IModuleItem";
@@ -33,15 +29,11 @@ export default function ExpandableModule({
}: { }: {
moduleName: string; moduleName: string;
}) { }) {
const { data: quizNames } = useQuizNamesQuery(moduleName);
const { data: pageNames } = usePageNamesQuery(moduleName);
const { itemDropOnModule } = useDraggingContext(); const { itemDropOnModule } = useDraggingContext();
const { data: assignments } = useAssignmentsQueries( const { data: assignments } = useAssignmentsQueries(moduleName);
moduleName, const { data: quizzes } = useQuizzesQueries(moduleName);
); const { data: pages } = usePagesQueries(moduleName);
const { data: quizzes } = useQuizzesQueries(moduleName, quizNames);
const { data: pages } = usePagesQueries(moduleName, pageNames);
const [expanded, setExpanded] = useState(false); const [expanded, setExpanded] = useState(false);

View File

@@ -73,16 +73,16 @@ export const hydrateCanvasCourse = async (
}; };
const loadAllModuleData = async (courseName: string, moduleName: string) => { const loadAllModuleData = async (courseName: string, moduleName: string) => {
const [assignmentNames, pageNames, quizNames] = await Promise.all([ const [assignmentNames, pages, quizzes] = await Promise.all([
await fileStorageService.assignments.getAssignmentNames( await fileStorageService.assignments.getAssignmentNames(
courseName, courseName,
moduleName moduleName
), ),
await fileStorageService.pages.getPageNames(courseName, moduleName), await fileStorageService.pages.getPages(courseName, moduleName),
await fileStorageService.quizzes.getQuizNames(courseName, moduleName), await fileStorageService.quizzes.getQuizzes(courseName, moduleName),
]); ]);
const [assignments, quizzes, pages] = await Promise.all([ const [assignments] = await Promise.all([
await Promise.all( await Promise.all(
assignmentNames.map(async (assignmentName) => { assignmentNames.map(async (assignmentName) => {
try { try {
@@ -97,33 +97,11 @@ const loadAllModuleData = async (courseName: string, moduleName: string) => {
} }
}) })
), ),
await Promise.all(
quizNames.map(
async (quizName) =>
await fileStorageService.quizzes.getQuiz(
courseName,
moduleName,
quizName
)
)
),
await Promise.all(
pageNames.map(
async (pageName) =>
await fileStorageService.pages.getPage(
courseName,
moduleName,
pageName
)
)
),
]); ]);
const assignmentsLoaded = assignments.filter(a => a !== null); const assignmentsLoaded = assignments.filter((a) => a !== null);
return { return {
moduleName, moduleName,
pageNames,
quizNames,
assignments: assignmentsLoaded, assignments: assignmentsLoaded,
quizzes, quizzes,
pages, pages,
@@ -133,15 +111,11 @@ const loadAllModuleData = async (courseName: string, moduleName: string) => {
const hydrateModuleData = async ( const hydrateModuleData = async (
{ {
moduleName, moduleName,
pageNames,
quizNames,
assignments, assignments,
quizzes, quizzes,
pages, pages,
}: { }: {
moduleName: string; moduleName: string;
pageNames: string[];
quizNames: string[];
assignments: LocalAssignment[]; assignments: LocalAssignment[];
quizzes: LocalQuiz[]; quizzes: LocalQuiz[];
pages: LocalCoursePage[]; pages: LocalCoursePage[];
@@ -153,6 +127,14 @@ const hydrateModuleData = async (
queryKey: localCourseKeys.allAssignments(courseName, moduleName), queryKey: localCourseKeys.allAssignments(courseName, moduleName),
queryFn: () => assignments, queryFn: () => assignments,
}); });
await queryClient.prefetchQuery({
queryKey: localCourseKeys.allQuizzes(courseName, moduleName),
queryFn: () => quizzes,
});
await queryClient.prefetchQuery({
queryKey: localCourseKeys.allPages(courseName, moduleName),
queryFn: () => pages,
});
await Promise.all( await Promise.all(
assignments.map( assignments.map(
async (assignment) => async (assignment) =>
@@ -166,10 +148,6 @@ const hydrateModuleData = async (
}) })
) )
); );
await queryClient.prefetchQuery({
queryKey: localCourseKeys.quizNames(courseName, moduleName),
queryFn: () => quizNames,
});
await Promise.all( await Promise.all(
quizzes.map( quizzes.map(
async (quiz) => async (quiz) =>
@@ -179,10 +157,6 @@ const hydrateModuleData = async (
}) })
) )
); );
await queryClient.prefetchQuery({
queryKey: localCourseKeys.pageNames(courseName, moduleName),
queryFn: () => pageNames,
});
await Promise.all( await Promise.all(
pages.map( pages.map(
async (page) => async (page) =>

View File

@@ -28,7 +28,7 @@ export const getAllAssignmentsQueryConfig = (
}, },
}); });
export const useAllAssignmentNamesQuery = (moduleName: string) => { const useAllAssignmentsQuery = (moduleName: string) => {
const { courseName } = useCourseContext(); const { courseName } = useCourseContext();
return useSuspenseQuery(getAllAssignmentsQueryConfig(courseName, moduleName)); return useSuspenseQuery(getAllAssignmentsQueryConfig(courseName, moduleName));
}; };
@@ -70,7 +70,7 @@ export const useAssignmentQuery = (
}; };
export const useAssignmentsQueries = (moduleName: string) => { export const useAssignmentsQueries = (moduleName: string) => {
const { data: allAssignments } = useAllAssignmentNamesQuery(moduleName); const { data: allAssignments } = useAllAssignmentsQuery(moduleName);
const { courseName } = useCourseContext(); const { courseName } = useCourseContext();
return useSuspenseQueries({ return useSuspenseQueries({
queries: allAssignments.map((assignment) => queries: allAssignments.map((assignment) =>

View File

@@ -19,23 +19,23 @@ export const localCourseKeys = {
"assignments", "assignments",
{ type: "all assignments" }, { type: "all assignments" },
] as const, ] as const,
quizNames: (courseName: string, moduleName: string) => allQuizzes: (courseName: string, moduleName: string) =>
[ [
"course details", "course details",
courseName, courseName,
"modules", "modules",
moduleName, moduleName,
"quizzes", "quizzes",
{ type: "names" }, { type: "all quizzes" },
] as const, ] as const,
pageNames: (courseName: string, moduleName: string) => allPages: (courseName: string, moduleName: string) =>
[ [
"course details", "course details",
courseName, courseName,
"modules", "modules",
moduleName, moduleName,
"pages", "pages",
{ type: "names" }, { type: "all pages" },
] as const, ] as const,
assignment: ( assignment: (
courseName: string, courseName: string,

View File

@@ -11,8 +11,8 @@ import {
getAllAssignmentsQueryConfig, getAllAssignmentsQueryConfig,
getAssignmentQueryConfig, getAssignmentQueryConfig,
} from "./assignmentHooks"; } from "./assignmentHooks";
import { getPageNamesQueryConfig, getPageQueryConfig } from "./pageHooks"; import { getAllPagesQueryConfig, getPageQueryConfig } from "./pageHooks";
import { getQuizNamesQueryConfig, getQuizQueryConfig } from "./quizHooks"; import { getAllQuizzesQueryConfig, getQuizQueryConfig } from "./quizHooks";
export const useModuleNamesQuery = () => { export const useModuleNamesQuery = () => {
const { courseName } = useCourseContext(); const { courseName } = useCourseContext();
@@ -92,57 +92,15 @@ export const useAllCourseDataQuery = () => {
}), }),
}); });
// const { data: assignmentsAndModules } = useSuspenseQueries({
// queries: assignmentsAndModules.map(
// ({ moduleName, assignment }, i) =>
// getAssignmentQueryConfig(courseName, moduleName, assignment)
// ),
// combine: (results) => ({
// data: results.flatMap((r, i) => ({
// moduleName: assignmentsAndModules[i].moduleName,
// assignment: r.data,
// })),
// pending: results.some((r) => r.isPending),
// }),
// });
const { data: quizNamesAndModules } = useSuspenseQueries({
queries: moduleNames.map((moduleName) =>
getQuizNamesQueryConfig(courseName, moduleName)
),
combine: (results) => ({
data: results.flatMap((r, i) =>
r.data.map((quizName) => ({
moduleName: moduleNames[i],
quizName: quizName,
}))
),
pending: results.some((r) => r.isPending),
}),
});
const { data: quizzesAndModules } = useSuspenseQueries({ const { data: quizzesAndModules } = useSuspenseQueries({
queries: quizNamesAndModules.map(({ moduleName, quizName }, i) =>
getQuizQueryConfig(courseName, moduleName, quizName)
),
combine: (results) => ({
data: results.flatMap((r, i) => ({
moduleName: quizNamesAndModules[i].moduleName,
quiz: r.data,
})),
pending: results.some((r) => r.isPending),
}),
});
const { data: pageNamesAndModules } = useSuspenseQueries({
queries: moduleNames.map((moduleName) => queries: moduleNames.map((moduleName) =>
getPageNamesQueryConfig(courseName, moduleName) getAllQuizzesQueryConfig(courseName, moduleName)
), ),
combine: (results) => ({ combine: (results) => ({
data: results.flatMap((r, i) => data: results.flatMap((r, i) =>
r.data.map((pageName) => ({ r.data.map((quiz) => ({
moduleName: moduleNames[i], moduleName: moduleNames[i],
pageName, quiz,
})) }))
), ),
pending: results.some((r) => r.isPending), pending: results.some((r) => r.isPending),
@@ -150,14 +108,16 @@ export const useAllCourseDataQuery = () => {
}); });
const { data: pagesAndModules } = useSuspenseQueries({ const { data: pagesAndModules } = useSuspenseQueries({
queries: pageNamesAndModules.map(({ moduleName, pageName }, i) => queries: moduleNames.map((moduleName) =>
getPageQueryConfig(courseName, moduleName, pageName) getAllPagesQueryConfig(courseName, moduleName)
), ),
combine: (results) => ({ combine: (results) => ({
data: results.flatMap((r, i) => ({ data: results.flatMap((r, i) =>
moduleName: pageNamesAndModules[i].moduleName, r.data.map((page) => ({
page: r.data, moduleName: moduleNames[i],
})), page,
}))
),
pending: results.some((r) => r.isPending), pending: results.some((r) => r.isPending),
}), }),
}); });

View File

@@ -10,13 +10,10 @@ import { localCourseKeys } from "./localCourseKeys";
import { useCourseContext } from "@/app/course/[courseName]/context/courseContext"; import { useCourseContext } from "@/app/course/[courseName]/context/courseContext";
import { axiosClient } from "@/services/axiosUtils"; import { axiosClient } from "@/services/axiosUtils";
export function getPageNamesQueryConfig( export function getAllPagesQueryConfig(courseName: string, moduleName: string) {
courseName: string,
moduleName: string
) {
return { return {
queryKey: localCourseKeys.pageNames(courseName, moduleName), queryKey: localCourseKeys.allPages(courseName, moduleName),
queryFn: async (): Promise<string[]> => { queryFn: async (): Promise<LocalCoursePage[]> => {
const url = const url =
"/api/courses/" + "/api/courses/" +
encodeURIComponent(courseName) + encodeURIComponent(courseName) +
@@ -29,29 +26,6 @@ export function getPageNamesQueryConfig(
}; };
} }
export const usePageNamesQuery = (moduleName: string) => {
const { courseName } = useCourseContext();
return useSuspenseQuery(getPageNamesQueryConfig(courseName, moduleName));
};
export const usePageQuery = (moduleName: string, pageName: string) => {
const { courseName } = useCourseContext();
return useSuspenseQuery(getPageQueryConfig(courseName, moduleName, pageName));
};
export const usePagesQueries = (moduleName: string, pageNames: string[]) => {
const { courseName } = useCourseContext();
return useSuspenseQueries({
queries: pageNames.map((name) =>
getPageQueryConfig(courseName, moduleName, name)
),
combine: (results) => ({
data: results.map((r) => r.data),
pending: results.some((r) => r.isPending),
}),
});
};
export function getPageQueryConfig( export function getPageQueryConfig(
courseName: string, courseName: string,
moduleName: string, moduleName: string,
@@ -72,13 +46,37 @@ export function getPageQueryConfig(
return response.data; return response.data;
} catch (e) { } catch (e) {
console.log("error getting page", e, url); console.log("error getting page", e, url);
debugger;
throw e; throw e;
} }
}, },
}; };
} }
export const usePageQuery = (moduleName: string, pageName: string) => {
const { courseName } = useCourseContext();
return useSuspenseQuery(getPageQueryConfig(courseName, moduleName, pageName));
};
const useAllPagesQuery = (moduleName: string) => {
const { courseName } = useCourseContext();
return useSuspenseQuery(getAllPagesQueryConfig(courseName, moduleName));
};
export const usePagesQueries = (moduleName: string) => {
const { courseName } = useCourseContext();
const { data: allPages } = useAllPagesQuery(moduleName);
return useSuspenseQueries({
queries: allPages.map((page) => ({
...getPageQueryConfig(courseName, moduleName, page.name),
queryFn: () => page,
})),
combine: (results) => ({
data: results.map((r) => r.data),
pending: results.some((r) => r.isPending),
}),
});
};
export const useUpdatePageMutation = () => { export const useUpdatePageMutation = () => {
const { courseName } = useCourseContext(); const { courseName } = useCourseContext();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
@@ -109,7 +107,7 @@ export const useUpdatePageMutation = () => {
), ),
}); });
queryClient.removeQueries({ queryClient.removeQueries({
queryKey: localCourseKeys.pageNames(courseName, moduleName), queryKey: localCourseKeys.allPages(courseName, moduleName),
}); });
} }
queryClient.setQueryData( queryClient.setQueryData(
@@ -131,7 +129,7 @@ export const useUpdatePageMutation = () => {
}, },
onSuccess: async (_, { moduleName, pageName }) => { onSuccess: async (_, { moduleName, pageName }) => {
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: localCourseKeys.pageNames(courseName, moduleName), queryKey: localCourseKeys.allPages(courseName, moduleName),
}); });
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: localCourseKeys.page(courseName, moduleName, pageName), queryKey: localCourseKeys.page(courseName, moduleName, pageName),
@@ -171,7 +169,7 @@ export const useCreatePageMutation = () => {
queryKey: localCourseKeys.page(courseName, moduleName, pageName), queryKey: localCourseKeys.page(courseName, moduleName, pageName),
}); });
queryClient.invalidateQueries({ queryClient.invalidateQueries({
queryKey: localCourseKeys.pageNames(courseName, moduleName), queryKey: localCourseKeys.allPages(courseName, moduleName),
}); });
}, },
}); });
@@ -192,7 +190,7 @@ export const useDeletePageMutation = () => {
queryKey: localCourseKeys.page(courseName, moduleName, pageName), queryKey: localCourseKeys.page(courseName, moduleName, pageName),
}); });
queryClient.removeQueries({ queryClient.removeQueries({
queryKey: localCourseKeys.pageNames(courseName, moduleName), queryKey: localCourseKeys.allPages(courseName, moduleName),
}); });
const url = const url =
"/api/courses/" + "/api/courses/" +
@@ -202,11 +200,10 @@ export const useDeletePageMutation = () => {
"/pages/" + "/pages/" +
encodeURIComponent(pageName); encodeURIComponent(pageName);
await axiosClient.delete(url); await axiosClient.delete(url);
}, },
onSuccess: async (_, { moduleName, pageName }) => { onSuccess: async (_, { moduleName, pageName }) => {
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: localCourseKeys.pageNames(courseName, moduleName), queryKey: localCourseKeys.allPages(courseName, moduleName),
}); });
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: localCourseKeys.page(courseName, moduleName, pageName), queryKey: localCourseKeys.page(courseName, moduleName, pageName),

View File

@@ -10,13 +10,13 @@ import { localCourseKeys } from "./localCourseKeys";
import { useCourseContext } from "@/app/course/[courseName]/context/courseContext"; import { useCourseContext } from "@/app/course/[courseName]/context/courseContext";
import { axiosClient } from "@/services/axiosUtils"; import { axiosClient } from "@/services/axiosUtils";
export function getQuizNamesQueryConfig( export function getAllQuizzesQueryConfig(
courseName: string, courseName: string,
moduleName: string moduleName: string
) { ) {
return { return {
queryKey: localCourseKeys.quizNames(courseName, moduleName), queryKey: localCourseKeys.allQuizzes(courseName, moduleName),
queryFn: async (): Promise<string[]> => { queryFn: async (): Promise<LocalQuiz[]> => {
const url = const url =
"/api/courses/" + "/api/courses/" +
encodeURIComponent(courseName) + encodeURIComponent(courseName) +
@@ -28,22 +28,24 @@ export function getQuizNamesQueryConfig(
}, },
}; };
} }
export const useQuizNamesQuery = (moduleName: string) => {
const { courseName } = useCourseContext();
return useSuspenseQuery(getQuizNamesQueryConfig(courseName, moduleName));
};
export const useQuizQuery = (moduleName: string, quizName: string) => { export const useQuizQuery = (moduleName: string, quizName: string) => {
const { courseName } = useCourseContext(); const { courseName } = useCourseContext();
return useSuspenseQuery(getQuizQueryConfig(courseName, moduleName, quizName)); return useSuspenseQuery(getQuizQueryConfig(courseName, moduleName, quizName));
}; };
export const useQuizzesQueries = (moduleName: string, quizNames: string[]) => { const useAllQuizzesQuery = (moduleName: string) => {
const { courseName } = useCourseContext(); const { courseName } = useCourseContext();
return useSuspenseQuery(getAllQuizzesQueryConfig(courseName, moduleName));
};
export const useQuizzesQueries = (moduleName: string) => {
const { courseName } = useCourseContext();
const { data: allQuizzes } = useAllQuizzesQuery(moduleName);
return useSuspenseQueries({ return useSuspenseQueries({
queries: quizNames.map((name) => queries: allQuizzes.map((quiz) => ({
getQuizQueryConfig(courseName, moduleName, name) ...getQuizQueryConfig(courseName, moduleName, quiz.name),
), queryFn: () => quiz,
})),
combine: (results) => ({ combine: (results) => ({
data: results.map((r) => r.data), data: results.map((r) => r.data),
pending: results.some((r) => r.isPending), pending: results.some((r) => r.isPending),
@@ -102,7 +104,7 @@ export const useUpdateQuizMutation = () => {
), ),
}); });
queryClient.removeQueries({ queryClient.removeQueries({
queryKey: localCourseKeys.quizNames(courseName, previousModuleName), queryKey: localCourseKeys.allQuizzes(courseName, previousModuleName),
}); });
} }
queryClient.setQueryData( queryClient.setQueryData(
@@ -128,7 +130,7 @@ export const useUpdateQuizMutation = () => {
}, },
onSuccess: async (_, { moduleName, quizName }) => { onSuccess: async (_, { moduleName, quizName }) => {
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: localCourseKeys.quizNames(courseName, moduleName), queryKey: localCourseKeys.allQuizzes(courseName, moduleName),
}); });
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: localCourseKeys.quiz(courseName, moduleName, quizName), queryKey: localCourseKeys.quiz(courseName, moduleName, quizName),
@@ -165,7 +167,7 @@ export const useCreateQuizMutation = () => {
}, },
onSuccess: async (_, { moduleName, quizName }) => { onSuccess: async (_, { moduleName, quizName }) => {
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: localCourseKeys.quizNames(courseName, moduleName), queryKey: localCourseKeys.allQuizzes(courseName, moduleName),
}); });
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: localCourseKeys.quiz(courseName, moduleName, quizName), queryKey: localCourseKeys.quiz(courseName, moduleName, quizName),
@@ -194,12 +196,12 @@ export const useDeleteQuizMutation = () => {
encodeURIComponent(quizName); encodeURIComponent(quizName);
await axiosClient.delete(url); await axiosClient.delete(url);
queryClient.removeQueries({ queryClient.removeQueries({
queryKey: localCourseKeys.quizNames(courseName, moduleName), queryKey: localCourseKeys.allQuizzes(courseName, moduleName),
}); });
}, },
onSuccess: async (_, { moduleName, quizName }) => { onSuccess: async (_, { moduleName, quizName }) => {
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: localCourseKeys.quizNames(courseName, moduleName), queryKey: localCourseKeys.allQuizzes(courseName, moduleName),
}); });
await queryClient.invalidateQueries({ await queryClient.invalidateQueries({
queryKey: localCourseKeys.quiz(courseName, moduleName, quizName), queryKey: localCourseKeys.quiz(courseName, moduleName, quizName),

View File

@@ -13,6 +13,8 @@ import {
LocalCoursePage, LocalCoursePage,
localPageMarkdownUtils, localPageMarkdownUtils,
} from "@/models/local/page/localCoursePage"; } from "@/models/local/page/localCoursePage";
import { assignmentMarkdownSerializer } from "@/models/local/assignment/utils/assignmentMarkdownSerializer";
import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils";
const typeToFolder = { const typeToFolder = {
Assignment: "assignments", Assignment: "assignments",
@@ -99,4 +101,41 @@ export const courseItemFileStorageService = {
).filter((a) => a !== null); ).filter((a) => a !== null);
return items; return items;
}, },
async updateOrCreateAssignment({
courseName,
moduleName,
name,
item,
type,
}: {
courseName: string;
moduleName: string;
name: string;
item: LocalAssignment | LocalQuiz | LocalCoursePage;
type: CourseItemType;
}) {
const typeFolder = typeToFolder[type];
const folder = path.join(basePath, courseName, moduleName, typeFolder);
await fs.mkdir(folder, { recursive: true });
const filePath = path.join(
basePath,
courseName,
moduleName,
typeFolder,
name + ".md"
);
const markdownDictionary: {
[key in CourseItemType]: () => string;
} = {
Assignment: () => assignmentMarkdownSerializer.toMarkdown(item as LocalAssignment),
Quiz: () => quizMarkdownUtils.toMarkdown(item as LocalQuiz),
Page: () => localPageMarkdownUtils.toMarkdown(item as LocalCoursePage),
};
const itemMarkdown = markdownDictionary[type]();
console.log(`Saving ${type} ${filePath}`);
await fs.writeFile(filePath, itemMarkdown);
},
}; };

View File

@@ -14,7 +14,6 @@ export const fileStorageService = {
quizzes: quizFileStorageService, quizzes: quizFileStorageService,
pages: pageFileStorageService, pages: pageFileStorageService,
async getEmptyDirectories(): Promise<string[]> { async getEmptyDirectories(): Promise<string[]> {
if (!(await directoryOrFileExists(basePath))) { if (!(await directoryOrFileExists(basePath))) {
throw new Error( throw new Error(
@@ -48,7 +47,7 @@ export const fileStorageService = {
await fs.mkdir(courseDirectory, { recursive: true }); await fs.mkdir(courseDirectory, { recursive: true });
}, },
async createModuleFolderForTesting(courseName: string, moduleName: string) { async createModuleFolderForTesting(courseName: string, moduleName: string) {
const courseDirectory = path.join(basePath, courseName); const courseDirectory = path.join(basePath, courseName, moduleName);
await fs.mkdir(courseDirectory, { recursive: true }); await fs.mkdir(courseDirectory, { recursive: true });
}, },