diff --git a/package-lock.json b/package-lock.json index 7e32f25..42a9627 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,8 +13,8 @@ "@iconify-icons/codicon": "^1.2.15", "@iconify/svelte": "^2.2.1", "@playwright/test": "^1.22.2", - "@sveltejs/adapter-node": "^1.0.0-next.86", - "@sveltejs/kit": "^1.0.0-next.430", + "@sveltejs/adapter-node": "^1.0.0-next.87", + "@sveltejs/kit": "^1.0.0-next.437", "@sveltejs/package": "^1.0.0-next.1", "@tailwindcss/typography": "^0.5.3", "@tricoteuses/explorer-tools": "^0.1.12", @@ -210,13 +210,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.25.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.25.0.tgz", - "integrity": "sha512-j4EZhTTQI3dBeWblE21EV//swwmBtOpIrLdOIJIRv4uqsLdHgBg1z+JtTg+AeC5o2bAXIE26kDNW5A0TimG8Bg==", + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.25.1.tgz", + "integrity": "sha512-IJ4X0yOakXtwkhbnNzKkaIgXe6df7u3H3FnuhI9Jqh+CdO0e/lYQlDLYiyI9cnXK8E7UAppAWP+VqAv6VX7HQg==", "dev": true, "dependencies": { "@types/node": "*", - "playwright-core": "1.25.0" + "playwright-core": "1.25.1" }, "bin": { "playwright": "cli.js" @@ -245,15 +245,15 @@ } }, "node_modules/@sveltejs/adapter-node": { - "version": "1.0.0-next.86", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-node/-/adapter-node-1.0.0-next.86.tgz", - "integrity": "sha512-VfKcFukVEPoAdm8tVGkFLyDDMZe+9HLFW7X/9Ch/UrSCHo3/HyOfYt/slmh+sjGXYjIBAtTjacrIfcMdYh744g==", + "version": "1.0.0-next.87", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-node/-/adapter-node-1.0.0-next.87.tgz", + "integrity": "sha512-ktvZ0+uthYH6SQMO34acbqkReeIcNMD1b7fnWqRIBj5CrgeBarvmbcj+x3/QKpOIG7s11yjwgYhOGLxZX0VMHw==", "dev": true }, "node_modules/@sveltejs/kit": { - "version": "1.0.0-next.430", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.0.0-next.430.tgz", - "integrity": "sha512-0NL6DfFWASDkvjL6iCr3pO/u1oqvoF75lvnO6QTB0rIHMYOL+l9BAkxVETnNxzvgLRFCECi6NSh2C0bdaYaM1g==", + "version": "1.0.0-next.437", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.0.0-next.437.tgz", + "integrity": "sha512-O0jTjJzb9zVqGpdWJxGiQzNe8eNPVxsfOownrqCTfAN5XDPAOvAYkIoax9xo/QYr/XlK0FKpscJXTuvLYYAXqg==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -303,9 +303,9 @@ } }, "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.1.tgz", - "integrity": "sha512-PorCgUounn0VXcpeJu+hOweZODKmGuLHsLomwqSj+p26IwjjGffmYQfVHtiTWq+NqaUuuHWWG7vPge6UFw4Aeg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.2.tgz", + "integrity": "sha512-8tTVbNuraeDchBaArNbwaZLpO0feM7BRSdZU5yeM4Clasx2p1p1CYBoWh+VgxZlxiark49HXummkHqKztbl8lA==", "dev": true, "dependencies": { "@rollup/pluginutils": "^4.2.1", @@ -376,9 +376,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.7.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.8.tgz", - "integrity": "sha512-/YP55EMK2341JkODUb8DM9O0x1SIz2aBvyF33Uf1c76St3VpsMXEIW0nxuKkq/5cxnbz0RD9cfwNZHEAZQD3ag==", + "version": "18.7.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.13.tgz", + "integrity": "sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==", "dev": true }, "node_modules/@types/pug": { @@ -397,14 +397,14 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.33.1.tgz", - "integrity": "sha512-S1iZIxrTvKkU3+m63YUOxYPKaP+yWDQrdhxTglVDVEVBf+aCSw85+BmJnyUaQQsk5TXFG/LpBu9fa+LrAQ91fQ==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.35.1.tgz", + "integrity": "sha512-RBZZXZlI4XCY4Wzgy64vB+0slT9+yAPQRjj/HSaRwUot33xbDjF1oN9BLwOLTewoOI0jothIltZRe9uJCHf8gg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.33.1", - "@typescript-eslint/type-utils": "5.33.1", - "@typescript-eslint/utils": "5.33.1", + "@typescript-eslint/scope-manager": "5.35.1", + "@typescript-eslint/type-utils": "5.35.1", + "@typescript-eslint/utils": "5.35.1", "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", @@ -430,14 +430,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.33.1.tgz", - "integrity": "sha512-IgLLtW7FOzoDlmaMoXdxG8HOCByTBXrB1V2ZQYSEV1ggMmJfAkMWTwUjjzagS6OkfpySyhKFkBw7A9jYmcHpZA==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.35.1.tgz", + "integrity": "sha512-XL2TBTSrh3yWAsMYpKseBYTVpvudNf69rPOWXWVBI08My2JVT5jR66eTt4IgQFHA/giiKJW5dUD4x/ZviCKyGg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.33.1", - "@typescript-eslint/types": "5.33.1", - "@typescript-eslint/typescript-estree": "5.33.1", + "@typescript-eslint/scope-manager": "5.35.1", + "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/typescript-estree": "5.35.1", "debug": "^4.3.4" }, "engines": { @@ -457,13 +457,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.33.1.tgz", - "integrity": "sha512-8ibcZSqy4c5m69QpzJn8XQq9NnqAToC8OdH/W6IXPXv83vRyEDPYLdjAlUx8h/rbusq6MkW4YdQzURGOqsn3CA==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.35.1.tgz", + "integrity": "sha512-kCYRSAzIW9ByEIzmzGHE50NGAvAP3wFTaZevgWva7GpquDyFPFcmvVkFJGWJJktg/hLwmys/FZwqM9EKr2u24Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.33.1", - "@typescript-eslint/visitor-keys": "5.33.1" + "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/visitor-keys": "5.35.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -474,12 +474,12 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.33.1.tgz", - "integrity": "sha512-X3pGsJsD8OiqhNa5fim41YtlnyiWMF/eKsEZGsHID2HcDqeSC5yr/uLOeph8rNF2/utwuI0IQoAK3fpoxcLl2g==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.35.1.tgz", + "integrity": "sha512-8xT8ljvo43Mp7BiTn1vxLXkjpw8wS4oAc00hMSB4L1/jIiYbjjnc3Qp2GAUOG/v8zsNCd1qwcqfCQ0BuishHkw==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "5.33.1", + "@typescript-eslint/utils": "5.35.1", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -500,9 +500,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.33.1.tgz", - "integrity": "sha512-7K6MoQPQh6WVEkMrMW5QOA5FO+BOwzHSNd0j3+BlBwd6vtzfZceJ8xJ7Um2XDi/O3umS8/qDX6jdy2i7CijkwQ==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.35.1.tgz", + "integrity": "sha512-FDaujtsH07VHzG0gQ6NDkVVhi1+rhq0qEvzHdJAQjysN+LHDCKDKCBRlZFFE0ec0jKxiv0hN63SNfExy0KrbQQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -513,13 +513,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.33.1.tgz", - "integrity": "sha512-JOAzJ4pJ+tHzA2pgsWQi4804XisPHOtbvwUyqsuuq8+y5B5GMZs7lI1xDWs6V2d7gE/Ez5bTGojSK12+IIPtXA==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.35.1.tgz", + "integrity": "sha512-JUqE1+VRTGyoXlDWWjm6MdfpBYVq+hixytrv1oyjYIBEOZhBCwtpp5ZSvBt4wIA1MKWlnaC2UXl2XmYGC3BoQA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.33.1", - "@typescript-eslint/visitor-keys": "5.33.1", + "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/visitor-keys": "5.35.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -540,15 +540,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.33.1.tgz", - "integrity": "sha512-uphZjkMaZ4fE8CR4dU7BquOV6u0doeQAr8n6cQenl/poMaIyJtBu8eys5uk6u5HiDH01Mj5lzbJ5SfeDz7oqMQ==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.35.1.tgz", + "integrity": "sha512-v6F8JNXgeBWI4pzZn36hT2HXXzoBBBJuOYvoQiaQaEEjdi5STzux3Yj8v7ODIpx36i/5s8TdzuQ54TPc5AITQQ==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.33.1", - "@typescript-eslint/types": "5.33.1", - "@typescript-eslint/typescript-estree": "5.33.1", + "@typescript-eslint/scope-manager": "5.35.1", + "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/typescript-estree": "5.35.1", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -564,12 +564,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.33.1.tgz", - "integrity": "sha512-nwIxOK8Z2MPWltLKMLOEZwmfBZReqUdbEoHQXeCpa+sRVARe5twpJGHCB4dk9903Yaf0nMAlGbQfaAH92F60eg==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.35.1.tgz", + "integrity": "sha512-cEB1DvBVo1bxbW/S5axbGPE6b7FIMAbo3w+AGq6zNDA7+NYJOIkKj/sInfTv4edxd4PxJSgdN4t6/pbvgA+n5g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.33.1", + "@typescript-eslint/types": "5.35.1", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -855,9 +855,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001379", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001379.tgz", - "integrity": "sha512-zXf+qxuN8OJrK5Bl5HbJg8cc5/Zm01WNW4ooVWUh92YlKqQZW3fwN5lXLB+kI8wkP5vTWkIIN+rutZuJhf4ykw==", + "version": "1.0.30001383", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001383.tgz", + "integrity": "sha512-swMpEoTp5vDoGBZsYZX7L7nXHe6dsHxi9o6/LKf/f0LukVtnrxly5GVb/fWdCDTqi/yw6Km6tiJ0pmBacm0gbg==", "dev": true, "funding": [ { @@ -913,18 +913,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/color": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", @@ -1179,9 +1167,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.225", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.225.tgz", - "integrity": "sha512-ICHvGaCIQR3P88uK8aRtx8gmejbVJyC6bB4LEC3anzBrIzdzC7aiZHY4iFfXhN4st6I7lMO0x4sgBHf/7kBvRw==", + "version": "1.4.230", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.230.tgz", + "integrity": "sha512-3pwjAK0qHSDN9+YAF4fJknsSruP7mpjdWzUSruIJD/JCH77pEh0SorEyb3xVaKkfwk2tzjOt2D8scJ0KAdfXLA==", "dev": true }, "node_modules/es6-promise": { @@ -1716,6 +1704,18 @@ "node": ">=4.0" } }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/espree": { "version": "9.3.3", "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz", @@ -1821,18 +1821,6 @@ "node": ">=8.6.0" } }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -2050,15 +2038,15 @@ } }, "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { - "is-glob": "^4.0.3" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=10.13.0" + "node": ">= 6" } }, "node_modules/globals": { @@ -2794,9 +2782,9 @@ } }, "node_modules/playwright-core": { - "version": "1.25.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.25.0.tgz", - "integrity": "sha512-kZ3Jwaf3wlu0GgU0nB8UMQ+mXFTqBIFz9h1svTlNduNKjnbPXFxw7mJanLVjqxHJRn62uBfmgBj93YHidk2N5Q==", + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.25.1.tgz", + "integrity": "sha512-lSvPCmA2n7LawD2Hw7gSCLScZ+vYRkhU8xH0AapMyzwN+ojoDqhkH/KIEUxwNu2PjPoE/fcE0wLAksdOhJ2O5g==", "dev": true, "bin": { "playwright": "cli.js" @@ -3535,6 +3523,18 @@ "postcss": "^8.0.9" } }, + "node_modules/tailwindcss/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/tailwindcss/node_modules/postcss-load-config": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", @@ -3675,9 +3675,9 @@ } }, "node_modules/undici": { - "version": "5.9.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.9.1.tgz", - "integrity": "sha512-6fB3a+SNnWEm4CJbgo0/CWR8RGcOCQP68SF4X0mxtYTq2VNN8T88NYrWVBAeSX+zb7bny2dx2iYhP3XHi00omg==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.10.0.tgz", + "integrity": "sha512-c8HsD3IbwmjjbLvoZuRI26TZic+TSEe8FPMLLOkN1AfYRhdjnKBU6yL+IwcSCbdZiX4e5t0lfMDLDCqj4Sq70g==", "dev": true, "engines": { "node": ">=12.18" @@ -3980,13 +3980,13 @@ } }, "@playwright/test": { - "version": "1.25.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.25.0.tgz", - "integrity": "sha512-j4EZhTTQI3dBeWblE21EV//swwmBtOpIrLdOIJIRv4uqsLdHgBg1z+JtTg+AeC5o2bAXIE26kDNW5A0TimG8Bg==", + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.25.1.tgz", + "integrity": "sha512-IJ4X0yOakXtwkhbnNzKkaIgXe6df7u3H3FnuhI9Jqh+CdO0e/lYQlDLYiyI9cnXK8E7UAppAWP+VqAv6VX7HQg==", "dev": true, "requires": { "@types/node": "*", - "playwright-core": "1.25.0" + "playwright-core": "1.25.1" } }, "@polka/url": { @@ -4006,15 +4006,15 @@ } }, "@sveltejs/adapter-node": { - "version": "1.0.0-next.86", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-node/-/adapter-node-1.0.0-next.86.tgz", - "integrity": "sha512-VfKcFukVEPoAdm8tVGkFLyDDMZe+9HLFW7X/9Ch/UrSCHo3/HyOfYt/slmh+sjGXYjIBAtTjacrIfcMdYh744g==", + "version": "1.0.0-next.87", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-node/-/adapter-node-1.0.0-next.87.tgz", + "integrity": "sha512-ktvZ0+uthYH6SQMO34acbqkReeIcNMD1b7fnWqRIBj5CrgeBarvmbcj+x3/QKpOIG7s11yjwgYhOGLxZX0VMHw==", "dev": true }, "@sveltejs/kit": { - "version": "1.0.0-next.430", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.0.0-next.430.tgz", - "integrity": "sha512-0NL6DfFWASDkvjL6iCr3pO/u1oqvoF75lvnO6QTB0rIHMYOL+l9BAkxVETnNxzvgLRFCECi6NSh2C0bdaYaM1g==", + "version": "1.0.0-next.437", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.0.0-next.437.tgz", + "integrity": "sha512-O0jTjJzb9zVqGpdWJxGiQzNe8eNPVxsfOownrqCTfAN5XDPAOvAYkIoax9xo/QYr/XlK0FKpscJXTuvLYYAXqg==", "dev": true, "requires": { "@sveltejs/vite-plugin-svelte": "^1.0.1", @@ -4044,9 +4044,9 @@ } }, "@sveltejs/vite-plugin-svelte": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.1.tgz", - "integrity": "sha512-PorCgUounn0VXcpeJu+hOweZODKmGuLHsLomwqSj+p26IwjjGffmYQfVHtiTWq+NqaUuuHWWG7vPge6UFw4Aeg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.2.tgz", + "integrity": "sha512-8tTVbNuraeDchBaArNbwaZLpO0feM7BRSdZU5yeM4Clasx2p1p1CYBoWh+VgxZlxiark49HXummkHqKztbl8lA==", "dev": true, "requires": { "@rollup/pluginutils": "^4.2.1", @@ -4101,9 +4101,9 @@ "dev": true }, "@types/node": { - "version": "18.7.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.8.tgz", - "integrity": "sha512-/YP55EMK2341JkODUb8DM9O0x1SIz2aBvyF33Uf1c76St3VpsMXEIW0nxuKkq/5cxnbz0RD9cfwNZHEAZQD3ag==", + "version": "18.7.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.13.tgz", + "integrity": "sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==", "dev": true }, "@types/pug": { @@ -4122,14 +4122,14 @@ } }, "@typescript-eslint/eslint-plugin": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.33.1.tgz", - "integrity": "sha512-S1iZIxrTvKkU3+m63YUOxYPKaP+yWDQrdhxTglVDVEVBf+aCSw85+BmJnyUaQQsk5TXFG/LpBu9fa+LrAQ91fQ==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.35.1.tgz", + "integrity": "sha512-RBZZXZlI4XCY4Wzgy64vB+0slT9+yAPQRjj/HSaRwUot33xbDjF1oN9BLwOLTewoOI0jothIltZRe9uJCHf8gg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.33.1", - "@typescript-eslint/type-utils": "5.33.1", - "@typescript-eslint/utils": "5.33.1", + "@typescript-eslint/scope-manager": "5.35.1", + "@typescript-eslint/type-utils": "5.35.1", + "@typescript-eslint/utils": "5.35.1", "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", @@ -4139,52 +4139,52 @@ } }, "@typescript-eslint/parser": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.33.1.tgz", - "integrity": "sha512-IgLLtW7FOzoDlmaMoXdxG8HOCByTBXrB1V2ZQYSEV1ggMmJfAkMWTwUjjzagS6OkfpySyhKFkBw7A9jYmcHpZA==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.35.1.tgz", + "integrity": "sha512-XL2TBTSrh3yWAsMYpKseBYTVpvudNf69rPOWXWVBI08My2JVT5jR66eTt4IgQFHA/giiKJW5dUD4x/ZviCKyGg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.33.1", - "@typescript-eslint/types": "5.33.1", - "@typescript-eslint/typescript-estree": "5.33.1", + "@typescript-eslint/scope-manager": "5.35.1", + "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/typescript-estree": "5.35.1", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.33.1.tgz", - "integrity": "sha512-8ibcZSqy4c5m69QpzJn8XQq9NnqAToC8OdH/W6IXPXv83vRyEDPYLdjAlUx8h/rbusq6MkW4YdQzURGOqsn3CA==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.35.1.tgz", + "integrity": "sha512-kCYRSAzIW9ByEIzmzGHE50NGAvAP3wFTaZevgWva7GpquDyFPFcmvVkFJGWJJktg/hLwmys/FZwqM9EKr2u24Q==", "dev": true, "requires": { - "@typescript-eslint/types": "5.33.1", - "@typescript-eslint/visitor-keys": "5.33.1" + "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/visitor-keys": "5.35.1" } }, "@typescript-eslint/type-utils": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.33.1.tgz", - "integrity": "sha512-X3pGsJsD8OiqhNa5fim41YtlnyiWMF/eKsEZGsHID2HcDqeSC5yr/uLOeph8rNF2/utwuI0IQoAK3fpoxcLl2g==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.35.1.tgz", + "integrity": "sha512-8xT8ljvo43Mp7BiTn1vxLXkjpw8wS4oAc00hMSB4L1/jIiYbjjnc3Qp2GAUOG/v8zsNCd1qwcqfCQ0BuishHkw==", "dev": true, "requires": { - "@typescript-eslint/utils": "5.33.1", + "@typescript-eslint/utils": "5.35.1", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.33.1.tgz", - "integrity": "sha512-7K6MoQPQh6WVEkMrMW5QOA5FO+BOwzHSNd0j3+BlBwd6vtzfZceJ8xJ7Um2XDi/O3umS8/qDX6jdy2i7CijkwQ==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.35.1.tgz", + "integrity": "sha512-FDaujtsH07VHzG0gQ6NDkVVhi1+rhq0qEvzHdJAQjysN+LHDCKDKCBRlZFFE0ec0jKxiv0hN63SNfExy0KrbQQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.33.1.tgz", - "integrity": "sha512-JOAzJ4pJ+tHzA2pgsWQi4804XisPHOtbvwUyqsuuq8+y5B5GMZs7lI1xDWs6V2d7gE/Ez5bTGojSK12+IIPtXA==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.35.1.tgz", + "integrity": "sha512-JUqE1+VRTGyoXlDWWjm6MdfpBYVq+hixytrv1oyjYIBEOZhBCwtpp5ZSvBt4wIA1MKWlnaC2UXl2XmYGC3BoQA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.33.1", - "@typescript-eslint/visitor-keys": "5.33.1", + "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/visitor-keys": "5.35.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4193,26 +4193,26 @@ } }, "@typescript-eslint/utils": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.33.1.tgz", - "integrity": "sha512-uphZjkMaZ4fE8CR4dU7BquOV6u0doeQAr8n6cQenl/poMaIyJtBu8eys5uk6u5HiDH01Mj5lzbJ5SfeDz7oqMQ==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.35.1.tgz", + "integrity": "sha512-v6F8JNXgeBWI4pzZn36hT2HXXzoBBBJuOYvoQiaQaEEjdi5STzux3Yj8v7ODIpx36i/5s8TdzuQ54TPc5AITQQ==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.33.1", - "@typescript-eslint/types": "5.33.1", - "@typescript-eslint/typescript-estree": "5.33.1", + "@typescript-eslint/scope-manager": "5.35.1", + "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/typescript-estree": "5.35.1", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" } }, "@typescript-eslint/visitor-keys": { - "version": "5.33.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.33.1.tgz", - "integrity": "sha512-nwIxOK8Z2MPWltLKMLOEZwmfBZReqUdbEoHQXeCpa+sRVARe5twpJGHCB4dk9903Yaf0nMAlGbQfaAH92F60eg==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.35.1.tgz", + "integrity": "sha512-cEB1DvBVo1bxbW/S5axbGPE6b7FIMAbo3w+AGq6zNDA7+NYJOIkKj/sInfTv4edxd4PxJSgdN4t6/pbvgA+n5g==", "dev": true, "requires": { - "@typescript-eslint/types": "5.33.1", + "@typescript-eslint/types": "5.35.1", "eslint-visitor-keys": "^3.3.0" } }, @@ -4404,9 +4404,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001379", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001379.tgz", - "integrity": "sha512-zXf+qxuN8OJrK5Bl5HbJg8cc5/Zm01WNW4ooVWUh92YlKqQZW3fwN5lXLB+kI8wkP5vTWkIIN+rutZuJhf4ykw==", + "version": "1.0.30001383", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001383.tgz", + "integrity": "sha512-swMpEoTp5vDoGBZsYZX7L7nXHe6dsHxi9o6/LKf/f0LukVtnrxly5GVb/fWdCDTqi/yw6Km6tiJ0pmBacm0gbg==", "dev": true }, "chalk": { @@ -4433,17 +4433,6 @@ "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } } }, "color": { @@ -4643,9 +4632,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.4.225", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.225.tgz", - "integrity": "sha512-ICHvGaCIQR3P88uK8aRtx8gmejbVJyC6bB4LEC3anzBrIzdzC7aiZHY4iFfXhN4st6I7lMO0x4sgBHf/7kBvRw==", + "version": "1.4.230", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.230.tgz", + "integrity": "sha512-3pwjAK0qHSDN9+YAF4fJknsSruP7mpjdWzUSruIJD/JCH77pEh0SorEyb3xVaKkfwk2tzjOt2D8scJ0KAdfXLA==", "dev": true }, "es6-promise": { @@ -4897,6 +4886,15 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } } } }, @@ -5027,17 +5025,6 @@ "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } } }, "fast-json-stable-stringify": { @@ -5196,12 +5183,12 @@ } }, "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { - "is-glob": "^4.0.3" + "is-glob": "^4.0.1" } }, "globals": { @@ -5755,9 +5742,9 @@ "dev": true }, "playwright-core": { - "version": "1.25.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.25.0.tgz", - "integrity": "sha512-kZ3Jwaf3wlu0GgU0nB8UMQ+mXFTqBIFz9h1svTlNduNKjnbPXFxw7mJanLVjqxHJRn62uBfmgBj93YHidk2N5Q==", + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.25.1.tgz", + "integrity": "sha512-lSvPCmA2n7LawD2Hw7gSCLScZ+vYRkhU8xH0AapMyzwN+ojoDqhkH/KIEUxwNu2PjPoE/fcE0wLAksdOhJ2O5g==", "dev": true }, "postcss": { @@ -6207,6 +6194,15 @@ "resolve": "^1.22.1" }, "dependencies": { + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, "postcss-load-config": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", @@ -6301,9 +6297,9 @@ "dev": true }, "undici": { - "version": "5.9.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.9.1.tgz", - "integrity": "sha512-6fB3a+SNnWEm4CJbgo0/CWR8RGcOCQP68SF4X0mxtYTq2VNN8T88NYrWVBAeSX+zb7bny2dx2iYhP3XHi00omg==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.10.0.tgz", + "integrity": "sha512-c8HsD3IbwmjjbLvoZuRI26TZic+TSEe8FPMLLOkN1AfYRhdjnKBU6yL+IwcSCbdZiX4e5t0lfMDLDCqj4Sq70g==", "dev": true }, "universalify": { diff --git a/package.json b/package.json index 036b64d..ad6cdf6 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ "@iconify-icons/codicon": "^1.2.15", "@iconify/svelte": "^2.2.1", "@playwright/test": "^1.22.2", - "@sveltejs/adapter-node": "^1.0.0-next.86", - "@sveltejs/kit": "^1.0.0-next.430", + "@sveltejs/adapter-node": "^1.0.0-next.87", + "@sveltejs/kit": "^1.0.0-next.437", "@sveltejs/package": "^1.0.0-next.1", "@tailwindcss/typography": "^0.5.3", "@tricoteuses/explorer-tools": "^0.1.12", diff --git a/src/lib/aggregates.ts b/src/lib/aggregates.ts index e984c29..4cac72a 100644 --- a/src/lib/aggregates.ts +++ b/src/lib/aggregates.ts @@ -11,6 +11,25 @@ export interface Aggregate { export type Follow = typeof allFollows[number] +export interface GetRechercheResult extends Aggregate { + follow: Follow[] + id: string + q?: string +} + +export interface GetTexteResult extends Aggregate { + follow: Follow[] + id: string +} + +export interface ListTextesResult extends Aggregate { + follow: Follow[] + ids: string[] + limit: number + offset: number + q?: string +} + export const allFollows = [ "LIENS.LIEN[@sens=cible,@typelien=CREATION].@id", "STRUCT.LIEN_ART.@id", diff --git a/src/lib/server/doers/recherche.ts b/src/lib/server/doers/recherche.ts deleted file mode 100644 index 48b1342..0000000 --- a/src/lib/server/doers/recherche.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { type Audit, auditSetNullish, cleanAudit } from "@auditors/core" -import { error } from "@sveltejs/kit" - -import type { Aggregate, Follow } from "$lib/aggregates" -import { - auditFollowSearchParams, - auditQSearchParam, -} from "$lib/auditors/search_params" -import type { Article } from "$lib/legal" -import { Aggregator } from "$lib/server/aggregates" -import { db } from "$lib/server/database" - -export function auditSearchParams( - audit: Audit, - query: URLSearchParams, -): [unknown, unknown] { - if (query == null) { - return [query, null] - } - if (!(query instanceof URLSearchParams)) { - return audit.unexpectedType(query, "URLSearchParams") - } - - const data: { [key: string]: unknown } = {} - for (const [key, value] of query.entries()) { - let values = data[key] as string[] | undefined - if (values === undefined) { - values = data[key] = [] - } - values.push(value) - } - const errors: { [key: string]: unknown } = {} - const remainingKeys = new Set(Object.keys(data)) - - auditFollowSearchParams(audit, data, errors, remainingKeys) - auditQSearchParam(audit, data, errors, remainingKeys) - - return audit.reduceRemaining(data, errors, remainingKeys, auditSetNullish({})) -} - -export const doGetRecherche = async ( - url: URL, -): Promise< - Aggregate & { - follow: Follow[] - q?: string - } -> => { - const [query, queryError] = auditSearchParams( - cleanAudit, - url.searchParams, - ) as [{ follow: Set; q?: string }, unknown] - if (queryError !== null) { - console.error( - `Error in ${url.pathname} query:\n${JSON.stringify( - query, - null, - 2, - )}\n\nError:\n${JSON.stringify(queryError, null, 2)}`, - ) - throw error(400, JSON.stringify(queryError, null, 2)) - } - const { follow, q } = query - - const aggregator = new Aggregator(follow) - let id: string | undefined = undefined - if (q !== undefined) { - // https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000006308296/ - // https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000006308296/1983-12-30/ - // https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000006308296/1984-12-30/ - // https://www.legifrance.gouv.fr/loda/article_lc/LEGIARTI000036456533 - // https://www.legifrance.gouv.fr/loda/article_lc/LEGIARTI000036456533/2018-01-01 - // https://www.legifrance.gouv.fr/loda/id/LEGIARTI000006317314/1983-12-30 - id = q.match(/LEGIARTI\d+/)?.[0] - if (id != null) { - const article = ( - await db<{ data: Article }[]>` - SELECT data FROM article - WHERE id = ${id} - ` - ).map(({ data }) => data)[0] - if (article !== undefined) { - aggregator.addArticle(article) - } - } - } - await aggregator.getAll() - - return { - ...aggregator.toJson(), - follow: [...follow], - id, - q, - } -} diff --git a/src/lib/server/doers/textes.ts b/src/lib/server/doers/textes.ts deleted file mode 100644 index 7a12cd8..0000000 --- a/src/lib/server/doers/textes.ts +++ /dev/null @@ -1,178 +0,0 @@ -import { type Audit, auditSetNullish, cleanAudit } from "@auditors/core" -import { error } from "@sveltejs/kit" - -import type { Aggregate, Follow } from "$lib/aggregates" -import { - auditFollowSearchParams, - auditLimitSearchParam, - auditOffsetSearchParam, - auditQSearchParam, -} from "$lib/auditors/search_params" -import type { TexteVersion } from "$lib/legal" -import { Aggregator } from "$lib/server/aggregates" -import { db } from "$lib/server/database" - -export function auditGetTexteSearchParams( - audit: Audit, - query: URLSearchParams, -): [unknown, unknown] { - if (query == null) { - return [query, null] - } - if (!(query instanceof URLSearchParams)) { - return audit.unexpectedType(query, "URLSearchParams") - } - - const data: { [key: string]: unknown } = {} - for (const [key, value] of query.entries()) { - let values = data[key] as string[] | undefined - if (values === undefined) { - values = data[key] = [] - } - values.push(value) - } - const errors: { [key: string]: unknown } = {} - const remainingKeys = new Set(Object.keys(data)) - - auditFollowSearchParams(audit, data, errors, remainingKeys) - - return audit.reduceRemaining(data, errors, remainingKeys, auditSetNullish({})) -} - -export function auditListTextesSearchParams( - audit: Audit, - query: URLSearchParams, -): [unknown, unknown] { - if (query == null) { - return [query, null] - } - if (!(query instanceof URLSearchParams)) { - return audit.unexpectedType(query, "URLSearchParams") - } - - const data: { [key: string]: unknown } = {} - for (const [key, value] of query.entries()) { - let values = data[key] as string[] | undefined - if (values === undefined) { - values = data[key] = [] - } - values.push(value) - } - const errors: { [key: string]: unknown } = {} - const remainingKeys = new Set(Object.keys(data)) - - auditFollowSearchParams(audit, data, errors, remainingKeys) - auditLimitSearchParam(audit, data, errors, remainingKeys) - auditOffsetSearchParam(audit, data, errors, remainingKeys) - auditQSearchParam(audit, data, errors, remainingKeys) - - return audit.reduceRemaining(data, errors, remainingKeys, auditSetNullish({})) -} - -export const doGetTexte = async ( - id: string, - url: URL, -): Promise< - Aggregate & { - follow: Follow[] - } -> => { - const [query, queryError] = auditGetTexteSearchParams( - cleanAudit, - url.searchParams, - ) as [ - { - follow: Set - }, - unknown, - ] - if (queryError !== null) { - console.error( - `Error in ${url.pathname} query:\n${JSON.stringify( - query, - null, - 2, - )}\n\nError:\n${JSON.stringify(queryError, null, 2)}`, - ) - throw error(400, JSON.stringify(queryError, null, 2)) - } - const { follow } = query - const texteVersion = ( - await db<{ data: TexteVersion }[]>` - SELECT data FROM texte_version - WHERE ID = ${id} - ` - ).map(({ data }) => data)[0] - if (texteVersion === undefined) { - throw error(404, `TEXTE_VERSION ${id} non trouvé`) - } - - const aggregator = new Aggregator(follow) - aggregator.addTexteVersion(texteVersion) - await aggregator.getAll() - - return { - ...aggregator.toJson(), - follow: [...follow], - id, - } -} - -export const doListTextes = async ( - url: URL, -): Promise< - Aggregate & { - follow: Follow[] - limit: number - offset: number - q?: string - } -> => { - const [query, queryError] = auditListTextesSearchParams( - cleanAudit, - url.searchParams, - ) as [ - { - follow: Set - limit: number - offset: number - q?: string - }, - unknown, - ] - if (queryError !== null) { - console.error( - `Error in ${url.pathname} query:\n${JSON.stringify( - query, - null, - 2, - )}\n\nError:\n${JSON.stringify(queryError, null, 2)}`, - ) - throw error(400, JSON.stringify(queryError, null, 2)) - } - const { follow, limit, offset, q } = query - const texteVersionArray = ( - await db<{ data: TexteVersion }[]>` - SELECT data FROM texte_version - OFFSET ${offset} - LIMIT ${limit} - ` - ).map(({ data }) => data) - - const aggregator = new Aggregator(follow) - for (const texteVersion of texteVersionArray) { - aggregator.addTexteVersion(texteVersion) - } - await aggregator.getAll() - - return { - ...aggregator.toJson(), - follow: [...follow], - ids: texteVersionArray.map( - (texteVersion) => texteVersion.META.META_COMMUN.ID, - ), - limit, - offset, - q, - } -} diff --git a/src/routes/api/recherche/+server.ts b/src/routes/api/recherche/+server.ts index 5b43846..e62bf77 100644 --- a/src/routes/api/recherche/+server.ts +++ b/src/routes/api/recherche/+server.ts @@ -1,12 +1,101 @@ -import { doGetRecherche } from "$lib/server/doers/recherche" +import { type Audit, auditSetNullish, cleanAudit } from "@auditors/core" +import { error } from "@sveltejs/kit" + +import type { Follow } from "$lib/aggregates" +import { + auditFollowSearchParams, + auditQSearchParam, +} from "$lib/auditors/search_params" +import type { Article } from "$lib/legal" +import { Aggregator } from "$lib/server/aggregates" +import { db } from "$lib/server/database" import type { RequestHandler } from "./$types" -export const GET: RequestHandler = async ({ url }) => { - const result = await doGetRecherche(url) - return new Response(JSON.stringify(result, null, 2), { - headers: { - "Content-Type": "application/json; charset=utf-8", - }, - }) +export function auditSearchParams( + audit: Audit, + query: URLSearchParams, +): [unknown, unknown] { + if (query == null) { + return [query, null] + } + if (!(query instanceof URLSearchParams)) { + return audit.unexpectedType(query, "URLSearchParams") + } + + const data: { [key: string]: unknown } = {} + for (const [key, value] of query.entries()) { + let values = data[key] as string[] | undefined + if (values === undefined) { + values = data[key] = [] + } + values.push(value) + } + const errors: { [key: string]: unknown } = {} + const remainingKeys = new Set(Object.keys(data)) + + auditFollowSearchParams(audit, data, errors, remainingKeys) + auditQSearchParam(audit, data, errors, remainingKeys) + + return audit.reduceRemaining(data, errors, remainingKeys, auditSetNullish({})) +} + +export const GET: RequestHandler = async ({ url }) => { + const [query, queryError] = auditSearchParams( + cleanAudit, + url.searchParams, + ) as [{ follow: Set; q?: string }, unknown] + if (queryError !== null) { + console.error( + `Error in ${url.pathname} query:\n${JSON.stringify( + query, + null, + 2, + )}\n\nError:\n${JSON.stringify(queryError, null, 2)}`, + ) + throw error(400, JSON.stringify(queryError, null, 2)) + } + const { follow, q } = query + + const aggregator = new Aggregator(follow) + let id: string | undefined = undefined + if (q !== undefined) { + // https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000006308296/ + // https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000006308296/1983-12-30/ + // https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000006308296/1984-12-30/ + // https://www.legifrance.gouv.fr/loda/article_lc/LEGIARTI000036456533 + // https://www.legifrance.gouv.fr/loda/article_lc/LEGIARTI000036456533/2018-01-01 + // https://www.legifrance.gouv.fr/loda/id/LEGIARTI000006317314/1983-12-30 + id = q.match(/LEGIARTI\d+/)?.[0] + if (id != null) { + const article = ( + await db<{ data: Article }[]>` + SELECT data FROM article + WHERE id = ${id} + ` + ).map(({ data }) => data)[0] + if (article !== undefined) { + aggregator.addArticle(article) + } + } + } + await aggregator.getAll() + + return new Response( + JSON.stringify( + { + ...aggregator.toJson(), + follow: [...follow], + id, + q, + }, + null, + 2, + ), + { + headers: { + "Content-Type": "application/json; charset=utf-8", + }, + }, + ) } diff --git a/src/routes/api/textes/+server.ts b/src/routes/api/textes/+server.ts index e374aa1..edcecb2 100644 --- a/src/routes/api/textes/+server.ts +++ b/src/routes/api/textes/+server.ts @@ -1,12 +1,106 @@ -import { doListTextes } from "$lib/server/doers/textes" +import { type Audit, auditSetNullish, cleanAudit } from "@auditors/core" +import { error } from "@sveltejs/kit" + +import type { Follow } from "$lib/aggregates" +import { + auditFollowSearchParams, + auditLimitSearchParam, + auditOffsetSearchParam, + auditQSearchParam, +} from "$lib/auditors/search_params" +import type { TexteVersion } from "$lib/legal" +import { Aggregator } from "$lib/server/aggregates" +import { db } from "$lib/server/database" import type { RequestHandler } from "./$types" -export const GET: RequestHandler = async ({ url }) => { - const result = await doListTextes(url) - return new Response(JSON.stringify(result, null, 2), { - headers: { - "Content-Type": "application/json; charset=utf-8", - }, - }) +export function auditSearchParams( + audit: Audit, + query: URLSearchParams, +): [unknown, unknown] { + if (query == null) { + return [query, null] + } + if (!(query instanceof URLSearchParams)) { + return audit.unexpectedType(query, "URLSearchParams") + } + + const data: { [key: string]: unknown } = {} + for (const [key, value] of query.entries()) { + let values = data[key] as string[] | undefined + if (values === undefined) { + values = data[key] = [] + } + values.push(value) + } + const errors: { [key: string]: unknown } = {} + const remainingKeys = new Set(Object.keys(data)) + + auditFollowSearchParams(audit, data, errors, remainingKeys) + auditLimitSearchParam(audit, data, errors, remainingKeys) + auditOffsetSearchParam(audit, data, errors, remainingKeys) + auditQSearchParam(audit, data, errors, remainingKeys) + + return audit.reduceRemaining(data, errors, remainingKeys, auditSetNullish({})) +} + +export const GET: RequestHandler = async ({ url }) => { + const [query, queryError] = auditSearchParams( + cleanAudit, + url.searchParams, + ) as [ + { + follow: Set + limit: number + offset: number + q?: string + }, + unknown, + ] + if (queryError !== null) { + console.error( + `Error in ${url.pathname} query:\n${JSON.stringify( + query, + null, + 2, + )}\n\nError:\n${JSON.stringify(queryError, null, 2)}`, + ) + throw error(400, JSON.stringify(queryError, null, 2)) + } + const { follow, limit, offset, q } = query + const texteVersionArray = ( + await db<{ data: TexteVersion }[]>` + SELECT data FROM texte_version + OFFSET ${offset} + LIMIT ${limit} + ` + ).map(({ data }) => data) + + const aggregator = new Aggregator(follow) + for (const texteVersion of texteVersionArray) { + aggregator.addTexteVersion(texteVersion) + } + await aggregator.getAll() + + return new Response( + JSON.stringify( + { + ...aggregator.toJson(), + follow: [...follow], + ids: texteVersionArray.map( + (texteVersion) => texteVersion.META.META_COMMUN.ID, + ), + limit, + offset, + q, + }, + null, + 2, + ), + { + headers: { + "Content-Type": "application/json; charset=utf-8", + }, + }, + ) } diff --git a/src/routes/api/textes/[id]/+server.ts b/src/routes/api/textes/[id]/+server.ts index 553e8c1..aceda4c 100644 --- a/src/routes/api/textes/[id]/+server.ts +++ b/src/routes/api/textes/[id]/+server.ts @@ -1,12 +1,91 @@ -import { doGetTexte } from "$lib/server/doers/textes" +import { type Audit, auditSetNullish, cleanAudit } from "@auditors/core" +import { error } from "@sveltejs/kit" + +import { auditFollowSearchParams } from "$lib/auditors/search_params" + +import type { Follow } from "$lib/aggregates" +import type { TexteVersion } from "$lib/legal" +import { Aggregator } from "$lib/server/aggregates" +import { db } from "$lib/server/database" import type { RequestHandler } from "./$types" -export const GET: RequestHandler = async ({ params, url }) => { - const result = await doGetTexte(params.id, url) - return new Response(JSON.stringify(result, null, 2), { - headers: { - "Content-Type": "application/json; charset=utf-8", - }, - }) +export function auditSearchParams( + audit: Audit, + query: URLSearchParams, +): [unknown, unknown] { + if (query == null) { + return [query, null] + } + if (!(query instanceof URLSearchParams)) { + return audit.unexpectedType(query, "URLSearchParams") + } + + const data: { [key: string]: unknown } = {} + for (const [key, value] of query.entries()) { + let values = data[key] as string[] | undefined + if (values === undefined) { + values = data[key] = [] + } + values.push(value) + } + const errors: { [key: string]: unknown } = {} + const remainingKeys = new Set(Object.keys(data)) + + auditFollowSearchParams(audit, data, errors, remainingKeys) + + return audit.reduceRemaining(data, errors, remainingKeys, auditSetNullish({})) +} + +export const GET: RequestHandler = async ({ params, url }) => { + const [query, queryError] = auditSearchParams( + cleanAudit, + url.searchParams, + ) as [ + { + follow: Set + }, + unknown, + ] + if (queryError !== null) { + console.error( + `Error in ${url.pathname} query:\n${JSON.stringify( + query, + null, + 2, + )}\n\nError:\n${JSON.stringify(queryError, null, 2)}`, + ) + throw error(400, JSON.stringify(queryError, null, 2)) + } + const { follow } = query + const texteVersion = ( + await db<{ data: TexteVersion }[]>` + SELECT data FROM texte_version + WHERE ID = ${params.id} + ` + ).map(({ data }) => data)[0] + if (texteVersion === undefined) { + throw error(404, `TEXTE_VERSION ${params.id} non trouvé`) + } + + const aggregator = new Aggregator(follow) + aggregator.addTexteVersion(texteVersion) + await aggregator.getAll() + + return new Response( + JSON.stringify( + { + ...aggregator.toJson(), + follow: [...follow], + id: params.id, + }, + null, + 2, + ), + { + headers: { + "Content-Type": "application/json; charset=utf-8", + }, + }, + ) } diff --git a/src/routes/recherche/+page.server.ts b/src/routes/recherche/+page.server.ts deleted file mode 100644 index ef82ac2..0000000 --- a/src/routes/recherche/+page.server.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { doGetRecherche } from "$lib/server/doers/recherche" - -import type { PageServerLoad } from "./$types" - -export const load: PageServerLoad = async ({ url }) => { - return (await doGetRecherche(url)) ?? {} -} diff --git a/src/routes/recherche/+page.ts b/src/routes/recherche/+page.ts new file mode 100644 index 0000000..3043409 --- /dev/null +++ b/src/routes/recherche/+page.ts @@ -0,0 +1,20 @@ +import { error } from "@sveltejs/kit" + +import type { GetRechercheResult } from "$lib/aggregates" + +import type { PageLoad } from "./$types" + +export const load: PageLoad = async ({ fetch, url }) => { + const apiUrl = `/api${url.pathname}` + const response = await fetch(apiUrl, { + headers: { Accept: "application/json" }, + }) + if (!response.ok) { + const text = await response.text() + console.error( + `Error in ${url.pathname} while calling ${apiUrl}:\n${response.status} ${response.statusText}\n\n${text}`, + ) + throw error(response.status, text) + } + return (await response.json()) as GetRechercheResult +} diff --git a/src/routes/textes/+page.server.ts b/src/routes/textes/+page.server.ts deleted file mode 100644 index 5bb1c7f..0000000 --- a/src/routes/textes/+page.server.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { doListTextes } from "$lib/server/doers/textes" - -import type { PageServerLoad } from "./$types" - -export const load: PageServerLoad = async ({ url }) => { - return (await doListTextes(url)) ?? {} -} diff --git a/src/routes/textes/+page.ts b/src/routes/textes/+page.ts new file mode 100644 index 0000000..ca4559b --- /dev/null +++ b/src/routes/textes/+page.ts @@ -0,0 +1,20 @@ +import { error } from "@sveltejs/kit" + +import type { ListTextesResult } from "$lib/aggregates" + +import type { PageLoad } from "./$types" + +export const load: PageLoad = async ({ fetch, url }) => { + const apiUrl = `/api${url.pathname}` + const response = await fetch(apiUrl, { + headers: { Accept: "application/json" }, + }) + if (!response.ok) { + const text = await response.text() + console.error( + `Error in ${url.pathname} while calling ${apiUrl}:\n${response.status} ${response.statusText}\n\n${text}`, + ) + throw error(response.status, text) + } + return (await response.json()) as ListTextesResult +} diff --git a/src/routes/textes/[id]/+page.server.ts b/src/routes/textes/[id]/+page.server.ts deleted file mode 100644 index 9e7a293..0000000 --- a/src/routes/textes/[id]/+page.server.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { doGetTexte } from "$lib/server/doers/textes" - -import type { PageServerLoad } from "./$types" - -export const load: PageServerLoad = async ({ params, url }) => { - return (await doGetTexte(params.id, url)) ?? {} -} diff --git a/src/routes/textes/[id]/+page.ts b/src/routes/textes/[id]/+page.ts new file mode 100644 index 0000000..0d1d740 --- /dev/null +++ b/src/routes/textes/[id]/+page.ts @@ -0,0 +1,20 @@ +import { error } from "@sveltejs/kit" + +import type { GetTexteResult } from "$lib/aggregates" + +import type { PageLoad } from "./$types" + +export const load: PageLoad = async ({ fetch, url }) => { + const apiUrl = `/api${url.pathname}` + const response = await fetch(apiUrl, { + headers: { Accept: "application/json" }, + }) + if (!response.ok) { + const text = await response.text() + console.error( + `Error in ${url.pathname} while calling ${apiUrl}:\n${response.status} ${response.statusText}\n\n${text}`, + ) + throw error(response.status, text) + } + return (await response.json()) as GetTexteResult +}