diff --git a/package.json b/package.json index 5abe16f2..8e7b7c01 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,6 @@ "dotenv": "^16.0.0", "fast-deep-equal": "^3.1.3", "form-data": "^4.0.0", - "juice": "^8.0.0", "mailgun.js": "^5.2.2", "markdown-it": "^13.0.0", "nanoid": "^3.3.3", @@ -62,6 +61,7 @@ "@types/busboy": "^1.5.0", "@types/cookie": "^0.5.1", "@types/markdown-it": "^12.2.3", + "@types/mjml": "^4.7.0", "@types/node": "^17.0.31", "@types/pica": "^9.0.0", "@types/prismjs": "^1.26.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1f50c708..a8bd0345 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,6 +19,7 @@ specifiers: '@types/busboy': ^1.5.0 '@types/cookie': ^0.5.1 '@types/markdown-it': ^12.2.3 + '@types/mjml': ^4.7.0 '@types/node': ^17.0.31 '@types/pica': ^9.0.0 '@types/prismjs': ^1.26.0 @@ -40,7 +41,6 @@ specifiers: eslint-config-next: ^12.1.6 fast-deep-equal: ^3.1.3 form-data: ^4.0.0 - juice: ^8.0.0 mailgun.js: ^5.2.2 markdown-it: ^13.0.0 nanoid: ^3.3.3 @@ -89,7 +89,6 @@ dependencies: dotenv: 16.0.0 fast-deep-equal: 3.1.3 form-data: 4.0.0 - juice: 8.0.0 mailgun.js: 5.2.2 markdown-it: 13.0.1 nanoid: 3.3.4 @@ -116,6 +115,7 @@ devDependencies: '@types/busboy': 1.5.0 '@types/cookie': 0.5.1 '@types/markdown-it': 12.2.3 + '@types/mjml': 4.7.0 '@types/node': 17.0.31 '@types/pica': 9.0.0 '@types/prismjs': 1.26.0 @@ -830,6 +830,16 @@ packages: resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==} dev: true + /@types/mjml-core/4.7.1: + resolution: {integrity: sha512-k5IRafi93tyZBGF+0BTrcBDvG47OueI+Q7TC4V4UjGQn0AMVvL3Y+S26QF/UHMmMJW5r1hxLyv3StX2/+FatFg==} + dev: true + + /@types/mjml/4.7.0: + resolution: {integrity: sha512-aWWu8Lxq2SexXGs+lBPRUpN3kFf0sDRo3Y4jz7BQ15cQvMfyZOadgFJsNlHmDqI6D2Qjx0PIK+1f9IMXgq9vTA==} + dependencies: + '@types/mjml-core': 4.7.1 + dev: true + /@types/node/17.0.31: resolution: {integrity: sha512-AR0x5HbXGqkEx9CadRH3EBYx/VkiUgZIhP4wvPn/+5KIsgpNoyFaRlVe0Zlx9gRtg8fA06a9tskE2MSN7TcG4Q==} dev: true @@ -1005,11 +1015,6 @@ packages: uri-js: 4.4.1 dev: true - /ansi-colors/4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - dev: false - /ansi-regex/5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -1193,10 +1198,6 @@ packages: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} dev: false - /boolbase/1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - dev: false - /brace-expansion/1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -1284,31 +1285,6 @@ packages: supports-color: 7.2.0 dev: true - /cheerio-select/2.1.0: - resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} - dependencies: - boolbase: 1.0.0 - css-select: 5.1.0 - css-what: 6.1.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.0.1 - dev: false - - /cheerio/1.0.0-rc.11: - resolution: {integrity: sha512-bQwNaDIBKID5ts/DsdhxrjqFXYfLw4ste+wMKqWA8DyKcS4qwsPP4Bk8ZNaTJjvpiX/qW3BT4sU7d6Bh5i+dag==} - engines: {node: '>= 6'} - dependencies: - cheerio-select: 2.1.0 - dom-serializer: 2.0.0 - domhandler: 5.0.3 - domutils: 3.0.1 - htmlparser2: 8.0.1 - parse5: 7.0.0 - parse5-htmlparser2-tree-adapter: 7.0.0 - tslib: 2.4.0 - dev: false - /chokidar/3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -1375,11 +1351,6 @@ packages: engines: {node: '>= 6'} dev: true - /commander/6.2.1: - resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} - engines: {node: '>= 6'} - dev: false - /concat-map/0.0.1: resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} @@ -1413,21 +1384,6 @@ packages: which: 2.0.2 dev: true - /css-select/5.1.0: - resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} - dependencies: - boolbase: 1.0.0 - css-what: 6.1.0 - domhandler: 5.0.3 - domutils: 3.0.1 - nth-check: 2.0.1 - dev: false - - /css-what/6.1.0: - resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} - engines: {node: '>= 6'} - dev: false - /cssesc/3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -1554,63 +1510,6 @@ packages: esutils: 2.0.3 dev: true - /dom-serializer/1.4.1: - resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} - dependencies: - domelementtype: 2.3.0 - domhandler: 4.3.1 - entities: 2.2.0 - dev: false - - /dom-serializer/2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - entities: 4.3.0 - dev: false - - /domelementtype/2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - dev: false - - /domhandler/3.3.0: - resolution: {integrity: sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==} - engines: {node: '>= 4'} - dependencies: - domelementtype: 2.3.0 - dev: false - - /domhandler/4.3.1: - resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} - engines: {node: '>= 4'} - dependencies: - domelementtype: 2.3.0 - dev: false - - /domhandler/5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} - dependencies: - domelementtype: 2.3.0 - dev: false - - /domutils/2.8.0: - resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} - dependencies: - dom-serializer: 1.4.1 - domelementtype: 2.3.0 - domhandler: 4.3.1 - dev: false - - /domutils/3.0.1: - resolution: {integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==} - dependencies: - dom-serializer: 2.0.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - dev: false - /dotenv/16.0.0: resolution: {integrity: sha512-qD9WU0MPM4SWLPJy/r2Be+2WgQj8plChsyrCNQzW/0WjvcJQiKQJ9mH3ZgB3fxbUUxgc/11ZJ0Fi5KiimWGz2Q==} engines: {node: '>=12'} @@ -1623,20 +1522,11 @@ packages: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} dev: true - /entities/2.2.0: - resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} - dev: false - /entities/3.0.1: resolution: {integrity: sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==} engines: {node: '>=0.12'} dev: false - /entities/4.3.0: - resolution: {integrity: sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg==} - engines: {node: '>=0.12'} - dev: false - /es-abstract/1.20.0: resolution: {integrity: sha512-URbD8tgRthKD3YcC39vbvSDrX23upXnPcnGAjQfgxXF5ID75YcENawc9ZX/9iTP9ptUyfCLIxTTuMYoRfiOVKA==} engines: {node: '>= 0.4'} @@ -1683,11 +1573,6 @@ packages: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} - /escape-goat/3.0.0: - resolution: {integrity: sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw==} - engines: {node: '>=10'} - dev: false - /escape-string-regexp/1.0.5: resolution: {integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=} engines: {node: '>=0.8.0'} @@ -2219,24 +2104,6 @@ packages: dependencies: function-bind: 1.1.1 - /htmlparser2/4.1.0: - resolution: {integrity: sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==} - dependencies: - domelementtype: 2.3.0 - domhandler: 3.3.0 - domutils: 2.8.0 - entities: 2.2.0 - dev: false - - /htmlparser2/8.0.1: - resolution: {integrity: sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==} - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.0.1 - entities: 4.3.0 - dev: false - /ignore/5.2.0: resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} engines: {node: '>= 4'} @@ -2451,20 +2318,6 @@ packages: object.assign: 4.1.2 dev: true - /juice/8.0.0: - resolution: {integrity: sha512-LRCfXBOqI1wt+zYR/5xwDnf+ZyiJiDt44DGZaBSAVwZWyWv3BliaiGTLS6KCvadv3uw6XGiPPFcTfY7CdF7Z/Q==} - engines: {node: '>=10.0.0'} - hasBin: true - dependencies: - cheerio: 1.0.0-rc.11 - commander: 6.2.1 - mensch: 0.3.4 - slick: 1.12.2 - web-resource-inliner: 5.0.0 - transitivePeerDependencies: - - encoding - dev: false - /kind-of/6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} @@ -2591,10 +2444,6 @@ packages: resolution: {integrity: sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=} dev: false - /mensch/0.3.4: - resolution: {integrity: sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g==} - dev: false - /merge2/1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -2624,12 +2473,6 @@ packages: mime-db: 1.52.0 dev: false - /mime/2.6.0: - resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} - engines: {node: '>=4.0.0'} - hasBin: true - dev: false - /minimatch/3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: @@ -2718,18 +2561,6 @@ packages: - babel-plugin-macros dev: false - /node-fetch/2.6.7: - resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - dependencies: - whatwg-url: 5.0.0 - dev: false - /node-fetch/3.0.0-beta.9: resolution: {integrity: sha512-RdbZCEynH2tH46+tj0ua9caUHVWrd/RHnRfvly2EVdqGmI3ndS1Vn/xjm5KuGejDt2RNDQsVRLPNd2QPwcewVg==} engines: {node: ^10.17 || >=12.3} @@ -2753,12 +2584,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /nth-check/2.0.1: - resolution: {integrity: sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==} - dependencies: - boolbase: 1.0.0 - dev: false - /object-assign/4.1.1: resolution: {integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=} engines: {node: '>=0.10.0'} @@ -2865,19 +2690,6 @@ packages: callsites: 3.1.0 dev: true - /parse5-htmlparser2-tree-adapter/7.0.0: - resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} - dependencies: - domhandler: 5.0.3 - parse5: 7.0.0 - dev: false - - /parse5/7.0.0: - resolution: {integrity: sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==} - dependencies: - entities: 4.3.0 - dev: false - /path-exists/3.0.0: resolution: {integrity: sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=} engines: {node: '>=4'} @@ -3281,10 +3093,6 @@ packages: engines: {node: '>=8'} dev: true - /slick/1.12.2: - resolution: {integrity: sha1-vQSN23TefRymkV+qSldXCzVQwtc=} - dev: false - /sortablejs/1.15.0: resolution: {integrity: sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w==} dev: false @@ -3461,10 +3269,6 @@ packages: is-number: 7.0.0 dev: true - /tr46/0.0.3: - resolution: {integrity: sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=} - dev: false - /ts-interface-checker/0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} dev: true @@ -3482,10 +3286,6 @@ packages: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} dev: true - /tslib/2.4.0: - resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} - dev: false - /tsutils/3.21.0_typescript@4.6.4: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} @@ -3618,11 +3418,6 @@ packages: resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} dev: true - /valid-data-url/3.0.1: - resolution: {integrity: sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA==} - engines: {node: '>=10'} - dev: false - /w3c-keyname/2.2.4: resolution: {integrity: sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw==} dev: false @@ -3635,29 +3430,11 @@ packages: '@zxing/text-encoding': 0.9.0 dev: false - /web-resource-inliner/5.0.0: - resolution: {integrity: sha512-AIihwH+ZmdHfkJm7BjSXiEClVt4zUFqX4YlFAzjL13wLtDuUneSaFvDBTbdYRecs35SiU7iNKbMnN+++wVfb6A==} - engines: {node: '>=10.0.0'} - dependencies: - ansi-colors: 4.1.3 - escape-goat: 3.0.0 - htmlparser2: 4.1.0 - mime: 2.6.0 - node-fetch: 2.6.7 - valid-data-url: 3.0.1 - transitivePeerDependencies: - - encoding - dev: false - /web-streams-polyfill/3.2.1: resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} engines: {node: '>= 8'} dev: false - /webidl-conversions/3.0.1: - resolution: {integrity: sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=} - dev: false - /webpack-merge/5.8.0: resolution: {integrity: sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==} engines: {node: '>=10.0.0'} @@ -3670,13 +3447,6 @@ packages: resolution: {integrity: sha512-AMcUeyXAhbACL8S2hqqdqOLqvJ8ylmIbNwUIqQujRSouf4+eUFaXbG6F1Rbu+srlJMmxQWsiU7mOJi0nMBfM1g==} dev: false - /whatwg-url/5.0.0: - resolution: {integrity: sha1-lmRU6HZUYuN2RNNib2dCzotwll0=} - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - dev: false - /which-boxed-primitive/1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: diff --git a/src/css/main.css b/src/css/main.css index 35331088..d6949bd4 100644 --- a/src/css/main.css +++ b/src/css/main.css @@ -1,6 +1,5 @@ @import "./variables.css"; @import "./tailwind.css"; @import "./prose.css"; -@import "./prose-email.css"; @import "./code.css"; @import "./prism-dark.css"; diff --git a/src/css/prose-email.css b/src/css/prose-email.css deleted file mode 100644 index 136dc231..00000000 --- a/src/css/prose-email.css +++ /dev/null @@ -1,4 +0,0 @@ -.prose.prose-email .table-wrapper, -.prose.prose-email .code pre { - @apply -mx-0 md:-mx-0; -} diff --git a/src/css/prose.css b/src/css/prose.css index be557c3d..98e7f0ee 100644 --- a/src/css/prose.css +++ b/src/css/prose.css @@ -64,7 +64,7 @@ } .prose .table-wrapper { - @apply min-w-full md:rounded-xl text-sm my-7 -mx-5 md:-mx-8 whitespace-nowrap; + @apply min-w-full md:rounded-xl text-sm my-7 -mx-5 md:-mx-8 whitespace-nowrap overflow-auto; @apply shadow-md ring-1 ring-zinc-700 ring-opacity-10; } diff --git a/src/lib/mailgun.server.ts b/src/lib/mailgun.server.ts index 4f3db193..0389b03c 100644 --- a/src/lib/mailgun.server.ts +++ b/src/lib/mailgun.server.ts @@ -13,7 +13,8 @@ import { SubscribeFormData } from "./types" import { getSite } from "~/models/site.model" import { type Site } from "~/lib/db.server" import Iron from "@hapi/iron" -import { renderPageForEmail } from "~/models/page.model" +import mjml from "mjml" +import { getSiteLink } from "./helpers" const enableMailgun = Boolean(MAILGUN_APIKEY && MAILGUN_DOMAIN) @@ -99,7 +100,7 @@ export const sendLoginEmail = async (payload: { } export const sendEmailForNewPost = async (payload: { - post: { slug: string; title: string } + post: { slug: string; title: string; rendered: { contentHTML: string } } site: Site subscribers: { id: string; email: string }[] }) => { @@ -107,10 +108,37 @@ export const sendEmailForNewPost = async (payload: { const from = `${payload.site.name} ` const subject = `${payload.post.title} - ${payload.site.name}` - const html = await renderPageForEmail({ - pageSlug: payload.post.slug, - subdomain: payload.site.subdomain, - }) + const siteLink = getSiteLink({ subdomain: payload.site.subdomain }) + const html = ` + + View this post in browser + + +

${payload.post.title}

+ +
+ ${payload.post.rendered.contentHTML} +
+ + +

+ + Unsubscribe + +

+ +

+ + Published on Proselog + +

+ ` const recipientVariables: { [email in string]: { unsubscribeToken: string } diff --git a/src/lib/reserved-words.ts b/src/lib/reserved-words.ts index e8cc728a..9441bcf7 100644 --- a/src/lib/reserved-words.ts +++ b/src/lib/reserved-words.ts @@ -533,17 +533,7 @@ const words = [ "zlib", ] -export const EMAIL_TEMPLATE_SEGMENT = "__email_templates__" - -export const checkEmailTemplateSegment = (str: string) => { - if (str.includes(EMAIL_TEMPLATE_SEGMENT)) { - throw new Error(`${EMAIL_TEMPLATE_SEGMENT} is reserved`) - } -} - export const checkReservedWords = (word: string) => { - checkEmailTemplateSegment(word) - if (words.includes(word)) { throw new Error(`${word} is a reserved word`) } diff --git a/src/models/page.model.ts b/src/models/page.model.ts index 27bb4984..a3ce0438 100644 --- a/src/models/page.model.ts +++ b/src/models/page.model.ts @@ -14,9 +14,6 @@ import { PageVisibilityEnum } from "~/lib/types" import { isUUID } from "~/lib/uuid" import { getSite } from "./site.model" import { stripHTML } from "~/lib/utils" -import { getSiteLink } from "~/lib/helpers" -import juice from "juice" -import { checkEmailTemplateSegment } from "~/lib/reserved-words" const checkPageSlug = async ({ slug, @@ -31,8 +28,6 @@ const checkPageSlug = async ({ throw new Error("Missing page slug") } - checkEmailTemplateSegment(slug) - const page = await prismaPrimary.page.findFirst({ where: { siteId, @@ -360,36 +355,3 @@ export const notifySubscribersForNewPost = async ( console.error("failed to send email", error) }) } - -export const renderPageForEmail = async (input: { - pageSlug: string - subdomain: string -}) => { - const siteLink = getSiteLink({ - subdomain: input.subdomain, - }) - const url = `${siteLink}/__email_templates__/${input.pageSlug}` - const html = await fetch(url) - .then((res) => res.text()) - .then((html) => html.replace(/]*><\/script>/g, "")) - - const resultHTML = await new Promise((resolve, reject) => { - juice.juiceResources( - html, - { - webResources: { - scripts: false, - images: false, - svgs: false, - relativeTo: siteLink, - }, - }, - (err, result) => { - if (err) return reject(err) - resolve(result) - } - ) - }) - - return resultHTML -} diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx index 3f1ff9ff..62e7eb44 100644 --- a/src/pages/_document.tsx +++ b/src/pages/_document.tsx @@ -1,27 +1,19 @@ import { Html, Head, Main, NextScript, DocumentProps } from "next/document" -import { EMAIL_TEMPLATE_SEGMENT } from "~/lib/reserved-words" export default function Document(props: DocumentProps) { - const isEmailTemplate = props.dangerousAsPath.includes( - `/${EMAIL_TEMPLATE_SEGMENT}/` - ) return ( - {!isEmailTemplate && ( - <> - - - - - )} + + +
diff --git a/src/pages/_site/[site]/__email_templates__/[page].tsx b/src/pages/_site/[site]/__email_templates__/[page].tsx deleted file mode 100644 index ea391668..00000000 --- a/src/pages/_site/[site]/__email_templates__/[page].tsx +++ /dev/null @@ -1,84 +0,0 @@ -import { createSSGHelpers } from "@trpc/react/ssg" -import { InferGetServerSidePropsType } from "next" -import { PostAuthors } from "~/components/site/PostMeta" -import { UniLink } from "~/components/ui/UniLink" -import { SITE_URL } from "~/lib/env" -import { serverSidePropsHandler } from "~/lib/server-side-props" -import { getTRPCContext } from "~/lib/trpc.server" -import { appRouter } from "~/router" - -export const config = { - unstable_runtimeJS: false, - unstable_JsPreload: false, -} - -export const getServerSideProps = serverSidePropsHandler(async (ctx) => { - const domainOrSubdomain = ctx.params!.site as string - const pageSlug = ctx.params!.page as string - const trpcContext = await getTRPCContext(ctx) - const ssg = createSSGHelpers({ router: appRouter, ctx: trpcContext }) - const page = await ssg.fetchQuery("site.page", { - site: domainOrSubdomain, - page: pageSlug, - render: true, - includeAuthors: true, - }) - - return { - props: { - page, - }, - } -}) - -export default function PageEmailPreview({ - page, -}: InferGetServerSidePropsType) { - return ( -
-
- - - - - You can also view this post in browser - -
-

{page.title}

- -
- -
- ) -}