diff --git a/.gitignore b/.gitignore index 272173e..7996add 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,6 @@ node_modules .vercel .output *.swp -*/*.swp \ No newline at end of file +*/*.swp +/src/lib/db/*.sqlite +/src/lib/db/*.sqlite* diff --git a/package.json b/package.json index e845911..0fc16a9 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,9 @@ "type": "module", "dependencies": { "@fontsource/fira-mono": "^4.5.0", + "@types/better-sqlite3": "^7.6.1", + "better-sqlite3": "^7.6.2", + "cookie": "^0.5.0", "html2canvas": "^1.4.1", "quill": "^1.3.7" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2eab755..e9ad3de 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,10 @@ specifiers: '@sveltejs/adapter-auto': next '@sveltejs/adapter-node': 1.0.0-next.95 '@sveltejs/kit': next + '@types/better-sqlite3': ^7.6.1 '@types/cookie': ^0.5.1 + better-sqlite3: ^7.6.2 + cookie: ^0.5.0 html2canvas: ^1.4.1 prettier: ^2.6.2 prettier-plugin-svelte: ^2.7.0 @@ -17,13 +20,16 @@ specifiers: dependencies: '@fontsource/fira-mono': 4.5.9 + '@types/better-sqlite3': 7.6.1 + better-sqlite3: 7.6.2 + cookie: 0.5.0 html2canvas: 1.4.1 quill: 1.3.7 devDependencies: '@sveltejs/adapter-auto': 1.0.0-next.80 '@sveltejs/adapter-node': 1.0.0-next.95 - '@sveltejs/kit': 1.0.0-next.503_svelte@3.50.1+vite@3.1.3 + '@sveltejs/kit': 1.0.0-next.511_svelte@3.50.1+vite@3.1.3 '@types/cookie': 0.5.1 prettier: 2.7.1 prettier-plugin-svelte: 2.7.0_nk6d2fkgcllkkdynqbuearcure @@ -229,8 +235,8 @@ packages: - supports-color dev: true - /@sveltejs/kit/1.0.0-next.503_svelte@3.50.1+vite@3.1.3: - resolution: {integrity: sha512-QSEHe40qMOYjXirxS57dIa9NU4FntlYh+KYslBzasjMCfSiUkHGaWMJRz8uU+R4BWnThD9SdCo7F/NwDxu5LRQ==} + /@sveltejs/kit/1.0.0-next.511_svelte@3.50.1+vite@3.1.3: + resolution: {integrity: sha512-A/fxd4qHWDD07Mjo6qEEEfsBEkoj5C4/dPSzx6xPUoWmPvRPhU8t+P0oMc8BOn5YHOhPDq3coH8bmafbh73zKg==} engines: {node: '>=16.14'} hasBin: true requiresBuild: true @@ -241,17 +247,16 @@ packages: '@sveltejs/vite-plugin-svelte': 1.0.8_svelte@3.50.1+vite@3.1.3 '@types/cookie': 0.5.1 cookie: 0.5.0 - devalue: 3.1.3 + devalue: 4.0.0 kleur: 4.1.5 magic-string: 0.26.4 mime: 3.0.0 - node-fetch: 3.2.10 sade: 1.8.1 set-cookie-parser: 2.5.1 sirv: 2.0.2 svelte: 3.50.1 tiny-glob: 0.2.9 - undici: 5.10.0 + undici: 5.11.0 vite: 3.1.3 transitivePeerDependencies: - diff-match-patch @@ -281,6 +286,12 @@ packages: - supports-color dev: true + /@types/better-sqlite3/7.6.1: + resolution: {integrity: sha512-2MuzBUSwAjY8GoT04vcLUojHmuuOCEFboESZfx6u9gpnHym5mYBMhCKGoe+R+yXkiho1xg348LRH8x27cJLHjw==} + dependencies: + '@types/node': 18.7.18 + dev: false + /@types/cookie/0.5.1: resolution: {integrity: sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g==} dev: true @@ -295,7 +306,6 @@ packages: /@types/node/18.7.18: resolution: {integrity: sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg==} - dev: true /@types/pug/2.0.6: resolution: {integrity: sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==} @@ -390,6 +400,18 @@ packages: engines: {node: '>= 0.6.0'} dev: false + /base64-js/1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false + + /better-sqlite3/7.6.2: + resolution: {integrity: sha512-S5zIU1Hink2AH4xPsN0W43T1/AJ5jrPh7Oy07ocuW/AKYYY02GWzz9NH0nbSMn/gw6fDZ5jZ1QsHt1BXAwJ6Lg==} + requiresBuild: true + dependencies: + bindings: 1.5.0 + prebuild-install: 7.1.1 + dev: false + /binary-extensions/2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} @@ -399,7 +421,14 @@ packages: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} dependencies: file-uri-to-path: 1.0.0 - dev: true + + /bl/4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.0 + dev: false /brace-expansion/1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -419,11 +448,25 @@ packages: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} dev: true + /buffer/5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: false + /builtin-modules/3.3.0: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} dev: true + /busboy/1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + dependencies: + streamsearch: 1.1.0 + dev: true + /call-bind/1.0.2: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} dependencies: @@ -451,6 +494,10 @@ packages: fsevents: 2.3.2 dev: true + /chownr/1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + dev: false + /chownr/2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} @@ -481,7 +528,6 @@ packages: /cookie/0.5.0: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} engines: {node: '>= 0.6'} - dev: true /css-line-break/2.1.0: resolution: {integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==} @@ -489,11 +535,6 @@ packages: utrie: 1.0.2 dev: false - /data-uri-to-buffer/4.0.0: - resolution: {integrity: sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==} - engines: {node: '>= 12'} - dev: true - /debug/4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -506,6 +547,13 @@ packages: ms: 2.1.2 dev: true + /decompress-response/6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + dependencies: + mimic-response: 3.1.0 + dev: false + /deep-equal/1.1.1: resolution: {integrity: sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==} dependencies: @@ -517,6 +565,11 @@ packages: regexp.prototype.flags: 1.4.3 dev: false + /deep-extend/0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + dev: false + /deepmerge/4.2.2: resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} engines: {node: '>=0.10.0'} @@ -542,16 +595,21 @@ packages: /detect-libc/2.0.1: resolution: {integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==} engines: {node: '>=8'} - dev: true - /devalue/3.1.3: - resolution: {integrity: sha512-9KO89Cb+qjzf2CqdrH+NuLaqdk9GhDP5EhR4zlkR51dvuIaiqtlkDkGzLMShDemwUy21raSMdu+kpX8Enw3yGQ==} + /devalue/4.0.0: + resolution: {integrity: sha512-w25siwXyuMUqMr7jPlEjyNCp1vn0Jzj/fNg3qVt/r/Dpe8HjESh2V92L0jmh3uq4iJt0BvjH+Azk1pQzkcnDWA==} dev: true /emoji-regex/8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: true + /end-of-stream/1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + dependencies: + once: 1.4.0 + dev: false + /es6-promise/3.3.1: resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} dev: true @@ -782,6 +840,11 @@ packages: resolution: {integrity: sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==} dev: false + /expand-template/2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + dev: false + /extend/3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} dev: false @@ -807,17 +870,8 @@ packages: reusify: 1.0.4 dev: true - /fetch-blob/3.2.0: - resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} - engines: {node: ^12.20 || >= 14.13} - dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 3.2.1 - dev: true - /file-uri-to-path/1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - dev: true /fill-range/7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} @@ -826,12 +880,9 @@ packages: to-regex-range: 5.0.1 dev: true - /formdata-polyfill/4.0.10: - resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} - engines: {node: '>=12.20.0'} - dependencies: - fetch-blob: 3.2.0 - dev: true + /fs-constants/1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + dev: false /fs-minipass/2.1.0: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} @@ -882,6 +933,10 @@ packages: has-symbols: 1.0.3 dev: false + /github-from-package/0.0.0: + resolution: {integrity: sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=} + dev: false + /glob-parent/5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -958,6 +1013,10 @@ packages: - supports-color dev: true + /ieee754/1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: false + /import-fresh/3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} @@ -975,7 +1034,10 @@ packages: /inherits/2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: true + + /ini/1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + dev: false /is-arguments/1.1.1: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} @@ -1062,7 +1124,6 @@ packages: engines: {node: '>=10'} dependencies: yallist: 4.0.0 - dev: true /magic-string/0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} @@ -1103,6 +1164,11 @@ packages: hasBin: true dev: true + /mimic-response/3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + dev: false + /min-indent/1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} @@ -1116,7 +1182,6 @@ packages: /minimist/1.2.6: resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} - dev: true /minipass/3.3.4: resolution: {integrity: sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==} @@ -1133,6 +1198,10 @@ packages: yallist: 4.0.0 dev: true + /mkdirp-classic/0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + dev: false + /mkdirp/0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true @@ -1166,10 +1235,16 @@ packages: hasBin: true dev: true - /node-domexception/1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} - dev: true + /napi-build-utils/1.0.2: + resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} + dev: false + + /node-abi/3.26.0: + resolution: {integrity: sha512-jRVtMFTChbi2i/jqo/i2iP9634KMe+7K1v35mIdj3Mn59i5q27ZYhn+sW6npISM/PQg7HrP2kwtRBMmh5Uvzdg==} + engines: {node: '>=10'} + dependencies: + semver: 7.3.7 + dev: false /node-fetch/2.6.7: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} @@ -1183,15 +1258,6 @@ packages: whatwg-url: 5.0.0 dev: true - /node-fetch/3.2.10: - resolution: {integrity: sha512-MhuzNwdURnZ1Cp4XTazr69K0BTizsBroX7Zx3UgDSVcZYKF/6p0CBe4EUb/hLqmzVhl0UpYfgRljQ4yxE+iCxA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - data-uri-to-buffer: 4.0.0 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 - dev: true - /node-gyp-build/4.5.0: resolution: {integrity: sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==} hasBin: true @@ -1241,7 +1307,6 @@ packages: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: wrappy: 1.0.2 - dev: true /parchment/1.1.4: resolution: {integrity: sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==} @@ -1281,6 +1346,25 @@ packages: source-map-js: 1.0.2 dev: true + /prebuild-install/7.1.1: + resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + detect-libc: 2.0.1 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.6 + mkdirp-classic: 0.5.3 + napi-build-utils: 1.0.2 + node-abi: 3.26.0 + pump: 3.0.0 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.1 + tunnel-agent: 0.6.0 + dev: false + /prettier-plugin-svelte/2.7.0_nk6d2fkgcllkkdynqbuearcure: resolution: {integrity: sha512-fQhhZICprZot2IqEyoiUYLTRdumULGRvw0o4dzl5jt0jfzVWdGqeYW27QTWAeXhoupEZJULmNoH3ueJwUWFLIA==} peerDependencies: @@ -1297,6 +1381,13 @@ packages: hasBin: true dev: true + /pump/3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: false + /queue-microtask/1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true @@ -1321,6 +1412,16 @@ packages: quill-delta: 3.6.3 dev: false + /rc/1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.6 + strip-json-comments: 2.0.1 + dev: false + /readable-stream/3.6.0: resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} engines: {node: '>= 6'} @@ -1328,7 +1429,6 @@ packages: inherits: 2.0.4 string_decoder: 1.3.0 util-deprecate: 1.0.2 - dev: true /readdirp/3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} @@ -1418,7 +1518,6 @@ packages: /safe-buffer/5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: true /sander/0.5.1: resolution: {integrity: sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==} @@ -1440,7 +1539,6 @@ packages: hasBin: true dependencies: lru-cache: 6.0.0 - dev: true /set-blocking/2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} @@ -1454,6 +1552,18 @@ packages: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true + /simple-concat/1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + dev: false + + /simple-get/4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + dev: false + /sirv/2.0.2: resolution: {integrity: sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w==} engines: {node: '>= 10'} @@ -1482,6 +1592,11 @@ packages: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} dev: true + /streamsearch/1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + dev: true + /string-width/4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -1495,7 +1610,6 @@ packages: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} dependencies: safe-buffer: 5.2.1 - dev: true /strip-ansi/6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} @@ -1511,6 +1625,11 @@ packages: min-indent: 1.0.1 dev: true + /strip-json-comments/2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + dev: false + /supports-preserve-symlinks-flag/1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} @@ -1609,6 +1728,26 @@ packages: engines: {node: '>= 8'} dev: true + /tar-fs/2.1.1: + resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 2.2.0 + dev: false + + /tar-stream/2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.0 + dev: false + /tar/6.1.11: resolution: {integrity: sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==} engines: {node: '>= 10'} @@ -1650,20 +1789,27 @@ packages: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} dev: true + /tunnel-agent/0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + dependencies: + safe-buffer: 5.2.1 + dev: false + /typescript/4.8.3: resolution: {integrity: sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==} engines: {node: '>=4.2.0'} hasBin: true dev: true - /undici/5.10.0: - resolution: {integrity: sha512-c8HsD3IbwmjjbLvoZuRI26TZic+TSEe8FPMLLOkN1AfYRhdjnKBU6yL+IwcSCbdZiX4e5t0lfMDLDCqj4Sq70g==} + /undici/5.11.0: + resolution: {integrity: sha512-oWjWJHzFet0Ow4YZBkyiJwiK5vWqEYoH7BINzJAJOLedZ++JpAlCbUktW2GQ2DS2FpKmxD/JMtWUUWl1BtghGw==} engines: {node: '>=12.18'} + dependencies: + busboy: 1.6.0 dev: true /util-deprecate/1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - dev: true /utrie/1.0.2: resolution: {integrity: sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==} @@ -1698,11 +1844,6 @@ packages: fsevents: 2.3.2 dev: true - /web-streams-polyfill/3.2.1: - resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} - engines: {node: '>= 8'} - dev: true - /webidl-conversions/3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: true @@ -1730,8 +1871,6 @@ packages: /wrappy/1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - dev: true /yallist/4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: true diff --git a/src/hooks.js b/src/hooks.js new file mode 100644 index 0000000..7bdf268 --- /dev/null +++ b/src/hooks.js @@ -0,0 +1,45 @@ +import * as cookie from "cookie"; + +/** @type {import('@sveltejs/kit').Handle} */ +export const handle = async ({ event, resolve }) => { + const cookieHeader = event.request.headers.get("cookie"); + const cookies = cookie.parse(cookieHeader ?? ""); + + if (!cookies.session) { + return await resolve(event); + } + + // Esto es lo que hace pillar una sesión y que tengo que implementar con better-sqlite3 + // const session = await db.user.findUnique({ + // where: { id: cookies.session }, + // }); + + // if (session) { + // event.locals.user = { + // username: session.username, + // name: session.name, + // slug: session.slug, + // isAdmin: session.isAdmin, + // }; + // } + + return await resolve(event); +}; + +/** + * + * @param {*} param0 + * @returns + */ +export const getSession = ({ locals }) => { + if (!locals.user) return {}; + + return { + user: { + username: locals.user.username, + name: locals.user.name, + slug: locals.user.slug, + isAdmin: locals.user.isAdmin, + }, + }; +}; diff --git a/src/hooks.server.js b/src/hooks.server.js index d30c399..d4dd570 100644 --- a/src/hooks.server.js +++ b/src/hooks.server.js @@ -1,15 +1,15 @@ /** @type {import('@sveltejs/kit').Handle} */ export const handle = async ({ event, resolve }) => { - let userid = event.cookies.get('userid'); + let userid = event.cookies.get('userid'); - if (!userid) { - // if this is the first time the user has visited this app, - // set a cookie so that we recognise them when they return - userid = crypto.randomUUID(); - event.cookies.set('userid', userid, { path: '/' }); - } + if (!userid) { + // if this is the first time the user has visited this app, + // set a cookie so that we recognise them when they return + userid = crypto.randomUUID(); + event.cookies.set('userid', userid, { path: '/' }); + } - event.locals.userid = userid; + event.locals.userid = userid; - return resolve(event); + return resolve(event); }; diff --git a/src/lib/api.js b/src/lib/api.js new file mode 100644 index 0000000..aa01f75 --- /dev/null +++ b/src/lib/api.js @@ -0,0 +1,14 @@ +/** +* @async +* @function send +* @param {HTMLFormElement} form +* @returns {Promise} +*/ +export const send = async (form) => { + const response = await fetch(form.action, { + method: form.method, + body: new FormData(form), + headers: { accept: "application/json" }, + }); + return await response.json(); +}; diff --git a/src/lib/components/Address.svelte b/src/lib/components/Address.svelte index 0c5209c..c09fa0a 100644 --- a/src/lib/components/Address.svelte +++ b/src/lib/components/Address.svelte @@ -29,6 +29,9 @@ diff --git a/src/lib/components/Subtitle.svelte b/src/lib/components/Subtitle.svelte index 4e657d6..a9598ba 100644 --- a/src/lib/components/Subtitle.svelte +++ b/src/lib/components/Subtitle.svelte @@ -31,7 +31,9 @@ position: absolute; overflow: hidden; display: flex; + /* flex-direction: column; */ justify-content: center; - align-items: start; + align-items: center; + text-transform: uppercase; } diff --git a/src/lib/components/Text.svelte b/src/lib/components/Text.svelte index 636b0de..b626e14 100644 --- a/src/lib/components/Text.svelte +++ b/src/lib/components/Text.svelte @@ -5,6 +5,7 @@ subtitle, content, date, + newdate, time, weekday, address, @@ -28,9 +29,20 @@ {#if checked}

Estimada/o amiga/o:

-

El {$weekday.toLowerCase()}, {textDate}, celebramos el acto '{$title}' en {$city}.

+

+ El {$weekday.toLowerCase()}, {textDate}, celebramos el acto '{$title}' en {$city}. +

Como siempre, la entrada es gratuita hasta completar aforo.

-

El acto comienza a las {$time}.

+

{@html $content}

{/if} @@ -47,9 +59,12 @@ background-color: #fff; } p { - margin-bottom: 1rem; + margin: 1rem 0; } label { color: #333; } + li { + margin: 1rem 0; + } diff --git a/src/lib/components/Title.svelte b/src/lib/components/Title.svelte index b26b7bc..c63007f 100644 --- a/src/lib/components/Title.svelte +++ b/src/lib/components/Title.svelte @@ -33,5 +33,6 @@ display: flex; justify-content: center; align-items: center; + text-transform: uppercase; } diff --git a/src/lib/db/carteles_dev.sqlite b/src/lib/db/carteles_dev.sqlite new file mode 100644 index 0000000..f71bd4d Binary files /dev/null and b/src/lib/db/carteles_dev.sqlite differ diff --git a/src/lib/db/db.js b/src/lib/db/db.js new file mode 100644 index 0000000..370aa16 --- /dev/null +++ b/src/lib/db/db.js @@ -0,0 +1,38 @@ +/** @typedef {typeof import('better-sqlite3')} better-sqlite3 */ +import Database from 'better-sqlite3'; + +export const db = new Database('./src/lib/db/carteles_dev.sqlite', { verbose: console.log }); +db.pragma("journal_mode = WAL"); +db.pragma("synchronous = normal"); +db.pragma("temp_store = memory"); + +const createUserTable = db.prepare(`CREATE TABLE IF NOT EXISTS Users ( + email TEXT PRIMARY KEY UNIQUE NOT NULL, + password TEXT, + isAdmin INTEGER + );`); + +const createPostersTable = db.prepare(`CREATE TABLE IF NOT EXISTS Posters ( + id INTEGER PRIMARY KEY UNIQUE NOT NULL, + createdAt TEXT NOT NULL, + image BLOB NOT NULL, + content TEXT +);`); + +createUserTable.run(); +createPostersTable.run(); + +/** +* @typedef {Object} User +* @property {string} [email] +* @property {string} [password] +* @property {boolean} [isAdmin] +*/ + +/** +* @typedef {Object} Poster +* @property {number} [id] +* @property {string} [createdAt] Date +* @property {Blob} [image] +* @property {string} [content] Stringified contents +*/ diff --git a/src/lib/db/utils.js b/src/lib/db/utils.js new file mode 100644 index 0000000..6f2797f --- /dev/null +++ b/src/lib/db/utils.js @@ -0,0 +1,95 @@ +import { db } from '$lib/db/db.js'; +/** +* Return of functions that change change DB, either 'success' or 'failure' with explanation +* @typedef {Object} ChangeDBResult +* @property {string} [error] +* @property {string} [success] +* @property {string} [id] +*/ + +/** +* @function addUserToDB Adds user to the db +* @param {string} email +* @param {string} passwordHash +* @param {boolean} isAdmin +* @returns {ChangeDBResult} return +*/ +export const addUserToDB = (email, passwordHash, isAdmin) => { + if (!email || !passwordHash || !isAdmin) { + return { + error: "Either email, password or isAdmin are missing" + }; + } + const addUser = db.prepare(`INSERT INTO Users(email,password,isAdmin) VALUES(?,?,?);`) + const result = addUser.run(email, passwordHash, isAdmin); + if (result.changes === 1) { + return { + success: `User '${email}' added to DB` + } + } + return { error: `Could not add user '${email}' to DB`, }; +} + +/** Removes user from db +* @param {string} email +* @returns {ChangeDBResult} return +*/ +export const delUserFromDB = (email) => { + if (!email) { + return { + error: "Email not provided" + } + } + const delUser = db.prepare(`DELETE FROM Users WHERE email=${email};`); + const result = delUser.run(); + if (result.changes === 1) { + return { + success: `User '${email}' removed successfully` + } + } + return { error: `Could not remove user '${email}' from DB` } +} + +/** +* @function addPosterToDB +* @param {any} image +* @param {string} content +* @returns {ChangeDBResult} return +*/ +export const addPosterToDB = (image, content) => { + + const id = crypto.randomUUID(); // Create random ID for Poster + console.log("New id is: ", id); + + const createdAt = Date.now().toString; + + if (!image) { // Return error if mandatory info is missing + return { + error: "Image missing" + } + } + + const addPoster = db.prepare(`INSERT INTO Posters(id,createdAt,image,content) VALUES ($id,$createdAt,$image,$content);`); + const result = addPoster.run({ + id: id, + createdAt: createdAt, + image: image, + content: content + }); + + if (result.changes === 1) { + return { + success: `Poster added to DB with id ${id}`, + id + } + } + return { // Default return just in case + error: `Could not save poster '${id}' to DB. Something went wrong` + } +} + +export const getAllPostersFromDB = () => { + const getPosters = db.prepare(`SELECT * FROM Posters;`); + const result = getPosters.all(); + return result; +} diff --git a/src/lib/form/Form.svelte b/src/lib/form/Form.svelte index 3030579..7d3a374 100644 --- a/src/lib/form/Form.svelte +++ b/src/lib/form/Form.svelte @@ -32,6 +32,34 @@ $content = editor.firstChild.innerHTML; } }; + const saveCanvas = async () => { + if ($canvas !== undefined) { + const img = await html2canvas($canvas, { scale: 2 }); + const image = img.toDataURL('image/png'); + const data = new FormData(); + data.append('image', image); + data.append( + 'content', + JSON.stringify({ + title: $title, + heading: $heading, + subtitle: $subtitle, + content: $content, + date: $date, + time: $time, + weekday: $weekday, + address: $address, + city: $city + }) + ); + + const req = await fetch('/admin', { + method: 'POST', + body: data + }); + console.log(req); + } + }; const downloadCanvas = async () => { if ($canvas !== undefined) { @@ -131,6 +159,7 @@ + diff --git a/src/routes/[slug]/+page.svelte b/src/routes/[slug]/+page.svelte index 22acc17..b0ebb2c 100644 --- a/src/routes/[slug]/+page.svelte +++ b/src/routes/[slug]/+page.svelte @@ -42,11 +42,11 @@ .form { grid-column: 1/2; - background-color: rgb(230, 240, 240); + background-color: rgb(236, 240, 240); } .preview { grid-column: 2/3; - background-color: rgb(240, 238, 240); + background-color: rgb(240, 240, 240); } diff --git a/src/routes/admin/+page.server.js b/src/routes/admin/+page.server.js new file mode 100644 index 0000000..793c3af --- /dev/null +++ b/src/routes/admin/+page.server.js @@ -0,0 +1,33 @@ +import { error } from '@sveltejs/kit'; +import fs from 'fs'; +import stream from 'stream'; +// import { canvas } from '$lib/stores/store'; +import { getAllPostersFromDB, addPosterToDB } from '$lib/db/utils'; + +/** @type {import('./$types').PageServerLoad} */ +export const load = () => { + const posters = getAllPostersFromDB(); + if (posters !== undefined) { + return { + posters + } + } + throw error(404, "error"); +}; + +/** @type {import('./$types').Actions} */ +export const actions = { + default: async ({ request }) => { + console.log("Estoy aquí"); + const path = crypto.randomUUID(); + const data = await request.formData(); + const image = data.get("image")?.toString(); + const content = data.get("content"); + fs.writeFileSync(`./static/${path}.png`, image, 'base64url'); + // const savetoDB = addPosterToDB(image, content); + return { + success: true + } + } + +} diff --git a/src/routes/admin/+page.svelte b/src/routes/admin/+page.svelte new file mode 100644 index 0000000..de890a5 --- /dev/null +++ b/src/routes/admin/+page.svelte @@ -0,0 +1,31 @@ + + +

Test

+ + +
+ + + + +
+ + diff --git a/src/routes/admin/auth/login/+page.server.js b/src/routes/admin/auth/login/+page.server.js new file mode 100644 index 0000000..e69de29 diff --git a/src/routes/admin/auth/login/+page.svelte b/src/routes/admin/auth/login/+page.svelte new file mode 100644 index 0000000..e69de29 diff --git a/static/plantilla_verde.png b/static/plantilla_verde.png index d718b3e..b970afc 100644 Binary files a/static/plantilla_verde.png and b/static/plantilla_verde.png differ