Use API instead of sharing code with doers.

This commit is contained in:
Emmanuel 2022-08-25 17:12:12 +02:00
parent 7fb08b413d
commit a0d9f1a06e
14 changed files with 554 additions and 511 deletions

378
package-lock.json generated
View file

@ -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": {

View file

@ -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",

View file

@ -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",

View file

@ -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<Follow>; 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,
}
}

View file

@ -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<Follow>
},
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<Follow>
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,
}
}

View file

@ -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<Follow>; 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",
},
},
)
}

View file

@ -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<Follow>
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",
},
},
)
}

View file

@ -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<Follow>
},
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",
},
},
)
}

View file

@ -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)) ?? {}
}

View file

@ -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
}

View file

@ -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)) ?? {}
}

View file

@ -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
}

View file

@ -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)) ?? {}
}

View file

@ -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
}