diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4d39db6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "editor.quickSuggestions": { + "strings": "on" + }, + "tailwindCSS.includeLanguages": { + "astro": "html" + } +} diff --git a/cypress/e2e/index.cy.ts b/cypress/e2e/index.cy.ts index ece08a2..8453dd7 100644 --- a/cypress/e2e/index.cy.ts +++ b/cypress/e2e/index.cy.ts @@ -2,4 +2,4 @@ it('titles are correct', () => { const page = cy.visit('http://localhost:3000'); page.get('h1').should('have.text', 'Welcome to Astro'); -}); +}) diff --git a/package-lock.json b/package-lock.json index 8e9c85b..cda2089 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,25 +8,26 @@ "name": "@fi3d/slicer-as-a-service", "version": "0.0.1", "dependencies": { - "@astrojs/node": "^5.2.0", - "@astrojs/tailwind": "^3.1.3", - "@dzeio/logger": "^3.0.0", - "@dzeio/object-util": "^1.5.0", - "@dzeio/url-manager": "^1.0.10", - "astro": "^2.6.4", - "bcryptjs": "^2.4.3", - "jsonwebtoken": "^9.0.0", - "mathjs": "^11.8.1", - "mongoose": "^7.3.0", - "tailwindcss": "^3.3.2" + "@astrojs/node": "^5", + "@astrojs/tailwind": "^3", + "@dzeio/logger": "^3", + "@dzeio/object-util": "^1", + "@dzeio/url-manager": "^1", + "astro": "^2", + "bcryptjs": "^2", + "jsonwebtoken": "^9", + "lucide-astro": "^0.256.1", + "mathjs": "^11", + "mongoose": "^7", + "tailwindcss": "^3" }, "devDependencies": { "@tailwindcss/typography": "^0.5.9", - "@types/bcryptjs": "^2.4.2", - "@types/jsonwebtoken": "^9.0.2", - "@types/node": "^20.3.1", + "@types/bcryptjs": "^2", + "@types/jsonwebtoken": "^9", + "@types/node": "^20", "@vitest/coverage-v8": "^0.32.2", - "cypress": "^12.15.0", + "cypress": "^12", "vitest": "^0.32.2" } }, @@ -54,14 +55,14 @@ } }, "node_modules/@astrojs/compiler": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-1.5.1.tgz", - "integrity": "sha512-iIGKu/uzB8sJ5VveQf0eHrVPPFEcrvSlp4qShYMOuY2aMmK2RVXQlX9dUjtmBQ+NAokfIOb7fwCutvH+p13l+g==" + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-1.5.2.tgz", + "integrity": "sha512-EZ3d5UTqN71N2zE3VdzVJeM+dM+pu0wV/jOi6g2VDU21LQTWozafsFMpbcLE/ksmTmbQM90/Tnn19/IR9fWGUw==" }, "node_modules/@astrojs/internal-helpers": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.1.0.tgz", - "integrity": "sha512-OSwvoFkTqVowiyP+codQeQZWoq/HOwY32x17NxDglWoCx2sdyXzplDZoVV4/3odmSEY6/A+48WMl5qkjmP1CXw==" + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.1.1.tgz", + "integrity": "sha512-+LySbvFbjv2nO2m/e78suleQOGEru4Cnx73VsZbrQgB2u7A4ddsQg3P2T0zC0e10jgcT+c6nNlKeLpa6nRhQIg==" }, "node_modules/@astrojs/language-server": { "version": "1.0.8", @@ -115,16 +116,16 @@ "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==" }, "node_modules/@astrojs/node": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@astrojs/node/-/node-5.2.0.tgz", - "integrity": "sha512-WWrQuxvdrD2Jd9np8vpS8/zCNEm0JnGv+oaojXzbfW36R8/09L827t/acYxLuguLufiV3U16QAqEwpS8VFS9TA==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@astrojs/node/-/node-5.3.0.tgz", + "integrity": "sha512-q7gJEPSZzC4FIRNmq3ks6mw0Jby4irXTfRhbOPOS4HRmbu4FDANnRqnZBOGe96cfBQTgDC3/FhQccDQtx+n4pg==", "dependencies": { "@astrojs/webapi": "^2.2.0", "send": "^0.18.0", "server-destroy": "^1.0.1" }, "peerDependencies": { - "astro": "^2.6.0" + "astro": "^2.7.0" } }, "node_modules/@astrojs/prism": { @@ -599,14 +600,14 @@ } }, "node_modules/@dzeio/object-util": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@dzeio/object-util/-/object-util-1.5.0.tgz", - "integrity": "sha512-NlKJulgd95Gvca3Wx9BQi0rABzwtvuCe9JDPBe9lOVmDDs2ufEWiTsLq59rtE1BEuuGzIm9wj/+8Imgk1Svfrw==" + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@dzeio/object-util/-/object-util-1.6.0.tgz", + "integrity": "sha512-6alYWBJUj6iK5jnl8t890PK9n9J2BMcOB0aovSgiUyJxpe/RkNgv8Sba8i6GTkOA0pEgxF6OuR5wvGVrD9Szyw==" }, "node_modules/@dzeio/url-manager": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@dzeio/url-manager/-/url-manager-1.0.10.tgz", - "integrity": "sha512-gy8/0yp60crudcqIwsyFsfbHOnG32TAYg14m+at9wzw/bau5URsarlLkO5A3tigk91m05tZQfHLa4xwrXBSY/w==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@dzeio/url-manager/-/url-manager-1.1.0.tgz", + "integrity": "sha512-LkslGBDHKw4l92grgvy4hTn6z93PQ+AKiQ6Brq6hiteVYtghTZWK4+IU+xX13C+8McB1eM+iuJIPHC9hTL4hfQ==", "dependencies": { "@dzeio/object-util": "^1.5.0" } @@ -1019,11 +1020,6 @@ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, - "node_modules/@ljharb/has-package-exports-patterns": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@ljharb/has-package-exports-patterns/-/has-package-exports-patterns-0.0.2.tgz", - "integrity": "sha512-4/RWEeXDO6bocPONheFe6gX/oQdP/bEpv0oL4HqjPP5DCenBSt0mHgahppY49N0CpsaqffdwPq+TlX9CYOq2Dw==" - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1099,19 +1095,6 @@ "tailwindcss": ">=3.0.0 || insiders" } }, - "node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", - "dev": true, - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@types/babel__core": { "version": "7.20.1", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", @@ -1228,9 +1211,9 @@ } }, "node_modules/@types/node": { - "version": "20.3.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.1.tgz", - "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==" + "version": "20.3.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.2.tgz", + "integrity": "sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw==" }, "node_modules/@types/parse5": { "version": "6.0.3", @@ -1313,18 +1296,6 @@ "vitest": ">=0.32.0 <1" } }, - "node_modules/@vitest/coverage-v8/node_modules/magic-string": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", - "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@vitest/expect": { "version": "0.32.2", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.32.2.tgz", @@ -1368,18 +1339,6 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/snapshot/node_modules/magic-string": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", - "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@vitest/spy": { "version": "0.32.2", "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.32.2.tgz", @@ -1407,9 +1366,9 @@ } }, "node_modules/@vscode/emmet-helper": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/@vscode/emmet-helper/-/emmet-helper-2.8.9.tgz", - "integrity": "sha512-ygpVStaePHt9aI9zk4NNJWI/NsRaeDSW1vQsZVmtpVRVCOdwYlsc3BfB/eppUu1OucT0x3OHDAzKcxnitjcSXQ==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/@vscode/emmet-helper/-/emmet-helper-2.9.2.tgz", + "integrity": "sha512-MaGuyW+fa13q3aYsluKqclmh62Hgp0BpKIqS66fCxfOaBcVQ1OnMQxRRgQUYnCkxFISAQlkJ0qWWPyXjro1Qrg==", "dependencies": { "emmet": "^2.4.3", "jsonc-parser": "^2.3.0", @@ -1661,39 +1620,39 @@ } }, "node_modules/astro": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/astro/-/astro-2.6.4.tgz", - "integrity": "sha512-YM5H9SLHflxCB/3H8S2Bi+1Lbwn/MA9Vl/eOZmkCT491gvBsyuKCTsoUas6fwggeKn+fIR2XpdYd2F+unQve3g==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/astro/-/astro-2.7.1.tgz", + "integrity": "sha512-W7KbiHPIWM9tmjAUza8iQtalbNnpRcbtKgEZ7zc/+vOpuvcmSHxkYVar+VhLf2ZuwBIDjgaF9M8ScQ2B1oobAA==", "dependencies": { - "@astrojs/compiler": "^1.4.0", - "@astrojs/internal-helpers": "^0.1.0", + "@astrojs/compiler": "^1.5.0", + "@astrojs/internal-helpers": "^0.1.1", "@astrojs/language-server": "^1.0.0", "@astrojs/markdown-remark": "^2.2.1", "@astrojs/telemetry": "^2.1.1", "@astrojs/webapi": "^2.2.0", - "@babel/core": "^7.21.8", - "@babel/generator": "^7.18.2", - "@babel/parser": "^7.18.4", - "@babel/plugin-transform-react-jsx": "^7.17.12", - "@babel/traverse": "^7.18.2", - "@babel/types": "^7.21.5", - "@types/babel__core": "^7.1.19", + "@babel/core": "^7.22.5", + "@babel/generator": "^7.22.5", + "@babel/parser": "^7.22.5", + "@babel/plugin-transform-react-jsx": "^7.22.5", + "@babel/traverse": "^7.22.5", + "@babel/types": "^7.22.5", + "@types/babel__core": "^7.20.1", "@types/yargs-parser": "^21.0.0", - "acorn": "^8.8.2", + "acorn": "^8.9.0", "boxen": "^6.2.1", "chokidar": "^3.5.3", - "ci-info": "^3.3.1", + "ci-info": "^3.8.0", "common-ancestor-path": "^1.0.1", "cookie": "^0.5.0", "debug": "^4.3.4", - "deepmerge-ts": "^4.2.2", + "deepmerge-ts": "^4.3.0", "devalue": "^4.3.2", "diff": "^5.1.0", - "es-module-lexer": "^1.1.0", - "esbuild": "^0.17.18", + "es-module-lexer": "^1.3.0", + "esbuild": "^0.17.19", "estree-walker": "3.0.0", "execa": "^6.1.0", - "fast-glob": "^3.2.11", + "fast-glob": "^3.2.12", "github-slugger": "^2.0.0", "gray-matter": "^4.0.3", "html-escaper": "^3.0.3", @@ -1701,26 +1660,24 @@ "kleur": "^4.1.4", "magic-string": "^0.27.0", "mime": "^3.0.0", - "ora": "^6.1.0", + "ora": "^6.3.1", "p-limit": "^4.0.0", "path-to-regexp": "^6.2.1", "preferred-pm": "^3.0.3", "prompts": "^2.4.2", "rehype": "^12.0.1", - "semver": "^7.3.8", + "semver": "^7.5.3", "server-destroy": "^1.0.1", "shiki": "^0.14.1", - "slash": "^4.0.0", "string-width": "^5.1.2", - "strip-ansi": "^7.0.1", - "supports-esm": "^1.0.0", + "strip-ansi": "^7.1.0", "tsconfig-resolver": "^3.0.1", "typescript": "*", - "unist-util-visit": "^4.1.0", - "vfile": "^5.3.2", - "vite": "^4.3.1", + "unist-util-visit": "^4.1.2", + "vfile": "^5.3.7", + "vite": "^4.3.9", "vitefu": "^0.2.4", - "yargs-parser": "^21.0.1", + "yargs-parser": "^21.1.1", "zod": "^3.20.6" }, "bin": { @@ -1739,6 +1696,17 @@ } } }, + "node_modules/astro/node_modules/magic-string": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", + "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.13" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/async": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", @@ -1880,6 +1848,29 @@ "readable-stream": "^3.4.0" } }, + "node_modules/bl/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/blob-util": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", @@ -2015,9 +2006,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.8.tgz", - "integrity": "sha512-j+7xYe+v+q2Id9qbBeCI8WX5NmZSRe8es1+0xntD/+gaWXznP8tFEkv5IgSaHf5dS1YwVMbX/4W6m937mj+wQw==", + "version": "4.21.9", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", + "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", "funding": [ { "type": "opencollective", @@ -2033,8 +2024,8 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001502", - "electron-to-chromium": "^1.4.428", + "caniuse-lite": "^1.0.30001503", + "electron-to-chromium": "^1.4.431", "node-releases": "^2.0.12", "update-browserslist-db": "^1.0.11" }, @@ -2054,9 +2045,10 @@ } }, "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, "funding": [ { "type": "github", @@ -2073,7 +2065,7 @@ ], "dependencies": { "base64-js": "^1.3.1", - "ieee754": "^1.2.1" + "ieee754": "^1.1.13" } }, "node_modules/buffer-crc32": { @@ -2166,9 +2158,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001502", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001502.tgz", - "integrity": "sha512-AZ+9tFXw1sS0o0jcpJQIXvFTOB/xGiQ4OQ2t98QX3NDn2EZTSRBC801gxrsGgViuq2ak/NLkNgSNEPtCr5lfKg==", + "version": "1.0.30001509", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001509.tgz", + "integrity": "sha512-2uDDk+TRiTX5hMcUYT/7CSyzMZxjfGu0vAUjS2g0LSD8UoXOv0LtpH4LxGMemsiPq6LCVIUjNwVM0erkOkGCDA==", "funding": [ { "type": "opencollective", @@ -2336,17 +2328,15 @@ } }, "node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, "dependencies": { - "restore-cursor": "^4.0.0" + "restore-cursor": "^3.1.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/cli-spinners": { @@ -2522,9 +2512,10 @@ } }, "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, "engines": { "node": ">= 6" } @@ -2623,9 +2614,9 @@ } }, "node_modules/cypress": { - "version": "12.15.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-12.15.0.tgz", - "integrity": "sha512-FqGbxsH+QgjStuTO9onXMIeF44eOrgVwPvlcvuzLIaePQMkl72YgBvpuHlBGRcrw3Q4SvqKfajN8iV5XWShAiQ==", + "version": "12.16.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-12.16.0.tgz", + "integrity": "sha512-mwv1YNe48hm0LVaPgofEhGCtLwNIQEjmj2dJXnAkY1b4n/NE9OtgPph4TyS+tOtYp5CKtRmDvBzWseUXQTjbTg==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -2680,9 +2671,9 @@ } }, "node_modules/cypress/node_modules/@types/node": { - "version": "14.18.51", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.51.tgz", - "integrity": "sha512-P9bsdGFPpVtofEKlhWMVS2qqx1A/rt9QBfihWlklfHHpUpjtYse5AzFz6j4DWrARLYh6gRnw9+5+DJcrq3KvBA==", + "version": "14.18.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.52.tgz", + "integrity": "sha512-DGhiXKOHSFVVm+PJD+9Y0ObxXLeG6qwc0HoOn+ooQKeNNu+T2mEJCM5UBDUREKAggl9MHYjb5E71PAmx6MbzIg==", "dev": true }, "node_modules/cypress/node_modules/ansi-styles": { @@ -2700,30 +2691,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/cypress/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/cypress/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -2752,18 +2719,6 @@ "node": ">=8" } }, - "node_modules/cypress/node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/cypress/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2782,15 +2737,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/cypress/node_modules/commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, "node_modules/cypress/node_modules/execa": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", @@ -2859,34 +2805,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cypress/node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cypress/node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/cypress/node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -2923,19 +2841,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/cypress/node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/cypress/node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -3238,9 +3143,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.429", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.429.tgz", - "integrity": "sha512-COua8RvN548KwPFzKMrTjFbmDsQRgdi0zSAhmo70TwC1tfLOSqq8p09n+GkdF5buvzE/NEYn1dP3itbfhun9gg==" + "version": "1.4.442", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.442.tgz", + "integrity": "sha512-RkrZF//Ya+0aJq2NM3OdisNh5ZodZq1rdXOS96G8DdDgpDKqKE81yTbbQ3F/4CKm1JBPsGu1Lp/akkna2xO06Q==" }, "node_modules/emmet": { "version": "2.4.4", @@ -3434,15 +3339,6 @@ "node": ">=4" } }, - "node_modules/executable/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -3849,17 +3745,6 @@ "node": ">=4" } }, - "node_modules/has-package-exports": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/has-package-exports/-/has-package-exports-1.3.0.tgz", - "integrity": "sha512-e9OeXPQnmPhYoJ63lXC4wWe34TxEGZDZ3OQX9XRqp2VwsfLl3bQBy7VehLnd34g3ef8CmYlBLGqEMKXuz8YazQ==", - "dependencies": { - "@ljharb/has-package-exports-patterns": "^0.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", @@ -4311,11 +4196,12 @@ "dev": true }, "node_modules/is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -4776,6 +4662,14 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/load-yaml-file/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "engines": { + "node": ">=6" + } + }, "node_modules/load-yaml-file/node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -4840,31 +4734,91 @@ "dev": true }, "node_modules/log-symbols": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", - "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, "dependencies": { - "chalk": "^5.0.0", - "is-unicode-supported": "^1.1.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", - "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/log-update": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", @@ -4907,18 +4861,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/log-update/node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/log-update/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -4943,43 +4885,6 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "node_modules/log-update/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/log-update/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/log-update/node_modules/slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", @@ -5063,10 +4968,19 @@ "yallist": "^3.0.2" } }, + "node_modules/lucide-astro": { + "version": "0.256.1", + "resolved": "https://registry.npmjs.org/lucide-astro/-/lucide-astro-0.256.1.tgz", + "integrity": "sha512-BACdrK5pG/OEgcVy8lzpr1NOAdfRtMLLuLDY3qlu+StHh9iZrDtI8x1EQKku2T3cviFvZlhD2nX5olfnFgCtNw==", + "peerDependencies": { + "astro": "^2.7.1" + } + }, "node_modules/magic-string": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", - "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", + "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==", + "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.13" }, @@ -5108,9 +5022,9 @@ } }, "node_modules/mathjs": { - "version": "11.8.1", - "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-11.8.1.tgz", - "integrity": "sha512-SHW5fqQXTHd4VqkKEtjQV16d/3fLUfna0VeW8Zd//dNWWLxHarEvXIqSs3vWCSPYc86l1r6yPcKvez8ZVLsoTg==", + "version": "11.8.2", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-11.8.2.tgz", + "integrity": "sha512-ZePu0oDbM0vuFExikIMY/9syjo/jbgNbX6ti+iMdaALDuxciMCsXIslGDBEn7QCpCWYBiVCYmc0lsmk5bwHBdQ==", "dependencies": { "@babel/runtime": "^7.22.5", "complex.js": "^2.1.1", @@ -6038,9 +5952,9 @@ } }, "node_modules/mongoose": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.3.0.tgz", - "integrity": "sha512-gvkV5qxmBkGohlk7VTeePMPM2OkQPeqVYZHvjoM4goOIK6G1eSfJMZwXV21asivXxlaz6OuP29TfGAKrKooDAg==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.3.1.tgz", + "integrity": "sha512-6289bmSIhvR8xMHsYe2/CuzN7wHK+2RHcK7idDdzniCPC5zix5JH0Hc4k3CmXlr/9zQ2250gUQiUWtvDB0vF1Q==", "dependencies": { "bson": "^5.3.0", "kareem": "2.5.1", @@ -6288,6 +6202,83 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/ora/node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/log-symbols": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", + "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", + "dependencies": { + "chalk": "^5.0.0", + "is-unicode-supported": "^1.1.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ospath": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", @@ -6467,17 +6458,17 @@ } }, "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "engines": { "node": ">= 6" } @@ -6665,7 +6656,7 @@ "postcss": "^8.2.14" } }, - "node_modules/postcss-selector-parser": { + "node_modules/postcss-nested/node_modules/postcss-selector-parser": { "version": "6.0.13", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", @@ -6677,6 +6668,19 @@ "node": ">=4" } }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-value-parser": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", @@ -6895,14 +6899,6 @@ "pify": "^2.3.0" } }, - "node_modules/read-cache/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -7073,24 +7069,23 @@ } }, "node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/restore-cursor/node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, "engines": { "node": ">=6" } @@ -7099,6 +7094,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, "dependencies": { "mimic-fn": "^2.1.0" }, @@ -7199,9 +7195,9 @@ } }, "node_modules/rollup": { - "version": "3.25.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.25.1.tgz", - "integrity": "sha512-tywOR+rwIt5m2ZAWSe5AIJcTat8vGlnPFAv15ycCrw33t6iFsXZ6mzHVFh2psSjxQPmI+xgzMZZizUAukBI4aQ==", + "version": "3.25.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.25.3.tgz", + "integrity": "sha512-ZT279hx8gszBj9uy5FfhoG4bZx8c+0A1sbqtr7Q3KNWIizpTdDEPZbV2xcbvHsnFp4MavCQYZyzApJ+virB8Yw==", "bin": { "rollup": "dist/bin/rollup" }, @@ -7419,9 +7415,9 @@ "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" }, "node_modules/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -7530,9 +7526,9 @@ } }, "node_modules/shiki": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.2.tgz", - "integrity": "sha512-ltSZlSLOuSY0M0Y75KA+ieRaZ0Trf5Wl3gutE7jzLuIcWxLp5i/uEnLoQWNvgKXQ5OMpGkJnVMRLAuzjc0LJ2A==", + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.3.tgz", + "integrity": "sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g==", "dependencies": { "ansi-sequence-parser": "^1.1.0", "jsonc-parser": "^3.2.0", @@ -7580,17 +7576,6 @@ "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" }, - "node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/slice-ansi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", @@ -7878,6 +7863,14 @@ "node": ">=8" } }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, "node_modules/suf-log": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/suf-log/-/suf-log-2.5.3.tgz", @@ -7897,14 +7890,6 @@ "node": ">=4" } }, - "node_modules/supports-esm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-esm/-/supports-esm-1.0.0.tgz", - "integrity": "sha512-96Am8CDqUaC0I2+C/swJ0yEvM8ZnGn4unoers/LSdE4umhX7mELzqyLzx3HnZAluq5PXIsGMKqa7NkqaeHMPcg==", - "dependencies": { - "has-package-exports": "^1.1.0" - } - }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -7979,6 +7964,18 @@ "node": ">=10.13.0" } }, + "node_modules/tailwindcss/node_modules/postcss-selector-parser": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", + "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -8187,9 +8184,9 @@ } }, "node_modules/tslib": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", + "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" }, "node_modules/tunnel-agent": { "version": "0.6.0", @@ -8238,9 +8235,9 @@ } }, "node_modules/typescript": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", - "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.5.tgz", + "integrity": "sha512-FOH+WN/DQjUvN6WgW+c4Ml3yi0PH+a/8q+kNIfRehv1wLhWONedw85iu+vQ39Wp49IzTJEsZ2lyLXpBF7mkF1g==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -8697,18 +8694,6 @@ } } }, - "node_modules/vitest/node_modules/magic-string": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", - "integrity": "sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/vscode-css-languageservice": { "version": "6.2.6", "resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-6.2.6.tgz", diff --git a/package.json b/package.json index 911ca97..0a17abb 100644 --- a/package.json +++ b/package.json @@ -12,25 +12,26 @@ "test": "vitest --coverage" }, "dependencies": { - "@astrojs/node": "^5.2.0", - "@astrojs/tailwind": "^3.1.3", - "@dzeio/logger": "^3.0.0", - "@dzeio/object-util": "^1.5.0", - "@dzeio/url-manager": "^1.0.10", - "astro": "^2.6.4", - "bcryptjs": "^2.4.3", - "jsonwebtoken": "^9.0.0", - "mathjs": "^11.8.1", - "mongoose": "^7.3.0", - "tailwindcss": "^3.3.2" + "@astrojs/node": "^5", + "@astrojs/tailwind": "^3", + "@dzeio/logger": "^3", + "@dzeio/object-util": "^1", + "@dzeio/url-manager": "^1", + "astro": "^2", + "bcryptjs": "^2", + "jsonwebtoken": "^9", + "lucide-astro": "^0.256.1", + "mathjs": "^11", + "mongoose": "^7", + "tailwindcss": "^3" }, "devDependencies": { "@tailwindcss/typography": "^0.5.9", - "@types/bcryptjs": "^2.4.2", - "@types/jsonwebtoken": "^9.0.2", - "@types/node": "^20.3.1", + "@types/bcryptjs": "^2", + "@types/jsonwebtoken": "^9", + "@types/node": "^20", "@vitest/coverage-v8": "^0.32.2", - "cypress": "^12.15.0", + "cypress": "^12", "vitest": "^0.32.2" } } diff --git a/public/logo.svg b/public/logo.svg new file mode 100644 index 0000000..3977715 --- /dev/null +++ b/public/logo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/sandbox.config.json b/sandbox.config.json deleted file mode 100644 index 1504dd4..0000000 --- a/sandbox.config.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "infiniteLoopProtection": true, - "hardReloadOnChange": false, - "view": "browser", - "template": "node", - "container": { - "port": 3000, - "startScript": "start", - "node": "14" - } -} diff --git a/src/env.d.ts b/src/env.d.ts index f03fc50..d745612 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -22,7 +22,7 @@ declare namespace App { authKey?: string responseBuilder: { body(body: string | Buffer | object | null | undefined): this - headers(headers: HeadersInit ): this + headers(headers: Record): this addHeader(key: string, value: string): this addHeaders(headers: Record): this removeHeader(key: string): this diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index 14fa766..837ba37 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -1,4 +1,5 @@ --- +import { WifiOff } from 'lucide-astro' export interface Props { title: string; } @@ -16,21 +17,21 @@ const { title } = Astro.props; {title} - - + + + + +
+ + +
- diff --git a/src/libs/StatusCode.ts b/src/libs/HTTP/StatusCode.ts similarity index 100% rename from src/libs/StatusCode.ts rename to src/libs/HTTP/StatusCode.ts diff --git a/src/libs/README.md b/src/libs/README.md new file mode 100644 index 0000000..2834616 --- /dev/null +++ b/src/libs/README.md @@ -0,0 +1,3 @@ +# Libs + +Globally independent objects/classes/functions that MUST be unit testable by themselve diff --git a/src/libs/RateLimiter.ts b/src/libs/RateLimiter.ts index 3522e11..88350df 100644 --- a/src/libs/RateLimiter.ts +++ b/src/libs/RateLimiter.ts @@ -1,6 +1,6 @@ -import { objectLoop } from '@dzeio/object-util' +import StatusCode from './HTTP/StatusCode' import { buildRFC7807 } from './RFCs/RFC7807' -import StatusCode from './StatusCode' +import ResponseBuilder from './ResponseBuilder' interface StorageItem { pointsRemaining: number @@ -33,36 +33,40 @@ export default class RateLimiter { private storage: Record = {} + public constructor( + private points = RateLimiter.points, + private timeSpan = RateLimiter.timeSpan + ) {} + public consume(key: string, value: number = 1): Response | RateLimitHeaders { let item = this.storage[key] const now = (new Date().getTime() / 1000) if (!item) { item = { - pointsRemaining: RateLimiter.points, - timeReset: now + RateLimiter.timeSpan + pointsRemaining: this.points, + timeReset: now + this.timeSpan } } if (item.timeReset <= now) { - item.timeReset = now + RateLimiter.timeSpan - item.pointsRemaining = RateLimiter.points + item.timeReset = now + this.timeSpan + item.pointsRemaining = this.points } item.pointsRemaining -= value this.storage[key] = item const headers: RateLimitHeaders = { - "X-RateLimit-Limit": RateLimiter.points.toFixed(0), + "X-RateLimit-Limit": this.points.toFixed(0), "X-RateLimit-Remaining": Math.max(item.pointsRemaining, 0).toFixed(0), "X-RateLimit-Reset": item.timeReset.toFixed(0) } if (item.pointsRemaining < 0) { + const res = new ResponseBuilder() const resp = buildRFC7807({ type: '/docs/error/rate-limited', status: StatusCode.TOO_MANY_REQUESTS, title: 'You are being rate limited as you have done too many requests to the server' - }) - resp.headers.append('Retry-After', (item.timeReset - now).toFixed(0)) - objectLoop(headers, (value, key) => { - resp.headers.append(key, value) - }) + }, res) + res.addHeader('Retry-After', (item.timeReset - now).toFixed(0)) + res.addHeaders(headers as any) return resp } return headers diff --git a/src/libs/ResponseBuilder.ts b/src/libs/ResponseBuilder.ts index af4a701..dd14a33 100644 --- a/src/libs/ResponseBuilder.ts +++ b/src/libs/ResponseBuilder.ts @@ -18,18 +18,14 @@ export default class ResponseBuilder { return this } - private _headers: Headers = new Headers() - public headers(headers: HeadersInit ) { - if (headers instanceof Headers) { - this._headers = headers - } else { - this._headers = new Headers(headers) - } + private _headers: Record = {} + public headers(headers: Record) { + this._headers = headers return this } public addHeader(key: string, value: string) { - this._headers.append(key, value) + this._headers[key] = value return this } @@ -41,7 +37,7 @@ export default class ResponseBuilder { } public removeHeader(key: string) { - this._headers.delete(key) + delete this._headers[key] return this } diff --git a/src/libs/gcodeUtils.ts b/src/libs/gcodeUtils.ts index 2e476dc..de3b1a3 100644 --- a/src/libs/gcodeUtils.ts +++ b/src/libs/gcodeUtils.ts @@ -4,7 +4,7 @@ * @returns a number if parsing happened correctly or undefined */ function parseNumber(str: string): number | undefined { - if (!/^(\d|\.)+$/g.test(str)) { + if (!/^-?(\d|\.)+$/g.test(str)) { return undefined } const float = parseFloat(str) @@ -53,10 +53,10 @@ export function getParams(data: string) { const lines = data.split('\n').filter((it) => it.startsWith(';') && it.includes('=')) // create the config object const obj: Record = {} - // loop through eacj config + // loop through each config for (const line of lines) { // get its key and value - const [key, value] = line.split('=', 2).map((it) => it.slice(1).trim()) + const [key, value] = line.slice(1).split(/ *= */, 2).map((it) => it.trim()) // sip if it has no key or value if (!key || !value) { continue @@ -78,10 +78,10 @@ export function getParams(data: string) { if (offset > 0) { realKey = `${realKey}_${offset}` } - // detect key collisions - if (obj[realKey] && obj[realKey] !== realValue) { - throw new Error(`Key collision ${key}=${realValue} ${realKey}=${obj[realKey]}`) - } + // detect key collisions (it will never happens with the while above) + // if (obj[realKey] && obj[realKey] !== realValue) { + // throw new Error(`Key collision ${key}=${realValue} ${realKey}=${obj[realKey]}`) + // } // set the value to the key obj[realKey] = realValue // transform the time to a number of seconds diff --git a/src/models/Dao.ts b/src/models/Dao.ts index 1278091..3384ef5 100644 --- a/src/models/Dao.ts +++ b/src/models/Dao.ts @@ -1,5 +1,3 @@ -import Client from './Client' - /** * the Dao is the object that connect the Database or source to the application layer * diff --git a/src/pages/admin.astro b/src/pages/admin.astro index a9a1864..0d85eb3 100644 --- a/src/pages/admin.astro +++ b/src/pages/admin.astro @@ -3,7 +3,13 @@ import Passthrough from '../components/Passthrough.astro' import Layout from '../layouts/Layout.astro' import DaoFactory from '../models/DaoFactory' -const user = await DaoFactory.get('user').get('648f81f857503c7d29465318') +const session = DaoFactory.get('session').getSession(Astro.request) + +if (!session) { + return Astro.redirect('/') +} + +const user = await DaoFactory.get('user').get(session.userId) const list = await DaoFactory.get('apiKey').findAll({ user: user!.id }) diff --git a/src/pages/api/v1/process/[configId].ts b/src/pages/api/v1/process/[configId].ts index 30c2df3..436770e 100644 --- a/src/pages/api/v1/process/[configId].ts +++ b/src/pages/api/v1/process/[configId].ts @@ -7,12 +7,9 @@ import { spawn } from 'node:child_process' import fs from 'node:fs/promises' import os from 'node:os' import path from 'node:path' +import StatusCode from '../../../../libs/HTTP/StatusCode' import { buildRFC7807 } from '../../../../libs/RFCs/RFC7807' -import RateLimiter from '../../../../libs/RateLimiter' -import ResponseBuilder from '../../../../libs/ResponseBuilder' -import StatusCode from '../../../../libs/StatusCode' import { getParams } from '../../../../libs/gcodeUtils' -import { validateAuth } from '../../../../libs/validateAuth' import DaoFactory from '../../../../models/DaoFactory' interface SliceError { @@ -20,7 +17,6 @@ interface SliceError { output: Array } - let tmpDir: string /** diff --git a/src/pages/api/v1/users/[userId]/configs/index.ts b/src/pages/api/v1/users/[userId]/configs/index.ts index 76a0f40..6640c3f 100644 --- a/src/pages/api/v1/users/[userId]/configs/index.ts +++ b/src/pages/api/v1/users/[userId]/configs/index.ts @@ -1,7 +1,7 @@ import { objectOmit } from '@dzeio/object-util' import type { APIRoute } from 'astro' +import StatusCode from '../../../../../../libs/HTTP/StatusCode' import { buildRFC7807 } from '../../../../../../libs/RFCs/RFC7807' -import StatusCode from '../../../../../../libs/StatusCode' import DaoFactory from '../../../../../../models/DaoFactory' export const post: APIRoute = async ({ params, request, locals }) => { diff --git a/src/pages/api/v1/users/[userId]/keys/index.ts b/src/pages/api/v1/users/[userId]/keys/index.ts index acabab2..ac5df30 100644 --- a/src/pages/api/v1/users/[userId]/keys/index.ts +++ b/src/pages/api/v1/users/[userId]/keys/index.ts @@ -1,6 +1,6 @@ import type { APIRoute } from 'astro' import crypto from 'node:crypto' -import StatusCode from '../../../../../../libs/StatusCode' +import StatusCode from '../../../../../../libs/HTTP/StatusCode' import DaoFactory from '../../../../../../models/DaoFactory' export const post: APIRoute = async ({ params, locals }) => { diff --git a/src/pages/api/v1/users/index.ts b/src/pages/api/v1/users/index.ts index 543fd6f..fb605ec 100644 --- a/src/pages/api/v1/users/index.ts +++ b/src/pages/api/v1/users/index.ts @@ -1,6 +1,6 @@ import type { APIRoute } from 'astro' +import StatusCode from '../../../../libs/HTTP/StatusCode' import { buildRFC7807 } from '../../../../libs/RFCs/RFC7807' -import StatusCode from '../../../../libs/StatusCode' export const get: APIRoute = async ({ locals }) => { return locals.responseBuilder diff --git a/src/pages/docs/[...page].astro b/src/pages/docs/[...page].astro index aed8784..ee918fb 100644 --- a/src/pages/docs/[...page].astro +++ b/src/pages/docs/[...page].astro @@ -1,7 +1,7 @@ --- import Layout from '../../layouts/Layout.astro' import { getEntry } from 'astro:content' -import StatusCode from '../../libs/StatusCode' +import StatusCode from '../../libs/HTTP/StatusCode' const page = Astro.params.page diff --git a/test.ts b/test.ts deleted file mode 100644 index 8e8cb46..0000000 --- a/test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import DaoFactory from './src/models/DaoFactory' - -(async () => { - // await DaoFactory.get('config').create({user: {id: 'pouet'}}) - // await DaoFactory.get('user').create({user: {id: 'pouet'}}) - // await DaoFactory.get('config').create({user: {id: 'pouet'}}) - // await DaoFactory.get('user').create({user: {id: 'pouet'}}) - // await DaoFactory.get('config').create({user: {id: 'pouet'}}) - // await DaoFactory.get('config').create({user: {id: 'pouet'}}) - // await DaoFactory.get('config').create({user: {id: 'pouet'}}) - // await DaoFactory.get('user').create({user: {id: 'pouet'}}) - // await DaoFactory.get('config').create({user: {id: 'pouet'}}) - // await DaoFactory.get('config').create({user: {id: 'pouet'}}) - // await DaoFactory.get('user').create({user: {id: 'pouet'}}) - // await DaoFactory.get('user').create({user: {id: 'pouet'}}) - - const dao = DaoFactory.get('user') - console.log(await dao.create({email: 'pokemon@go.com'})) - const obj = await dao.get('648f82be60a03b7398d36925') - console.log(obj) - if (!obj) { - console.log('no obj :(') - } else { - console.log('object :)', obj) - obj.email += 'jesuisundieu@pokemon.com' - console.log(await dao.update(obj)) - } - - const toDelete = await dao.findOne({email: 'pokemon@go.com'}) - if (toDelete) { - console.log('todelete :)', toDelete) - await dao.delete(toDelete) - } - - console.log() - console.log('done') - process.exit(0) -})() - -// await mongoose.get('id') -// await fetch(`/api/users/${'id'}`).then((it) => it.json()) diff --git a/tests/libs/authUtils.test.ts b/tests/libs/authUtils.test.ts new file mode 100644 index 0000000..c3dbb74 --- /dev/null +++ b/tests/libs/authUtils.test.ts @@ -0,0 +1,22 @@ +import { describe, expect, it } from 'vitest' +import { comparePassword, hashPassword } from '../../src/libs/AuthUtils' + + +describe('AuthUtils', () => { + it('should hash the password', async () => { + expect(await hashPassword('test')).toBeDefined() + }) + + it('should compared succeffully password', async () => { + const pass = 'test' + const hash = await hashPassword(pass) + expect(await comparePassword(pass, hash)).toBe(true) + }) + + it('should not generate twice the same hash', async () => { + const pass = 'test' + const hash1 = await hashPassword(pass) + const hash2 = await hashPassword(pass) + expect(hash1).not.toBe(hash2) + }) +}) diff --git a/tests/libs/gcodeUtilts.test.ts b/tests/libs/gcodeUtilts.test.ts new file mode 100644 index 0000000..3f90bf6 --- /dev/null +++ b/tests/libs/gcodeUtilts.test.ts @@ -0,0 +1,50 @@ +import { afterEach, assert, beforeEach, describe, expect, it, test, vi } from 'vitest' +import { getParams } from '../../src/libs/gcodeUtils' + + +describe('gcodeUtils', () => { + it('should get parameters', () => { + const gcode = ` +balfs +dgfdf +sd +httphq +estimated_printing_time_normal_modewef + +; test=a +fgd +;test =b +;test= c +;test = d +;number=1.12 +;number2=-1 +;invalid= +;invalid +;estimated_printing_time_normal_mode=1d 1h 1m 1s + +sdffgaf +fgsdf +g +sfd +hh +ehf +` + expect(getParams(gcode)).toEqual({ + test: 'a', + test_1: 'b', + test_2: 'c', + test_3: 'd', + number: 1.12, + number2: -1, + estimated_printing_time_normal_mode: '1d 1h 1m 1s', + estimated_printing_time_seconds: 90061 + }) + }) + + it('should get parameters', () => { + const gcode = ` +;estimated_printing_time_normal_mode=1w 1d 1h 1m 1s +` + expect(() => getParams(gcode)).toThrow(/1w/g) + }) +}) diff --git a/tests/libs/rateLimit.test.ts b/tests/libs/rateLimit.test.ts new file mode 100644 index 0000000..eb6456e --- /dev/null +++ b/tests/libs/rateLimit.test.ts @@ -0,0 +1,122 @@ +import { afterEach, assert, beforeEach, describe, expect, it, test, vi } from 'vitest' +import RateLimiter from '../../src/libs/RateLimiter' + + +// Mock Response +vi.stubGlobal('Response', class { + public constructor( + public body?: any, + public init?: any + ) {} +}) + +describe('Rate Limit', () => { + beforeEach(() => { + vi.useFakeTimers() + }) + + + it('should work with global variant', () => { + const now1 = new Date(1000) + vi.setSystemTime(now1) + const limit = RateLimiter.getInstance() + + const result1 = limit.consume('key') + expect(result1).toEqual({ + "X-RateLimit-Limit": '10', + "X-RateLimit-Remaining": '9', + "X-RateLimit-Reset": '61' + }) + const limit2 = RateLimiter.getInstance() + const result2 = limit2.consume('key') + expect(result2).toEqual({ + "X-RateLimit-Limit": '10', + "X-RateLimit-Remaining": '8', + "X-RateLimit-Reset": '61' + }) + }) + + it('should consume points', () => { + const now1 = new Date(1000) + vi.setSystemTime(now1) + const limit = new RateLimiter(2, 10) + + const result1 = limit.consume('key') + expect(result1).toEqual({ + "X-RateLimit-Limit": '2', + "X-RateLimit-Remaining": '1', + "X-RateLimit-Reset": '11' + }) + const result2 = limit.consume('key') + expect(result2).toEqual({ + "X-RateLimit-Limit": '2', + "X-RateLimit-Remaining": '0', + "X-RateLimit-Reset": '11' + }) + }) + + it('should rate limit', () => { + const now1 = new Date(1000) + vi.setSystemTime(now1) + const limit = new RateLimiter(1, 10) + + const result1 = limit.consume('key') + expect(result1).toEqual({ + "X-RateLimit-Limit": '1', + "X-RateLimit-Remaining": '0', + "X-RateLimit-Reset": '11' + }) + const result2 = limit.consume('key') + expect(result2).instanceOf(Response) + const result3 = limit.consume('key') + expect(result3).instanceOf(Response) + }) + + it('should reset after some time', () => { + const now1 = new Date(1000) + vi.setSystemTime(now1) + const limit = new RateLimiter(2, 10) + + const result1 = limit.consume('key') + expect(result1).toEqual({ + "X-RateLimit-Limit": '2', + "X-RateLimit-Remaining": '1', + "X-RateLimit-Reset": '11' + }) + const result2 = limit.consume('key') + expect(result2).toEqual({ + "X-RateLimit-Limit": '2', + "X-RateLimit-Remaining": '0', + "X-RateLimit-Reset": '11' + }) + + + const result3 = limit.consume('key') + expect(result3).instanceOf(Response) + + const now2 = new Date(11000) + vi.setSystemTime(now2) + const result4 = limit.consume('key') + expect(result4).toEqual({ + "X-RateLimit-Limit": '2', + "X-RateLimit-Remaining": '1', + "X-RateLimit-Reset": '21' + }) + + + const result5 = limit.consume('key') + expect(result5).toEqual({ + "X-RateLimit-Limit": '2', + "X-RateLimit-Remaining": '0', + "X-RateLimit-Reset": '21' + }) + + + const result6 = limit.consume('key') + expect(result6).instanceOf(Response) + }) + + afterEach(() => { + vi.useRealTimers() + }) +})