diff --git a/opensaas-sh/app_diff/.env.vault.diff b/opensaas-sh/app_diff/.env.vault.diff index 714c36b85..ee47573dc 100644 --- a/opensaas-sh/app_diff/.env.vault.diff +++ b/opensaas-sh/app_diff/.env.vault.diff @@ -7,20 +7,20 @@ +#/--------------------------------------------------/ + +# development -+DOTENV_VAULT_DEVELOPMENT="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" -+DOTENV_VAULT_DEVELOPMENT_VERSION=12 ++DOTENV_VAULT_DEVELOPMENT="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" ++DOTENV_VAULT_DEVELOPMENT_VERSION=13 + +# ci -+DOTENV_VAULT_CI="pveNDc605iqf5ZOh9mvYpFOc925852DGrvz7y+vs82ub3bZvTiLhJMuJKZEDtyjn7yBUdfMRsAP6wAL8/73te+4y7K56lT48MuvFlpvwM9ERkCzJY1yZ6ib3eBzTax/jon2H5kfEHBM9TRIa5B8JrCHbYqhcrnxj0VyLEa4x1I4pMTdesRZ+907FTdExaRSFFujdkUaScytOV93DTr2lQZpUGBga5CbKr3KyeSS1+ONGSWc+BQiAkdhmnvPsyKHnWRKHSFVhInne2W00LFZLBZ56I4+G7D+x+ze3/WNb5GSq7eNlVwnTJgj5AXJBjtAV/uD7cmOnJ3h+lOkvz3Wry10BaICTAx5SVfOuD5Pr/FLgR2zJau+pgqhRdcp7gG4y2thWN5ZtlLGnJlL7xgnRaD+oIYBn6fg8CCZsnsX2XZHAzJcgntph2pUd0At4UawSijDVZuylcneNdF3CJ68/fcqqpR94LYU61w4WasrAWj1hFiRV1MTpLkdQWTMT6K5k5TDouuljI3nt+Upf9mDK7efjy7OTiiArNxKpUxUy31Kl0TgWTsttDFbcOGwbsxq1t/Tu9Ph0eEhwHc2dTUuSuhV+PHxE8GwUvGiIDBbAZZq7ZyeLc5btdP++8zdXBtYM7bIa9qubaCWakruk31w6Gm5ySjGY+R1HGURldXJmypsAEcu5kK3IX4Z8IubF79T8ZvutLdoXJPSaH9x8ij7EcamTVfZPmekj6FpI3sqy7rmaUup73MBld9a3r9AQTzXbEmR+2xbK488D1il8PUqu9J3QkUeF2rpB97Uy2mgl1zF8VXiGkdP1Hpqeck8FpS89GWFF4FA3oBE/Keqvqvvs/f+KzDn2AvHHwrT6fnVBdeuSp4hK+sSkig1rh+1P69zYjIDqpph0kT+Ri7uNMkbrXX7iT5he9J1LrXtiM/DLxXqi8M3FfeN7aaSxQ2nzac1mlN+vwsIqJbzOSm+ABGHNJNjPjBZpMbeBZsFwogaCbFd2oorp02h6yC6741qwH7gFEr1EJVcu+TJspHyKpq4TFIk+srRMhuCqwUAkdzY4skjEGVhxxYMiKAtRg5IKYICqbfNsestMipAcf22teriGnmqBe9Yuzq9IXZXRcl/etagr0/B3SQhNlVj2u9VMBfhj5ZY+QcQDfSjqOcW/DyphyBU4T1/rHn1x5RznCvtbOPZ+XXFApZaeoKzj/s8JxHzM8aegITx3jVRwXnr0/0FnHTnC34b124K6HM3oKxdPdrtACgW8gH+mgXCaStBqwBdk1aV62+YQxWdHXjy9FAvTF8BktcxwE0TXC5Qu0JsoS8uYbbQmaQCNWIJWF/KptW+g9gkKDBV2Iq5mXwMLHzCtzxGarj5jqznVEX4OdbYbgSOZ5mB5JEU2OwSn2QtzqUVquAN+DygbDVrh1+KA9bk4HMt38rMKHV/i9VBHkuApYT7OUIexCu4jxUDBnid/Hnm3OfMvXrUesoqFv2cYEHX8R/jvhLx36jEWeaTYL+e9XFpSLlWJTGc7wAg0Zj+XJlNtLhFlB6pw" -+DOTENV_VAULT_CI_VERSION=8 ++DOTENV_VAULT_CI="XGJ7HhbwC6C7beVXbifG+tkHOTHTPNHoECye25INPUQmK9vxQ9RObeQjfhLGd2Qkj1bsHDU3VGEjuReB7OxZ7YSFF1xaFoVPdm4x+Rwlr/vbVEy0t4JeUGYA54aNPQYaQBmCF0QVKSI0l7O+WWX7Th62nGyDYwwVOs4PIXwGf1Zr+mtmmJSOuJT8jPQdTfFTKVi/ntWrxl3CBsflW4xQIWsvnoHyDy161gg/HNmmnmdqDYK+roUBokBc1X2rBoSI+vmUUAg+M0rejg8HBs8ZKFDDBXPYOrcnQR306VYrVZjoS0HaA1pZNROXbUaUS2lxl74mP1vD3nV5oQ79coPc9FcwrIMBpv3V7gjdHSM/D/Scf3Wkq+nkk0YsysebRg3qBv/pOy5zb53+NF2AfHZ2drcW4X5QZng6haCqwaDuBDBetro9NECTuMTxuVR8Qfd+NlCXP9RVxhmVMETBYbABSzj2uXKPfCtc2QbtJULXtdO7BkW2ED7c40MGO2NDdEbv8NzqwPqPzpVjtw86YrzHH1y0pgfoEzGPXv6A9QQlt2Ns2EPHjPM87swrTuOGr/xHfpm/j6X8+kB4GwsJehes+BELT6UM9+maPExap/qh1c4WKCwrUYxLD82nixmzxARsqyqJYIoD57AzPeWeqwrxy2nNmKuN/xuau7u/mZqbXwpbE0RIs2zbREZazHDiD8GOL/kXAYhGOQABXrTpl6mFsNVU0OPWE6VkxA90YNxG0kTIBHYaOd2IbPDxPFYbtIGZNCYTn50+7JwPfl56fbVAM5mbvTGaQPo/74H92E3akWFBCA2Wa1yUn1jhfoYzGYrRj+CBCtJLpZI/JIfsVeKdVZ+3/osTb2UdN7humZlrpKzrFqcIKCsbYB2Y55R+LrbuQzbqKl7JUT/y0obboa6jBtO2VFzsF1cJDh3UCCQ2BdBXu5KYhk8BdM1SKWN/p+kteGSgdOuxs9dZW/z/p2Ycjd1cNZjDahN4Ye5HBtiNEXuej7o7SaF5BQC/fqQpSqvVKacxkNL+0X/UR+HUJE1t8d8jEwfT9WE0zxjnraDVxMbC6EHbPV44hUoYyclaKraSAgpaZuW0dkikWrTbyl8SMJPGsD5WZU5gps9i9SfY7y6R2Ruc7vxPRRYb25NTZap6L+hkWeXVM50tKDCIs6cWFHNF7oW9oF72WdZVziWm7kWX7Q0BjNT76od+CMD9tyHo48qSEmYed22cXCMV+dIsQtXwz8y0S8xuaBs1dHsHcEnF6sOGFsRlLaYbXbJiBOFqzqW2iKFdu/CMEJ8qmssxpKQfyy93mOSragacJ3D6iVbTvDaHZ+KbFtIdk+w368MaA/9xEvvdkDJX+u+wqA13SpXkOr2T0Czip1h8fiEw41Jc5cGmMLZyPo1d9dDnc9vyFtfDxGZxQ38BpEmDZcy21cM57TuhLmlZ0U15aiD122rZfdWGkKjtG2854MEJDoLVZRZHhxpSqdhEKRHCgFvhjHYU/FjjaBSGu0g5lOzbc3V/Un8U9Ix5KwMx+VAahGAF2pLaYRmNof3IXTzJC9xPwj+IsO7jTPtsBuJFjSjG" ++DOTENV_VAULT_CI_VERSION=9 + +# staging -+DOTENV_VAULT_STAGING="nAXVAHQaoF1R6J23PDrfp6kH0L+nXmZaI0OUfcCBU7QSfP+K3mbkdO92cbKVUN6ycc1wxRue6BFLEUgBLuCJQwUdKYevK81fs/ACrHYxuW6Px85FG3NJVLGvgF/3qiqu0RRfcpeB6lYJCAPFsYcoA9Cx8QDkYmvSlWAGmLJQ7cqzHUNlveOqtrXsLFV2OjlWjlYD1l7VQkaXnsY+Mij60DbRIadusoDuAB3z5m7N8/ogMOGENlUl9HRJJ4ppcJiHoBm7pxrLpK0oubx3KEDTSkPVlpNb1YYMeU2VKiGYCOMyXX8IguISrrgU4hHEvbLM8F3gnKHyx59qbwU/32yX7ofIIPsTLLTwD+mHWElPoLs9WWq249RYEmRT7w5iuCdjl9Qlr36EJKPYc7UG+P0DZROb7pXcbtYg8/gfaCXOQG5Ue2FMon4bEphkmY1CKaJKtPTXNuecDVTa8O4hEM65xrEClieVUgexEaM0g7fEUo8wOljZx96gG8Mf4RqHX3xy4M0d4/2UluE053kavUaTULhRPG/oTHIGiKFRnG0BfgQFcGRXkFgLG9zerVAoWEGAcBGHn5NECIUWqaD2Z7sdEZd9R0SZmtwUXoPV1jqHNeKEvt7fUN8xcPsV1MFAUi2cAyGLkrl541KbWpU0IpHK1pIkbfUVyDOL4htSD/SajhtlyJ79q7Xd5sKsb273ZQsmtk3ZREBjQUFA2NP+fPH7ifttVeWi3EFUi8+8cWwgNHM6Cn7LaFitah6+DcCQ6+l7SneFTEbzMlprzazBBL/Gu4kr6pNXGX0RZnR8uhs6aZZgV2h9V14s0uZx3EcAFqC3g+I5X08Fi+2ERpcfWUvFdjx5akmDQllSB+oqy6SxiJvqFnfWvVPQNhx1xh2x8OplZbzykEJ+Tfl0mlc5UHHoLQqje0jagBRSHWQbxC0jIGGyqdhnz3uG672krM/zTTc2wKWMk4EZFDG7Yc7oz3DcJXjFBgxEagd9jYxqLIN0RAH9pq+0aUP7daz0CbX+xhTd988dl+LblcnEN59XEsBOhWCd5bm51KJZcKQ1UpsVVPGHnTT7MPE2+6BheEr1dgu/LDUPDW8NT0QwBUwXwxH1ROuTOu2+LWNdFrV11sEpKGfW2bjqrkpbx/xovahbFyCSq12T0EBInAFF5bq2pB0Ik2vfEH8gNL0Z+FoqH0/aDrSuw6j8xqmd2rKL3XwL5bYVZDCc1isAWXESA9CHHTSx1NGoa1kpunJkGJY//2rn5srK9RlOOHxxUrtqVBMfEGsj7qIv/Ebsgr3dvFpdVXiRZ5s3KZZs6YlSXyukklehkjtYoMM2TaZ478ioFOtD8yx12PjI3Pfoapo2La2boM48RFcipmVNpWNsLjGXaYyhYVV3RBsZAMvkOnYRVFUiZ50+ETdfizX0H23+mmkBt8FjNqHhvg9BIRaYnKTar1FPAd840lo4w2e7n2mKufHwykI5ILrJV0ozhPy7Yr8kltPiQYjpy1ua2scUdnKCngdX0KjqNQz072e6uYlhRpOib6CEwZXqMbr/" -+DOTENV_VAULT_STAGING_VERSION=8 ++DOTENV_VAULT_STAGING="YrzhnLjbj2iFnQUJpisMUL3I0Z0xD/45ZCpyo6N73EcX4465FwJ5sVw9nGjq/+UIxPJKvEk4ibq907PIPAHkSY3+j+Dsx3aydlokbgmv2X1OjVK4QmoCmwYRHBChTgbIkDlwhbjxbiiRiu6S8lQmFrDe4DcstI4gtp6x5PbdNKbYIKrDU+iXgLh8vlul6emavsloUKAyAf/5yaobAyQSJFkEDOmHdHiFGnwkxJeuwn3BCyPZ16mg3vx7BmpVdNSbk1coQ2HTsYPfoZsKZKzc/Oon+qo/FSQ7+fyp+8+CJvpINUm9Xkn40kN1IBVJ3ZZowdJ4rYPW2Uz0oD0bLGv6jjZVAD0z8HVOpBbcaqfEwWx9b6NJ1j7xg2GiZ6321V93D14LJL6KT/Sl4391j8CUhEKTEXCNtKMchyJyo+N/hlE3BAk2Yv3llw2YW4w9FSxecbuKni2ZlH6AGGupEv3VNzrlFhyvoBKQlFbLSnrEMIlUJ0Bo0KhQF6lBlJUdBiR4KsO+8WBbj7qn25rlDp++XBshivWf08NpzMB1+fHQ05QS+gwYeLtnhD8VxvCm3nHpHPCw2zZrhWZQ7Z1n7hA2qxknp/Hhs4agY3I7ZmeGDGYwAID8RcVGGyqE7VU8eu7x1OWqrDbtCzWRgeoHG1yB2upUQ3taKyyvUdeh4bwDXp5M0ZOsh+0+X4ZphEV81s4D0ABVifp9eu+PUob/kJATutNWNCsgysO8nzryACKAXb4WOHItw5DuNdd2L4y9gWcOC5Ecf44NEhO4Zr/E9TXNSavQR0SiTTsCRodAIG0k1VDJnzdV/GI7dXGcnx/pI92bAD8Evubh3oxROCwuyIb0ch6foQA/wjygujHn6wZq+TyQVrhklzKMcxiBtifkDVL9ROjQ4nJ3eOzZ6P5pLb+s42DlS/SD94XnqCSLmnh2Nok5FhMWVI3PZN76xcqvC/+0ctwMiS04dcefvBb6Aegyyp9MoDnG2z5BwsGi2YY1mj3U3baDEeMRc4WF6y+Ac9BC7LvgMgA0W8lODRuChRBfEx9Z6qBhJAhHwBUdERg9Nm3maQU1rsBMmSQ7rt6DyEc4b0HWJdy9UMq6Q33wTdCihPBhMxZPEF6x6k8Y0jcfyzu5JWIH08QtiP0CYwA6dke3E7grS9GxHkRW/AZmCuLNSuKpwLLb6f1Y+pSIaeyI8k6jhuWoN8kLaaCgHBt+eo3jL/0A4fjaSdjYCCbJgDIBdW4Ku8PcxocKymvPd4IBhRjXQiKdmL6wjYQqaz7pCEyxkq0n8Z2h8CnnjuaUUU710keHI/MnfvlUGtSyjFHIwS4RGpU8F/Y9KTvGKpbjGpvWK6+Gie959VR1u/NdgM4mlgJOzI8xqSm8jfNL5eUegnGqor4CbWrn1vECEqbcBaGI5Lzw/0T6zrEErV6QDdihMjJE9ouBEihUtoesRKd3q9zza/4AlLb/a/kulVX33N4VNSxaidEYat6H09S0qUDxcWD92GxHuxxhMU9X0U+YrswMXzUwGEkDd2Hp4IPqsJ6tG1lORgHV2JLoTeQmPob5fzokIapakE+g78MiWlgn" ++DOTENV_VAULT_STAGING_VERSION=9 + +# production -+DOTENV_VAULT_PRODUCTION="zGpYx7O6vRv3vYt0aW1H6UF3TSi6DUFgqjeKzkNcJukFWQWvTgX5HYtLKQnBAGCDpuWY+KWfiFGNu/zVouo5LTlQb6apzBLzj0dr+PxxDpjXe8s+q7OSPH7Ist4UiVurC2nAMjgFsUpDA2LUkfPOuWPRvg1UGYjTaxEADTYCI/vk0Uegv4R11K1/HcCGXlliJk2QAVaT5ZYSo0VKvcRu5HYHSX4aAwJgnucm3xvNmPn9Cjkxx1jZL5jYfzLS1etDEPn6slDj88NzZ8BvXHeSJUftpR352azOJpL0GbSKrwoPNYU9F2JCthilLqPZPC6LJzg0/4p5vUKA83gqnDnUxEHR+ZlNK0MRTQPEwrZitruOaP1ggWIsEJA/DZFMLA5oQrq4kp+p2E99YbsPNmV0LfvsA6LtqKv393jsuzSdJ94zeLhQlRRECiTQRVEee3ug5tJ0f34N7acRSv4EdgriKp8poIsE4miVK2xXwrek9jRxeXLHzu7Oo8yBkYaX2DqtXyxf+8Qq2WgvdRm9QgfGdiwftYsjXO52jhHI7z7bJ3R/W5BR+Z0QbR83LR3ZWdI+AYY9F2CkYF62nW5TVxiWU0M4DZ5KUgVo+iNgm+AV0nefgFvud6Ln3VtNcb2bT0RFAw4MJK0LyYlNewZBJQhlfRiN+3xJKqLbDKMlhGmSHF8RRNYN9MfKwOfF62jNFlwPjgyGCjuQL96L97z50Q63TMbpEciR0uNcMavIADPs1qDhCSkYO4rQO1IgOUF34trra9KKRfoP2UdDJhiqvlTQ2Ygu2uc164Vho0E003jlBBZBI+UUJhPz4cYTtFJjpinRCp/Q0mUeiTLbo1V7T32IQ+ZkUqO7FRuwxR282OzKQVRZiUxuOAa7WxdQzrcXbCOcCvJWX8hTVrSim9z+NAFxNyTCwVBhek9EfwCfxJSCuFuI9axlb6xA1sZ/61G5+wuKeEpUvlTbQC/ZT1QJqpKMmujEePAfW++dzJJgW/nX9o0CIt3KTzwVzImAe+/oNhzKn0TbzsvMqeOaTgymo2re0Rdw3P/Fk5SUQTM7+2GIFC+iRC5a3LN7UOFP+UdQ21J+WGkkl+yvJyyjY3IRSoFWqSCU7BAjULmJmtkl1Y/60vIj+GET5hu7VGaTlIgaWiVZc4eGAu6UAeGzasTjYWNQh50p44VxQlYBijJC+JUhzPkFOLjaLx6rRZzTQVl9NUxIxdkaOn+BImJQadaC2Ad3YOMpsLVJF/p25fi2L2e2MtsDdcx2ZNlpV1GIrYGqMIiujPdpoMzibj4VmObVMB6dazpyqgAf/QXdGguyv/4JJBcNUNPbqHqMl0yY+DzGzxPCKx6WViR63HZJeC5hJE39wNEgeYGJcXrL5K2siwrFENns8Os93aoE/8xgiPdj3vLQmcL0Z30XEqPl6/V4mTgc2Oa1SAi1NGLXnVsYJ/h1Rr4a9T11zkKhRCIvT4Jd5WpvGjG3f9t7YUigb6BqlMc0BTJ6ufQP/xBBOHqzoUs3gVk4HTMDfpYwO9k9SJNkfWBn1iV102BJ" -+DOTENV_VAULT_PRODUCTION_VERSION=8 ++DOTENV_VAULT_PRODUCTION="nwpPZ519tEw+H7zTYMlCASEl+aTG5sDW2aUPGzKkE595ORAtfhxrx+jpiWRFruCKX1SIbIjb6uFWcQXVO0nBcgIT69gDygY7vE5SjXe/KLyWiySsJ3gcpiuk3m/qSiYasEjOR8tKOdQji6omwCn8oYpK9K/joO9XE7U+HyVzqSMkuwrW2Gawnr/qmIcQRQFj03+Lm++2V/oDEbpFLW8JCO2TZUc62iJsKNV2g7AemTGb7O3b/rb1QuoXVikUVh+PhBRzIXSIrsEHevEV94fV9uozZ5EvBrEIUao8XH6o/qiuOUcbp2i8Nzdo0jKA0kxh7hPFJQHmfk7on5wJKW2PHXWLb0k+/gbDG23vnkU5ndunZvjRnMZg0w30qmA9z0kMus3qCHcKp88dVaFDyIyUBv/PoFrRJPSX8alOL2HWqr9gqGc/TvcLwNwEkM5IZFBNpC8Xj/ka/RNxabS9YnSMYCGe080los5juy46rNw6qSVf6LTPUCoO5KMi3WeeM0eGCoM8wFZQEZS8J6FHMSXQbjg4X2k71wq6DNhnMleG7qQHXECxKRPnnrveJdowAulRlHhVISqRRnMLQZ59PXw5dKg8jucwsaARvgNQvRf/6A/I6+FenX83Rej+hmpXaWR/NCSC/WMxbnRhdAKplv6G9pdKAz4pI3n+hNP+WNPeAnlVSdxGeWNGh9ndYOGzCG0om7McBu2h0NjzrViHlMz6WbY1UfCruJ9zRjlpu5LXQv77C52NSVPrkk0lMX0FrwvCM3qTwu56VYQ7/A9+ZEfi2X7iKXGBjzavVmncPDLy8M9QhA9A8mqzAlBRxnqM2xr4B16f2uKQyp2KQt43kNmfhUkFPNcyp5hrSFMKkHA85q9uemoDYNgC+09/0hkH1dcg6NoKGf18PZl3dKstOIBSQhU4tU0IyL6ZY6PKveMotuJxA0i15I/ClRbpffhfEL0vbWuBTfdh9J0qmvNJoHtPiZlLpojBvCpIKLkf5bHj8Ucg/EReJ7Rc1830N2cEj5YROH8YV7C4Lox8yPicjXlUk9OsvyKXOSXrWpdsUFKtWc2OVvI53OgrWp8Ct1kqTAxRTT9Dzp/PPKVapirulDa18DLL6qVu7elapRU+9wXB5bmwbtam75l6KK77EVsP9WVVuBY6ciiTWoCKDf1Y5tYo4rb/yABQzybcfBVl9dSz5smGZh1Lp3/HeOekCASJZ95WjGt2cBd6PeIjambljFrp+n0oUiDOdOVi5Wp0j6P8NkO5s7W+QzrnQJSlaN0M5iYhXz3VKo8gnTyrw0+iJ7xQBVFgDhzkfsG4YurbiUdOEcpMBvnxACMhlUl5mq6srh+QJSjUPJEviLXB3sk2Ok0JI/UkDq+CwpRtLdpdhNV1Tq12XjjCeB8uNpJt5zUWENnH4BVDHsSmheFczJ45zibCDI2pA7H4IwAgbDEUgvITHj8aBwhvXkAso+nte6GUQrv1Hy9qitpAmGTP0VZXsd7ZWa+kJjT3kJHYbgd8O10Tx+qu9lZ5Fx94wgIATdX7ey5G7D8rVNAsd8IL9PPgYyPcwNTsdmj9ms83pjmWL3FX" ++DOTENV_VAULT_PRODUCTION_VERSION=9 + +#/----------------settings/metadata-----------------/ +DOTENV_VAULT="vlt_47e3eeb0730e831e688049600e59f8975260a1f00302ae08684ed87ba67872d0" diff --git a/opensaas-sh/app_diff/main.wasp.diff b/opensaas-sh/app_diff/main.wasp.diff index 826d36a94..48d953476 100644 --- a/opensaas-sh/app_diff/main.wasp.diff +++ b/opensaas-sh/app_diff/main.wasp.diff @@ -106,7 +106,19 @@ }, }, } -@@ -207,9 +205,9 @@ +@@ -101,6 +99,11 @@ + component: import LandingPage from "@src/landing-page/LandingPage" + } + ++query getGithubRoadmap { ++ fn: import { getGithubRoadmap } from "@src/landing-page/operations", ++ entities: [] ++} ++ + //#region Auth Pages + route LoginRoute { path: "/login", to: LoginPage } + page LoginPage { +@@ -207,9 +210,9 @@ } api paymentsWebhook { @@ -118,7 +130,7 @@ httpRoute: (POST, "/payments-webhook") } //#endregion -@@ -245,6 +243,17 @@ +@@ -245,6 +248,17 @@ fn: import { deleteFile } from "@src/file-upload/operations", entities: [User, File] } @@ -136,7 +148,7 @@ //#endregion //#region Analytics -@@ -291,7 +300,6 @@ +@@ -291,7 +305,6 @@ component: import AdminCalendar from "@src/admin/elements/calendar/CalendarPage" } diff --git a/opensaas-sh/app_diff/package-lock.json.diff b/opensaas-sh/app_diff/package-lock.json.diff index 2c9374ae6..ba5c8408e 100644 --- a/opensaas-sh/app_diff/package-lock.json.diff +++ b/opensaas-sh/app_diff/package-lock.json.diff @@ -1,6 +1,6 @@ --- template/app/package-lock.json +++ opensaas-sh/app/package-lock.json -@@ -0,0 +1,14527 @@ +@@ -0,0 +1,15497 @@ +{ + "name": "opensaas", + "lockfileVersion": 3, @@ -8,6 +8,10 @@ + "packages": { + "": { + "name": "opensaas", ++ "workspaces": [ ++ ".wasp/build/*", ++ ".wasp/out/*" ++ ], + "dependencies": { + "@aws-sdk/client-s3": "^3.523.0", + "@aws-sdk/s3-presigned-post": "^3.750.0", @@ -89,7 +93,7 @@ + "react-hook-form": "^7.45.4", + "react-router-dom": "^6.26.2", + "superjson": "^2.2.1", -+ "tailwindcss": "^3.2.7", ++ "tailwindcss": "^3.4.17", + "vitest": "^1.2.1", + "zod": "^3.23.8" + }, @@ -101,6 +105,72 @@ + "@tanstack/react-query": "~4.41.0" + } + }, ++ ".wasp/out/server": { ++ "name": "@wasp.sh/generated-server-dev", ++ "version": "0.0.0", ++ "dependencies": { ++ "cookie-parser": "~1.4.6", ++ "cors": "^2.8.5", ++ "dotenv": "^16.0.2", ++ "express": "~5.1.0", ++ "helmet": "^6.0.0", ++ "morgan": "~1.10.0", ++ "superjson": "^2.2.1" ++ }, ++ "devDependencies": { ++ "@rollup/plugin-node-resolve": "^16.0.0", ++ "@tsconfig/node22": "latest", ++ "@types/cors": "^2.8.5", ++ "@types/express": "^5.0.0", ++ "@types/express-serve-static-core": "^5.0.0", ++ "@types/node": "^22.0.0", ++ "nodemon": "^2.0.19", ++ "rollup": "^4.9.6", ++ "rollup-plugin-esbuild": "^6.1.1", ++ "typescript": "5.8.2" ++ }, ++ "engines": { ++ "node": ">=22.12.0" ++ } ++ }, ++ ".wasp/out/server/node_modules/@types/node": { ++ "version": "22.19.1", ++ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.1.tgz", ++ "integrity": "sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "undici-types": "~6.21.0" ++ } ++ }, ++ ".wasp/out/server/node_modules/undici-types": { ++ "version": "6.21.0", ++ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", ++ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", ++ "dev": true, ++ "license": "MIT" ++ }, ++ ".wasp/out/web-app": { ++ "name": "@wasp.sh/generated-webapp-dev", ++ "version": "0.0.0", ++ "dependencies": { ++ "@tanstack/react-query": "~4.41.0", ++ "axios": "^1.4.0", ++ "react": "^18.2.0", ++ "react-dom": "^18.2.0", ++ "react-router-dom": "^6.26.2" ++ }, ++ "devDependencies": { ++ "@tsconfig/vite-react": "^7.0.0", ++ "@types/react": "^18.0.37", ++ "@types/react-dom": "^18.0.11", ++ "@vitejs/plugin-react": "^4.7.0", ++ "typescript": "5.8.2" ++ }, ++ "engines": { ++ "node": ">=22.12.0" ++ } ++ }, + "node_modules/@adobe/css-tools": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", @@ -1054,15 +1124,234 @@ + "node": ">=6.9.0" + } + }, ++ "node_modules/@babel/compat-data": { ++ "version": "7.28.5", ++ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", ++ "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", ++ "dev": true, ++ "license": "MIT", ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/core": { ++ "version": "7.28.5", ++ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", ++ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@babel/code-frame": "^7.27.1", ++ "@babel/generator": "^7.28.5", ++ "@babel/helper-compilation-targets": "^7.27.2", ++ "@babel/helper-module-transforms": "^7.28.3", ++ "@babel/helpers": "^7.28.4", ++ "@babel/parser": "^7.28.5", ++ "@babel/template": "^7.27.2", ++ "@babel/traverse": "^7.28.5", ++ "@babel/types": "^7.28.5", ++ "@jridgewell/remapping": "^2.3.5", ++ "convert-source-map": "^2.0.0", ++ "debug": "^4.1.0", ++ "gensync": "^1.0.0-beta.2", ++ "json5": "^2.2.3", ++ "semver": "^6.3.1" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/babel" ++ } ++ }, ++ "node_modules/@babel/generator": { ++ "version": "7.28.5", ++ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", ++ "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@babel/parser": "^7.28.5", ++ "@babel/types": "^7.28.5", ++ "@jridgewell/gen-mapping": "^0.3.12", ++ "@jridgewell/trace-mapping": "^0.3.28", ++ "jsesc": "^3.0.2" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/helper-compilation-targets": { ++ "version": "7.27.2", ++ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", ++ "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@babel/compat-data": "^7.27.2", ++ "@babel/helper-validator-option": "^7.27.1", ++ "browserslist": "^4.24.0", ++ "lru-cache": "^5.1.1", ++ "semver": "^6.3.1" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { ++ "version": "5.1.1", ++ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", ++ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", ++ "dev": true, ++ "license": "ISC", ++ "dependencies": { ++ "yallist": "^3.0.2" ++ } ++ }, ++ "node_modules/@babel/helper-globals": { ++ "version": "7.28.0", ++ "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", ++ "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", ++ "dev": true, ++ "license": "MIT", ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/helper-module-imports": { ++ "version": "7.27.1", ++ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", ++ "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@babel/traverse": "^7.27.1", ++ "@babel/types": "^7.27.1" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/helper-module-transforms": { ++ "version": "7.28.3", ++ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", ++ "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@babel/helper-module-imports": "^7.27.1", ++ "@babel/helper-validator-identifier": "^7.27.1", ++ "@babel/traverse": "^7.28.3" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ }, ++ "peerDependencies": { ++ "@babel/core": "^7.0.0" ++ } ++ }, ++ "node_modules/@babel/helper-plugin-utils": { ++ "version": "7.27.1", ++ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", ++ "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", ++ "dev": true, ++ "license": "MIT", ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/helper-string-parser": { ++ "version": "7.27.1", ++ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", ++ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", ++ "dev": true, ++ "license": "MIT", ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, + "node_modules/@babel/helper-validator-identifier": { ++ "version": "7.28.5", ++ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", ++ "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", ++ "license": "MIT", ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", -+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", -+ "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", ++ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", ++ "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", ++ "dev": true, ++ "license": "MIT", ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/helpers": { ++ "version": "7.28.4", ++ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", ++ "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", ++ "dev": true, + "license": "MIT", ++ "dependencies": { ++ "@babel/template": "^7.27.2", ++ "@babel/types": "^7.28.4" ++ }, + "engines": { + "node": ">=6.9.0" + } + }, ++ "node_modules/@babel/parser": { ++ "version": "7.28.5", ++ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", ++ "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@babel/types": "^7.28.5" ++ }, ++ "bin": { ++ "parser": "bin/babel-parser.js" ++ }, ++ "engines": { ++ "node": ">=6.0.0" ++ } ++ }, ++ "node_modules/@babel/plugin-transform-react-jsx-self": { ++ "version": "7.27.1", ++ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", ++ "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@babel/helper-plugin-utils": "^7.27.1" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ }, ++ "peerDependencies": { ++ "@babel/core": "^7.0.0-0" ++ } ++ }, ++ "node_modules/@babel/plugin-transform-react-jsx-source": { ++ "version": "7.27.1", ++ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", ++ "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@babel/helper-plugin-utils": "^7.27.1" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ }, ++ "peerDependencies": { ++ "@babel/core": "^7.0.0-0" ++ } ++ }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", @@ -1072,6 +1361,54 @@ + "node": ">=6.9.0" + } + }, ++ "node_modules/@babel/template": { ++ "version": "7.27.2", ++ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", ++ "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@babel/code-frame": "^7.27.1", ++ "@babel/parser": "^7.27.2", ++ "@babel/types": "^7.27.1" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/traverse": { ++ "version": "7.28.5", ++ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", ++ "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@babel/code-frame": "^7.27.1", ++ "@babel/generator": "^7.28.5", ++ "@babel/helper-globals": "^7.28.0", ++ "@babel/parser": "^7.28.5", ++ "@babel/template": "^7.27.2", ++ "@babel/types": "^7.28.5", ++ "debug": "^4.3.1" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, ++ "node_modules/@babel/types": { ++ "version": "7.28.5", ++ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", ++ "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@babel/helper-string-parser": "^7.27.1", ++ "@babel/helper-validator-identifier": "^7.28.5" ++ }, ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, + "node_modules/@emnapi/core": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.5.0.tgz", @@ -1766,6 +2103,17 @@ + "@jridgewell/trace-mapping": "^0.3.24" + } + }, ++ "node_modules/@jridgewell/remapping": { ++ "version": "2.3.5", ++ "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", ++ "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@jridgewell/gen-mapping": "^0.3.5", ++ "@jridgewell/trace-mapping": "^0.3.24" ++ } ++ }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", @@ -4243,6 +4591,81 @@ + "node": ">=14.0.0" + } + }, ++ "node_modules/@rolldown/pluginutils": { ++ "version": "1.0.0-beta.27", ++ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", ++ "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", ++ "dev": true, ++ "license": "MIT" ++ }, ++ "node_modules/@rollup/plugin-node-resolve": { ++ "version": "16.0.3", ++ "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.3.tgz", ++ "integrity": "sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@rollup/pluginutils": "^5.0.1", ++ "@types/resolve": "1.20.2", ++ "deepmerge": "^4.2.2", ++ "is-module": "^1.0.0", ++ "resolve": "^1.22.1" ++ }, ++ "engines": { ++ "node": ">=14.0.0" ++ }, ++ "peerDependencies": { ++ "rollup": "^2.78.0||^3.0.0||^4.0.0" ++ }, ++ "peerDependenciesMeta": { ++ "rollup": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@rollup/pluginutils": { ++ "version": "5.3.0", ++ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", ++ "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@types/estree": "^1.0.0", ++ "estree-walker": "^2.0.2", ++ "picomatch": "^4.0.2" ++ }, ++ "engines": { ++ "node": ">=14.0.0" ++ }, ++ "peerDependencies": { ++ "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" ++ }, ++ "peerDependenciesMeta": { ++ "rollup": { ++ "optional": true ++ } ++ } ++ }, ++ "node_modules/@rollup/pluginutils/node_modules/estree-walker": { ++ "version": "2.0.2", ++ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", ++ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", ++ "dev": true, ++ "license": "MIT" ++ }, ++ "node_modules/@rollup/pluginutils/node_modules/picomatch": { ++ "version": "4.0.3", ++ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", ++ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", ++ "dev": true, ++ "license": "MIT", ++ "engines": { ++ "node": ">=12" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/jonschlinkert" ++ } ++ }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz", @@ -5348,7 +5771,6 @@ + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.41.0.tgz", + "integrity": "sha512-193R4Jp9hjvlij6LryxrB5Mpbffd2L9PeWh3KlIy/hJV4SkBOfiQZ+jc5qAZLDCrdbkA5FjGj+UoDYw6TcNnyA==", + "license": "MIT", -+ "peer": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" @@ -5359,7 +5781,6 @@ + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.41.0.tgz", + "integrity": "sha512-4/euCZAv8zeaB5P/nQiySzB0JHM3tiraU9KjSvSlJAX7oIE9uPDZlHCkDg/bHYNXewzvsg0FtOMq0VUq8XMMOQ==", + "license": "MIT", -+ "peer": true, + "dependencies": { + "@tanstack/query-core": "4.41.0", + "use-sync-external-store": "^1.2.0" @@ -5462,6 +5883,20 @@ + "node": ">= 10" + } + }, ++ "node_modules/@tsconfig/node22": { ++ "version": "22.0.5", ++ "resolved": "https://registry.npmjs.org/@tsconfig/node22/-/node22-22.0.5.tgz", ++ "integrity": "sha512-hLf2ld+sYN/BtOJjHUWOk568dvjFQkHnLNa6zce25GIH+vxKfvTgm3qpaH6ToF5tu/NN0IH66s+Bb5wElHrLcw==", ++ "dev": true, ++ "license": "MIT" ++ }, ++ "node_modules/@tsconfig/vite-react": { ++ "version": "7.0.2", ++ "resolved": "https://registry.npmjs.org/@tsconfig/vite-react/-/vite-react-7.0.2.tgz", ++ "integrity": "sha512-lEj4y5SPRcH+bjw0tyuxrEnPqQUwfQzBKgd1YamD9xyet9zLwh2gwy5F8w/Nxg5DjdgYVjjKo5aLJUf0BTDz4w==", ++ "dev": true, ++ "license": "MIT" ++ }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", @@ -5478,6 +5913,51 @@ + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "license": "MIT" + }, ++ "node_modules/@types/babel__core": { ++ "version": "7.20.5", ++ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", ++ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@babel/parser": "^7.20.7", ++ "@babel/types": "^7.20.7", ++ "@types/babel__generator": "*", ++ "@types/babel__template": "*", ++ "@types/babel__traverse": "*" ++ } ++ }, ++ "node_modules/@types/babel__generator": { ++ "version": "7.27.0", ++ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", ++ "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@babel/types": "^7.0.0" ++ } ++ }, ++ "node_modules/@types/babel__template": { ++ "version": "7.4.4", ++ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", ++ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@babel/parser": "^7.1.0", ++ "@babel/types": "^7.0.0" ++ } ++ }, ++ "node_modules/@types/babel__traverse": { ++ "version": "7.28.0", ++ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", ++ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@babel/types": "^7.28.2" ++ } ++ }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", @@ -5511,6 +5991,16 @@ + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "license": "MIT" + }, ++ "node_modules/@types/cors": { ++ "version": "2.8.19", ++ "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", ++ "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@types/node": "*" ++ } ++ }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -5670,6 +6160,13 @@ + "node": ">= 0.12" + } + }, ++ "node_modules/@types/resolve": { ++ "version": "1.20.2", ++ "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", ++ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", ++ "dev": true, ++ "license": "MIT" ++ }, + "node_modules/@types/send": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.0.tgz", @@ -5718,6 +6215,27 @@ + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "license": "MIT" + }, ++ "node_modules/@vitejs/plugin-react": { ++ "version": "4.7.0", ++ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", ++ "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "@babel/core": "^7.28.0", ++ "@babel/plugin-transform-react-jsx-self": "^7.27.1", ++ "@babel/plugin-transform-react-jsx-source": "^7.27.1", ++ "@rolldown/pluginutils": "1.0.0-beta.27", ++ "@types/babel__core": "^7.20.5", ++ "react-refresh": "^0.17.0" ++ }, ++ "engines": { ++ "node": "^14.18.0 || >=16.0.0" ++ }, ++ "peerDependencies": { ++ "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" ++ } ++ }, + "node_modules/@vitest/expect": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.1.tgz", @@ -5872,6 +6390,14 @@ + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, ++ "node_modules/@wasp.sh/generated-server-dev": { ++ "resolved": ".wasp/out/server", ++ "link": true ++ }, ++ "node_modules/@wasp.sh/generated-webapp-dev": { ++ "resolved": ".wasp/out/web-app", ++ "link": true ++ }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.11", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz", @@ -6551,6 +7077,24 @@ + "baseline-browser-mapping": "dist/cli.js" + } + }, ++ "node_modules/basic-auth": { ++ "version": "2.0.1", ++ "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", ++ "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", ++ "license": "MIT", ++ "dependencies": { ++ "safe-buffer": "5.1.2" ++ }, ++ "engines": { ++ "node": ">= 0.8" ++ } ++ }, ++ "node_modules/basic-auth/node_modules/safe-buffer": { ++ "version": "5.1.2", ++ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", ++ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", ++ "license": "MIT" ++ }, + "node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", @@ -7094,6 +7638,13 @@ + "node": ">= 6" + } + }, ++ "node_modules/concat-map": { ++ "version": "0.0.1", ++ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", ++ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", ++ "dev": true, ++ "license": "MIT" ++ }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", @@ -7121,6 +7672,13 @@ + "node": ">= 0.6" + } + }, ++ "node_modules/convert-source-map": { ++ "version": "2.0.0", ++ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", ++ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", ++ "dev": true, ++ "license": "MIT" ++ }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", @@ -7130,6 +7688,25 @@ + "node": ">= 0.6" + } + }, ++ "node_modules/cookie-parser": { ++ "version": "1.4.7", ++ "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz", ++ "integrity": "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==", ++ "license": "MIT", ++ "dependencies": { ++ "cookie": "0.7.2", ++ "cookie-signature": "1.0.6" ++ }, ++ "engines": { ++ "node": ">= 0.8.0" ++ } ++ }, ++ "node_modules/cookie-parser/node_modules/cookie-signature": { ++ "version": "1.0.6", ++ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", ++ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", ++ "license": "MIT" ++ }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", @@ -7154,6 +7731,19 @@ + "url": "https://github.com/sponsors/mesqueeb" + } + }, ++ "node_modules/cors": { ++ "version": "2.8.5", ++ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", ++ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", ++ "license": "MIT", ++ "dependencies": { ++ "object-assign": "^4", ++ "vary": "^1" ++ }, ++ "engines": { ++ "node": ">= 0.10" ++ } ++ }, + "node_modules/cron-parser": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz", @@ -7480,6 +8070,18 @@ + "node": ">=12" + } + }, ++ "node_modules/dotenv": { ++ "version": "16.6.1", ++ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", ++ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", ++ "license": "BSD-2-Clause", ++ "engines": { ++ "node": ">=12" ++ }, ++ "funding": { ++ "url": "https://dotenvx.com" ++ } ++ }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -7607,6 +8209,13 @@ + "url": "https://github.com/sponsors/ljharb" + } + }, ++ "node_modules/es-module-lexer": { ++ "version": "1.7.0", ++ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", ++ "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", ++ "dev": true, ++ "license": "MIT" ++ }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", @@ -8289,6 +8898,16 @@ + "node": ">= 0.4" + } + }, ++ "node_modules/gensync": { ++ "version": "1.0.0-beta.2", ++ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", ++ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", ++ "dev": true, ++ "license": "MIT", ++ "engines": { ++ "node": ">=6.9.0" ++ } ++ }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -8365,6 +8984,19 @@ + "url": "https://github.com/sponsors/sindresorhus" + } + }, ++ "node_modules/get-tsconfig": { ++ "version": "4.13.0", ++ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", ++ "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "resolve-pkg-maps": "^1.0.0" ++ }, ++ "funding": { ++ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" ++ } ++ }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -8584,6 +9216,15 @@ + "integrity": "sha512-CHvacVPbl8AqIg2sBNKySUmumu7o15jSrCaTrIh9GW2Eq4y/krCN/vZFOsKCwlrhWQbO4267a8xvvP8bs+qREQ==", + "license": "MIT" + }, ++ "node_modules/helmet": { ++ "version": "6.2.0", ++ "resolved": "https://registry.npmjs.org/helmet/-/helmet-6.2.0.tgz", ++ "integrity": "sha512-DWlwuXLLqbrIOltR6tFQXShj/+7Cyp0gLi6uAb8qMdFh/YBBFbKSgQ6nbXmScYd8emMctuthmgIa7tUfo9Rtyg==", ++ "license": "MIT", ++ "engines": { ++ "node": ">=14.0.0" ++ } ++ }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", @@ -8710,6 +9351,13 @@ + ], + "license": "BSD-3-Clause" + }, ++ "node_modules/ignore-by-default": { ++ "version": "1.0.1", ++ "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", ++ "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", ++ "dev": true, ++ "license": "ISC" ++ }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", @@ -9033,6 +9681,13 @@ + "url": "https://github.com/sponsors/ljharb" + } + }, ++ "node_modules/is-module": { ++ "version": "1.0.0", ++ "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", ++ "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", ++ "dev": true, ++ "license": "MIT" ++ }, + "node_modules/is-node-process": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", @@ -9388,6 +10043,19 @@ + "node": ">=14" + } + }, ++ "node_modules/jsesc": { ++ "version": "3.1.0", ++ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", ++ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", ++ "dev": true, ++ "license": "MIT", ++ "bin": { ++ "jsesc": "bin/jsesc" ++ }, ++ "engines": { ++ "node": ">=6" ++ } ++ }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", @@ -9397,6 +10065,19 @@ + "bignumber.js": "^9.0.0" + } + }, ++ "node_modules/json5": { ++ "version": "2.2.3", ++ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", ++ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", ++ "dev": true, ++ "license": "MIT", ++ "bin": { ++ "json5": "lib/cli.js" ++ }, ++ "engines": { ++ "node": ">=6" ++ } ++ }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", @@ -9743,6 +10424,49 @@ + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, ++ "node_modules/morgan": { ++ "version": "1.10.1", ++ "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.1.tgz", ++ "integrity": "sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==", ++ "license": "MIT", ++ "dependencies": { ++ "basic-auth": "~2.0.1", ++ "debug": "2.6.9", ++ "depd": "~2.0.0", ++ "on-finished": "~2.3.0", ++ "on-headers": "~1.1.0" ++ }, ++ "engines": { ++ "node": ">= 0.8.0" ++ } ++ }, ++ "node_modules/morgan/node_modules/debug": { ++ "version": "2.6.9", ++ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", ++ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", ++ "license": "MIT", ++ "dependencies": { ++ "ms": "2.0.0" ++ } ++ }, ++ "node_modules/morgan/node_modules/ms": { ++ "version": "2.0.0", ++ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", ++ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", ++ "license": "MIT" ++ }, ++ "node_modules/morgan/node_modules/on-finished": { ++ "version": "2.3.0", ++ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", ++ "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", ++ "license": "MIT", ++ "dependencies": { ++ "ee-first": "1.1.1" ++ }, ++ "engines": { ++ "node": ">= 0.8" ++ } ++ }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", @@ -9921,6 +10645,102 @@ + "integrity": "sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg==", + "license": "MIT" + }, ++ "node_modules/nodemon": { ++ "version": "2.0.22", ++ "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", ++ "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "chokidar": "^3.5.2", ++ "debug": "^3.2.7", ++ "ignore-by-default": "^1.0.1", ++ "minimatch": "^3.1.2", ++ "pstree.remy": "^1.1.8", ++ "semver": "^5.7.1", ++ "simple-update-notifier": "^1.0.7", ++ "supports-color": "^5.5.0", ++ "touch": "^3.1.0", ++ "undefsafe": "^2.0.5" ++ }, ++ "bin": { ++ "nodemon": "bin/nodemon.js" ++ }, ++ "engines": { ++ "node": ">=8.10.0" ++ }, ++ "funding": { ++ "type": "opencollective", ++ "url": "https://opencollective.com/nodemon" ++ } ++ }, ++ "node_modules/nodemon/node_modules/brace-expansion": { ++ "version": "1.1.12", ++ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", ++ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "balanced-match": "^1.0.0", ++ "concat-map": "0.0.1" ++ } ++ }, ++ "node_modules/nodemon/node_modules/debug": { ++ "version": "3.2.7", ++ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", ++ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "ms": "^2.1.1" ++ } ++ }, ++ "node_modules/nodemon/node_modules/has-flag": { ++ "version": "3.0.0", ++ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", ++ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", ++ "dev": true, ++ "license": "MIT", ++ "engines": { ++ "node": ">=4" ++ } ++ }, ++ "node_modules/nodemon/node_modules/minimatch": { ++ "version": "3.1.2", ++ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", ++ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", ++ "dev": true, ++ "license": "ISC", ++ "dependencies": { ++ "brace-expansion": "^1.1.7" ++ }, ++ "engines": { ++ "node": "*" ++ } ++ }, ++ "node_modules/nodemon/node_modules/semver": { ++ "version": "5.7.2", ++ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", ++ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", ++ "dev": true, ++ "license": "ISC", ++ "bin": { ++ "semver": "bin/semver" ++ } ++ }, ++ "node_modules/nodemon/node_modules/supports-color": { ++ "version": "5.5.0", ++ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", ++ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "has-flag": "^3.0.0" ++ }, ++ "engines": { ++ "node": ">=4" ++ } ++ }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -10059,6 +10879,15 @@ + "node": ">= 0.8" + } + }, ++ "node_modules/on-headers": { ++ "version": "1.1.0", ++ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", ++ "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", ++ "license": "MIT", ++ "engines": { ++ "node": ">= 0.8" ++ } ++ }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -11199,6 +12028,13 @@ + "url": "https://github.com/sponsors/lupomontero" + } + }, ++ "node_modules/pstree.remy": { ++ "version": "1.1.8", ++ "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", ++ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", ++ "dev": true, ++ "license": "MIT" ++ }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -11358,6 +12194,16 @@ + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, ++ "node_modules/react-refresh": { ++ "version": "0.17.0", ++ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", ++ "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", ++ "dev": true, ++ "license": "MIT", ++ "engines": { ++ "node": ">=0.10.0" ++ } ++ }, + "node_modules/react-remove-scroll": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", @@ -11562,6 +12408,16 @@ + "url": "https://github.com/sponsors/ljharb" + } + }, ++ "node_modules/resolve-pkg-maps": { ++ "version": "1.0.0", ++ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", ++ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", ++ "dev": true, ++ "license": "MIT", ++ "funding": { ++ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" ++ } ++ }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -11646,6 +12502,26 @@ + "fsevents": "~2.3.2" + } + }, ++ "node_modules/rollup-plugin-esbuild": { ++ "version": "6.2.1", ++ "resolved": "https://registry.npmjs.org/rollup-plugin-esbuild/-/rollup-plugin-esbuild-6.2.1.tgz", ++ "integrity": "sha512-jTNOMGoMRhs0JuueJrJqbW8tOwxumaWYq+V5i+PD+8ecSCVkuX27tGW7BXqDgoULQ55rO7IdNxPcnsWtshz3AA==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "debug": "^4.4.0", ++ "es-module-lexer": "^1.6.0", ++ "get-tsconfig": "^4.10.0", ++ "unplugin-utils": "^0.2.4" ++ }, ++ "engines": { ++ "node": ">=14.18.0" ++ }, ++ "peerDependencies": { ++ "esbuild": ">=0.18.0", ++ "rollup": "^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0" ++ } ++ }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", @@ -11783,6 +12659,16 @@ + "loose-envify": "^1.1.0" + } + }, ++ "node_modules/semver": { ++ "version": "6.3.1", ++ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", ++ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", ++ "dev": true, ++ "license": "ISC", ++ "bin": { ++ "semver": "bin/semver.js" ++ } ++ }, + "node_modules/send": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", @@ -12023,6 +12909,29 @@ + "url": "https://github.com/sponsors/isaacs" + } + }, ++ "node_modules/simple-update-notifier": { ++ "version": "1.1.0", ++ "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", ++ "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "semver": "~7.0.0" ++ }, ++ "engines": { ++ "node": ">=8.10.0" ++ } ++ }, ++ "node_modules/simple-update-notifier/node_modules/semver": { ++ "version": "7.0.0", ++ "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", ++ "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", ++ "dev": true, ++ "license": "ISC", ++ "bin": { ++ "semver": "bin/semver.js" ++ } ++ }, + "node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", @@ -12719,6 +13628,16 @@ + "node": ">=6" + } + }, ++ "node_modules/touch": { ++ "version": "3.1.1", ++ "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", ++ "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", ++ "dev": true, ++ "license": "ISC", ++ "bin": { ++ "nodetouch": "bin/nodetouch.js" ++ } ++ }, + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", @@ -12828,6 +13747,13 @@ + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "license": "MIT" + }, ++ "node_modules/undefsafe": { ++ "version": "2.0.5", ++ "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", ++ "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", ++ "dev": true, ++ "license": "MIT" ++ }, + "node_modules/undici-types": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.14.0.tgz", @@ -12852,6 +13778,43 @@ + "node": ">= 0.8" + } + }, ++ "node_modules/unplugin-utils": { ++ "version": "0.2.5", ++ "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.2.5.tgz", ++ "integrity": "sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg==", ++ "dev": true, ++ "license": "MIT", ++ "dependencies": { ++ "pathe": "^2.0.3", ++ "picomatch": "^4.0.3" ++ }, ++ "engines": { ++ "node": ">=18.12.0" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/sxzz" ++ } ++ }, ++ "node_modules/unplugin-utils/node_modules/pathe": { ++ "version": "2.0.3", ++ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", ++ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", ++ "dev": true, ++ "license": "MIT" ++ }, ++ "node_modules/unplugin-utils/node_modules/picomatch": { ++ "version": "4.0.3", ++ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", ++ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", ++ "dev": true, ++ "license": "MIT", ++ "engines": { ++ "node": ">=12" ++ }, ++ "funding": { ++ "url": "https://github.com/sponsors/jonschlinkert" ++ } ++ }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", @@ -14437,6 +15400,13 @@ + "node": ">=10" + } + }, ++ "node_modules/yallist": { ++ "version": "3.1.1", ++ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", ++ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", ++ "dev": true, ++ "license": "ISC" ++ }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/opensaas-sh/app_diff/src/client/App.tsx.diff b/opensaas-sh/app_diff/src/client/App.tsx.diff index 711aa8480..1ee6df830 100644 --- a/opensaas-sh/app_diff/src/client/App.tsx.diff +++ b/opensaas-sh/app_diff/src/client/App.tsx.diff @@ -9,3 +9,20 @@ ); }, [location]); +@@ -42,7 +42,15 @@ + const id = location.hash.replace("#", ""); + const element = document.getElementById(id); + if (element) { +- element.scrollIntoView(); ++ const yOffset = -100; ++ const top = element.getBoundingClientRect().top + window.pageYOffset + yOffset; ++ window.scrollTo({ top, behavior: "smooth" }); ++ } ++ } else if (location.pathname === "/") { ++ // scroll to top of page ++ if (window.scrollY > 0) { ++ console.log("scrolling to top"); ++ window.scrollTo({ top: 0, behavior: "smooth" }); + } + } + }, [location]); diff --git a/opensaas-sh/app_diff/src/client/components/NavBar/constants.ts.diff b/opensaas-sh/app_diff/src/client/components/NavBar/constants.ts.diff index bcdd8eea6..3e4d4979c 100644 --- a/opensaas-sh/app_diff/src/client/components/NavBar/constants.ts.diff +++ b/opensaas-sh/app_diff/src/client/components/NavBar/constants.ts.diff @@ -1,10 +1,13 @@ --- template/app/src/client/components/NavBar/constants.ts +++ opensaas-sh/app/src/client/components/NavBar/constants.ts -@@ -9,12 +9,12 @@ +@@ -8,13 +8,14 @@ + ]; export const marketingNavigationItems: NavigationItem[] = [ - { name: "Features", to: "/#features" }, +- { name: "Features", to: "/#features" }, - { name: "Pricing", to: routes.PricingPageRoute.to }, ++ { name: "Features", to: "/#auth-feature" }, ++ { name: "Roadmap", to: "/#roadmap" }, ...staticNavigationItems, ] as const; diff --git a/opensaas-sh/app_diff/src/landing-page/LandingPage.tsx.diff b/opensaas-sh/app_diff/src/landing-page/LandingPage.tsx.diff index 3fd1f59d8..e53021d76 100644 --- a/opensaas-sh/app_diff/src/landing-page/LandingPage.tsx.diff +++ b/opensaas-sh/app_diff/src/landing-page/LandingPage.tsx.diff @@ -5,15 +5,16 @@ import ExamplesCarousel from "./components/ExamplesCarousel"; import FAQ from "./components/FAQ"; import FeaturesGrid from "./components/FeaturesGrid"; -@@ -11,7 +12,6 @@ +@@ -11,7 +12,7 @@ footerNavigation, testimonials, } from "./contentSections"; -import AIReady from "./ExampleHighlightedFeature"; ++import Roadmap from "./components/Roadmap"; export default function LandingPage() { return ( -@@ -19,6 +19,9 @@ +@@ -19,8 +20,12 @@
@@ -22,4 +23,7 @@ + ++ + +
diff --git a/opensaas-sh/app_diff/src/landing-page/components/Examples/Auth.tsx.diff b/opensaas-sh/app_diff/src/landing-page/components/Examples/Auth.tsx.diff index f30a0ddc1..32b3a44b5 100644 --- a/opensaas-sh/app_diff/src/landing-page/components/Examples/Auth.tsx.diff +++ b/opensaas-sh/app_diff/src/landing-page/components/Examples/Auth.tsx.diff @@ -1,6 +1,6 @@ --- template/app/src/landing-page/components/Examples/Auth.tsx +++ opensaas-sh/app/src/landing-page/components/Examples/Auth.tsx -@@ -0,0 +1,163 @@ +@@ -0,0 +1,164 @@ +import { useState } from "react"; +import { FaDiscord, FaGithub, FaGoogle, FaSlack } from "react-icons/fa"; +import { Button } from "../../../client/components/ui/button"; @@ -55,6 +55,7 @@ + + return ( + ++
+ + -+
++
+
+
+
diff --git a/opensaas-sh/app_diff/src/landing-page/components/HighlightedFeature.tsx.diff b/opensaas-sh/app_diff/src/landing-page/components/HighlightedFeature.tsx.diff index 06e500e73..2e670e130 100644 --- a/opensaas-sh/app_diff/src/landing-page/components/HighlightedFeature.tsx.diff +++ b/opensaas-sh/app_diff/src/landing-page/components/HighlightedFeature.tsx.diff @@ -1,6 +1,12 @@ --- template/app/src/landing-page/components/HighlightedFeature.tsx +++ opensaas-sh/app/src/landing-page/components/HighlightedFeature.tsx -@@ -6,6 +6,8 @@ +@@ -1,11 +1,14 @@ + import { cn } from "../../client/utils"; + + interface FeatureProps { ++ id?: string; + name: string; + description: string | React.ReactNode; direction?: "row" | "row-reverse"; highlightedComponent: React.ReactNode; tilt?: "left" | "right"; @@ -9,7 +15,13 @@ } /** -@@ -18,6 +20,8 @@ +@@ -13,11 +16,14 @@ + * Shows text description on one side, and whatever component you want to show on the other side to demonstrate the functionality. + */ + const HighlightedFeature = ({ ++ id, + name, + description, direction = "row", highlightedComponent, tilt, @@ -18,9 +30,11 @@ }: FeatureProps) => { const tiltToClass: Record["tilt"], string> = { left: "rotate-1", -@@ -27,12 +31,14 @@ +@@ -26,13 +32,16 @@ + return (
{description}

) : ( -@@ -43,6 +49,7 @@ +@@ -43,6 +52,7 @@ className={cn( "my-10 flex w-full flex-1 items-center justify-center transition-transform duration-300 ease-in-out", tilt && tiltToClass[tilt], diff --git a/opensaas-sh/app_diff/src/landing-page/components/Roadmap.tsx.diff b/opensaas-sh/app_diff/src/landing-page/components/Roadmap.tsx.diff new file mode 100644 index 000000000..000afd485 --- /dev/null +++ b/opensaas-sh/app_diff/src/landing-page/components/Roadmap.tsx.diff @@ -0,0 +1,150 @@ +--- template/app/src/landing-page/components/Roadmap.tsx ++++ opensaas-sh/app/src/landing-page/components/Roadmap.tsx +@@ -0,0 +1,147 @@ ++import type { EpicStats } from "../operations"; ++import { EpicStatus } from "../operations"; ++ ++import { useQuery, getGithubRoadmap } from "wasp/client/operations"; ++import { Loader2 } from "lucide-react"; ++ ++export default function Roadmap() { ++ const { data: epics, isLoading, error } = useQuery(getGithubRoadmap); ++ ++ if (isLoading) { ++ return ( ++
++ ++
++ ); ++ } ++ ++ if (error) { ++ return ( ++
++ Failed to load roadmap ++
++ ); ++ } ++ ++ if (!epics || epics.length === 0) return null; ++ ++ const getStatusColor = (status: EpicStatus) => { ++ switch (status) { ++ case EpicStatus.Ideas: ++ return "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300 border-blue-200 dark:border-blue-800"; ++ case EpicStatus.Planned: ++ return "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300 border-green-200 dark:border-green-800"; ++ case EpicStatus.InProgress: ++ return "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-300 border-yellow-200 dark:border-yellow-800"; ++ case EpicStatus.Done: ++ return "bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-300 border-purple-200 dark:border-purple-800"; ++ default: ++ return "bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-300 border-gray-200 dark:border-gray-700"; ++ } ++ }; ++ ++ const getProgressBarColor = (status: EpicStatus) => { ++ switch (status) { ++ case EpicStatus.Ideas: return "bg-blue-500"; ++ case EpicStatus.Planned: return "bg-green-500"; ++ case EpicStatus.InProgress: return "bg-yellow-500"; ++ case EpicStatus.Done: return "bg-purple-500"; ++ default: return "bg-gray-500"; ++ } ++ }; ++ ++ const getBorderColor = (status: EpicStatus) => { ++ switch (status) { ++ case EpicStatus.Ideas: return "border-blue-200 dark:border-blue-800"; ++ case EpicStatus.Planned: return "border-green-200 dark:border-green-800"; ++ case EpicStatus.InProgress: return "border-yellow-200 dark:border-yellow-800"; ++ case EpicStatus.Done: return "border-purple-200 dark:border-purple-800"; ++ default: return "border-gray-200 dark:border-gray-700"; ++ } ++ }; ++ ++ const getHoverBorderColor = (status: EpicStatus) => { ++ switch (status) { ++ case EpicStatus.Ideas: return "hover:border-blue-400 dark:hover:border-blue-600"; ++ case EpicStatus.Planned: return "hover:border-green-400 dark:hover:border-green-600"; ++ case EpicStatus.InProgress: return "hover:border-yellow-400 dark:hover:border-yellow-600"; ++ case EpicStatus.Done: return "hover:border-purple-400 dark:hover:border-purple-600"; ++ default: return "hover:border-gray-400 dark:hover:border-gray-600"; ++ } ++ }; ++ ++ return ( ++
++
++
++

++ The Roadmap ++

++

++ High-level topics we are planning and working on. ++

++
++ ++
++ {[EpicStatus.Ideas, EpicStatus.Planned, EpicStatus.InProgress, EpicStatus.Done].map((status) => { ++ const statusEpics = epics.filter((e: EpicStats) => e.status === status); ++ const borderColor = getBorderColor(status); ++ const statusColor = getStatusColor(status); ++ ++ return ( ++
++
++

++ {status} ++

++ ({statusEpics.length}) ++
++ ++
++ {statusEpics.map((epic: EpicStats) => { ++ const progress = epic.total > 0 ? Math.round((epic.done / epic.total) * 100) : 0; ++ const progressColor = getProgressBarColor(epic.status); ++ const hoverBorderColor = getHoverBorderColor(epic.status); ++ ++ return ( ++ ++

++ {epic.name} ++

++ ++
++
++ Progress ++ {progress}% ({epic.done}/{epic.total}) ++
++
++
++
++
++
++ ); ++ })} ++ ++ {statusEpics.length === 0 && ( ++
++ No epics ++
++ )} ++
++
++ ); ++ })} ++
++
++
++ ); ++} diff --git a/opensaas-sh/app_diff/src/landing-page/contentSections.tsx.diff b/opensaas-sh/app_diff/src/landing-page/contentSections.tsx.diff index 8be0d2796..5ab6f5502 100644 --- a/opensaas-sh/app_diff/src/landing-page/contentSections.tsx.diff +++ b/opensaas-sh/app_diff/src/landing-page/contentSections.tsx.diff @@ -11,7 +11,7 @@ import kivo from "../client/static/examples/kivo.webp"; import messync from "../client/static/examples/messync.webp"; import microinfluencerClub from "../client/static/examples/microinfluencers.webp"; -@@ -6,161 +11,253 @@ +@@ -6,161 +11,248 @@ import reviewradar from "../client/static/examples/reviewradar.webp"; import scribeist from "../client/static/examples/scribeist.webp"; import searchcraft from "../client/static/examples/searchcraft.webp"; @@ -21,11 +21,6 @@ +import { BlogUrl, DocsUrl, GithubUrl, WaspUrl } from "../shared/common"; +import { GridFeature } from "./components/FeaturesGrid"; -+export const landingPageNavigationItems: NavigationItem[] = [ -+ { name: "Features", to: "#features" }, -+ { name: "Documentation", to: DocsUrl }, -+ { name: "Blog", to: BlogUrl }, -+]; export const features: GridFeature[] = [ { - name: "Cool Feature 1", diff --git a/opensaas-sh/app_diff/src/landing-page/operations.ts.diff b/opensaas-sh/app_diff/src/landing-page/operations.ts.diff new file mode 100644 index 000000000..3fec58ad3 --- /dev/null +++ b/opensaas-sh/app_diff/src/landing-page/operations.ts.diff @@ -0,0 +1,211 @@ +--- template/app/src/landing-page/operations.ts ++++ opensaas-sh/app/src/landing-page/operations.ts +@@ -0,0 +1,208 @@ ++import type { GetGithubRoadmap } from 'wasp/server/operations' ++import * as z from 'zod' ++ ++const ORG_NAME = "wasp-lang" ++const PROJECT_NUMBER = 6 ++ ++const GithubIssueSchema = z.object({ ++ title: z.string(), ++ url: z.string(), ++ number: z.number(), ++ issueType: z.object({ ++ name: z.string() ++ }).nullish(), ++ subIssues: z.object({ ++ totalCount: z.number(), ++ nodes: z.array(z.object({ ++ state: z.string(), ++ number: z.number() ++ })) ++ }).nullish() ++}) ++ ++const ProjectV2ItemFieldValueSchema = z.object({ ++ name: z.string().nullish(), ++ field: z.object({ ++ name: z.string() ++ }).nullish() ++}) ++ ++const ProjectV2ItemSchema = z.object({ ++ id: z.string(), ++ databaseId: z.number().nullish(), ++ fieldValues: z.object({ ++ nodes: z.array(ProjectV2ItemFieldValueSchema) ++ }), ++ content: GithubIssueSchema ++}) ++ ++const GithubGraphQLResponseSchema = z.object({ ++ data: z.object({ ++ organization: z.object({ ++ projectV2: z.object({ ++ items: z.object({ ++ nodes: z.array(ProjectV2ItemSchema) ++ }).nullish() ++ }).nullish() ++ }).nullish() ++ }).nullish(), ++ errors: z.array(z.any()).nullish() ++}) ++ ++export enum EpicStatus { ++ Ideas = "Ideas", ++ Planned = "Planned", ++ InProgress = "In progress", ++ Done = "Done" ++} ++ ++export type EpicStats = { ++ name: string ++ total: number ++ done: number ++ status: EpicStatus ++ url: string ++} ++ ++type RoadmapData = EpicStats[] ++ ++let cachedData: RoadmapData | null = null ++let lastFetchTime = 0 ++const CACHE_DURATION = 4 * 60 * 60 * 1000 ++ ++export const getGithubRoadmap: GetGithubRoadmap = async () => { ++ const currentTime = Date.now() ++ ++ if (cachedData && currentTime - lastFetchTime < CACHE_DURATION) { ++ return cachedData ++ } ++ ++ const token = process.env.GITHUB_ROADMAP_TOKEN ++ if (!token) { ++ console.warn("GITHUB_ROADMAP_TOKEN is not set") ++ return [] ++ } ++ ++ const query = ` ++ query($org: String!, $number: Int!) { ++ organization(login: $org) { ++ projectV2(number: $number) { ++ items(first: 100) { ++ nodes { ++ id ++ databaseId ++ fieldValues(first: 50) { ++ nodes { ++ ... on ProjectV2ItemFieldSingleSelectValue { ++ name ++ field { ... on ProjectV2FieldCommon { name } } ++ } ++ } ++ } ++ content { ++ ... on Issue { ++ title ++ url ++ number ++ issueType { name } ++ subIssues(first: 100) { ++ totalCount ++ nodes { ++ state ++ number ++ } ++ } ++ } ++ } ++ } ++ } ++ } ++ } ++ } ++ ` ++ ++ try { ++ const response = await fetch("https://api.github.com/graphql", { ++ method: "POST", ++ headers: { ++ "Content-Type": "application/json", ++ Authorization: `Bearer ${token}`, ++ }, ++ body: JSON.stringify({ ++ query, ++ variables: { org: ORG_NAME, number: PROJECT_NUMBER }, ++ }), ++ }) ++ ++ const json = await response.json() ++ ++ const parseResult = GithubGraphQLResponseSchema.safeParse(json) ++ if (!parseResult.success) { ++ console.error("GitHub API response validation failed:", parseResult.error) ++ return cachedData || [] ++ } ++ ++ const validatedResponse = parseResult.data ++ ++ if (validatedResponse.errors) { ++ console.error("GitHub API Errors:", validatedResponse.errors) ++ throw new Error("GitHub API returned errors") ++ } ++ ++ const nodes = validatedResponse.data?.organization?.projectV2?.items?.nodes || [] ++ const statusFieldName = "Status" ++ ++ const BASE_PROJECT_URL = "https://github.com/orgs/wasp-lang/projects/6/views/1?pane=issue&itemId=" ++ ++ const epics: EpicStats[] = nodes ++ .filter((node) => { ++ const issue = node.content ++ return issue && issue.issueType?.name === "Epic" ++ }) ++ .map((node) => { ++ const issue = node.content ++ ++ const statusField = node.fieldValues.nodes.find( ++ (f) => f.field?.name === statusFieldName ++ ) ++ const statusName = statusField?.name || "Ideas" ++ ++ let status: EpicStatus = EpicStatus.Ideas ++ if (Object.values(EpicStatus).includes(statusName as EpicStatus)) { ++ status = statusName as EpicStatus ++ } ++ ++ const subIssues = issue.subIssues?.nodes || [] ++ const total = issue.subIssues?.totalCount ?? subIssues.length ++ const done = subIssues.filter((sub) => sub.state === "CLOSED").length ++ ++ return { ++ name: issue.title, ++ total, ++ done, ++ status, ++ url: `${BASE_PROJECT_URL}${node.databaseId}` ++ } ++ }) ++ ++ const statusOrder = { ++ [EpicStatus.InProgress]: 0, ++ [EpicStatus.Planned]: 1, ++ [EpicStatus.Ideas]: 2, ++ [EpicStatus.Done]: 3 ++ } ++ ++ epics.sort((a, b) => { ++ const orderA = statusOrder[a.status] ?? 99 ++ const orderB = statusOrder[b.status] ?? 99 ++ return orderA - orderB ++ }) ++ ++ cachedData = epics ++ lastFetchTime = currentTime ++ return epics ++ } catch (error) { ++ console.error("Failed to fetch GitHub roadmap:", error) ++ return cachedData || [] ++ } ++} diff --git a/opensaas-sh/blog/public/banner-images/2025-11-21-open-saas-public-roadmap.webp b/opensaas-sh/blog/public/banner-images/2025-11-21-open-saas-public-roadmap.webp new file mode 100644 index 000000000..66eaa2027 Binary files /dev/null and b/opensaas-sh/blog/public/banner-images/2025-11-21-open-saas-public-roadmap.webp differ diff --git a/opensaas-sh/blog/src/assets/roadmap/open-saas-ai-ready.webp b/opensaas-sh/blog/src/assets/roadmap/open-saas-ai-ready.webp new file mode 100644 index 000000000..26ab1dc1c Binary files /dev/null and b/opensaas-sh/blog/src/assets/roadmap/open-saas-ai-ready.webp differ diff --git a/opensaas-sh/blog/src/assets/roadmap/open-saas-epic-detail.webp b/opensaas-sh/blog/src/assets/roadmap/open-saas-epic-detail.webp new file mode 100644 index 000000000..2674291dd Binary files /dev/null and b/opensaas-sh/blog/src/assets/roadmap/open-saas-epic-detail.webp differ diff --git a/opensaas-sh/blog/src/assets/roadmap/open-saas-epic.webp b/opensaas-sh/blog/src/assets/roadmap/open-saas-epic.webp new file mode 100644 index 000000000..5beaf43b0 Binary files /dev/null and b/opensaas-sh/blog/src/assets/roadmap/open-saas-epic.webp differ diff --git a/opensaas-sh/blog/src/assets/roadmap/open-saas-roadmap.webp b/opensaas-sh/blog/src/assets/roadmap/open-saas-roadmap.webp new file mode 100644 index 000000000..a3ad26df9 Binary files /dev/null and b/opensaas-sh/blog/src/assets/roadmap/open-saas-roadmap.webp differ diff --git a/opensaas-sh/blog/src/assets/roadmap/open-saas-used-by.webp b/opensaas-sh/blog/src/assets/roadmap/open-saas-used-by.webp new file mode 100644 index 000000000..bd51df914 Binary files /dev/null and b/opensaas-sh/blog/src/assets/roadmap/open-saas-used-by.webp differ diff --git a/opensaas-sh/blog/src/content/docs/blog/2025-11-21-open-saas-public-roadmap.mdx b/opensaas-sh/blog/src/content/docs/blog/2025-11-21-open-saas-public-roadmap.mdx new file mode 100644 index 000000000..4916486c3 --- /dev/null +++ b/opensaas-sh/blog/src/content/docs/blog/2025-11-21-open-saas-public-roadmap.mdx @@ -0,0 +1,193 @@ +--- +title: "Open SaaS — Public Development Roadmap" +date: 2025-11-21 +tags: + - roadmap + - open-saas + - wasp + - open-source +authors: vince +--- +import { Image } from 'astro:assets'; +import openSaasUsedBy from '../../../assets/roadmap/open-saas-used-by.webp'; +import openSaasRoadmap from '../../../assets/roadmap/open-saas-roadmap.webp'; +import epicExample from '../../../assets/roadmap/open-saas-epic.webp'; +import epicDetailExample from '../../../assets/roadmap/open-saas-epic-detail.webp'; +import aiReady from '../../../assets/roadmap/open-saas-ai-ready.webp'; +import Tweet from '../../../components/Tweet.astro'; +import { Aside } from '@astrojs/starlight/components'; + +We created Open SaaS to help developers launch full-featured SaaS products faster. As an open-source project powered by [Wasp](https://wasp.sh), we thought it was important to have two things: +1. A solid roadmap so that development is focused. +2. A roadmap that's public, so that the community can see what's coming next and get involved. + +So we created just that. Behold, the [Open SaaS public roadmap](https://github.com/orgs/wasp-lang/projects/6)! +
+ +Open SaaS public roadmap + + +--- + +## Why a roadmap? + +Open SaaS is becoming a beast of its own. At 13k GitHub stars and growing, and with constant feature additions and improvements, we thought it was time to make future development more organized, transparent, and community-driven. + +
+ +Open SaaS is used by thousands of developers + +
+ +With thousands of SaaS apps being deployed with Open SaaS, the needs of its users are also becoming more diverse. It would be impossible to address all of them, but we needed a way to track and prioritize the most important features and improvements. + +Up until now, it was just me basically deciding which issues to work on and when. This was pretty inefficent to begin with, and then with more contributors joining the project, it became even more so. + +The roadmap is thus a great way to make sense of all the different possible directions we can go in, help focus our efforts, and make development and contributions more meaningful. + +## How it works + +Open SaaS currently has about [100 open GitHub issues](https://github.com/wasp-lang/open-saas/issues), so it would be crazy to organize and track them all in the roadmap. + +
+ +An example of an Epic in the Open SaaS roadmap + +
+ +So to make things overseeable, the roadmap is a GitHub project with a collection of "Epics". An Epic is just a GitHub issue with a bunch of sub-issues. Each Epic has a status and a progress bar to show you how many of its sub-issues are completed. + +
+ +An example of an Epic in the Open SaaS roadmap + +
+ +No regular issues are allowed in it, only epics, of which we don't want too many. This way, its easy to understand the current themes and priorities of the project, as well as what's currently underway. + +--- + +## Guiding themes + +When creating epics within the roadmap, there are a few categories we're focusing on at the moment. These guiding themes inform the epics we create, and help us make sure we're addressing the most important needs of our users. + +### 1. Real-world launch readiness + +Open SaaS should not just be a polished demo, or a flimsy template. It should be something you can deploy and scale. We want to make sure Open SaaS is a production-ready starter that can be used to build real-world SaaS products. +This means having a solid architecture, a clean codebase, and a set of features that are robust and ready to be used in production. + + + +### 2. Modularity & flexibility + +Different [auth methods](https://docs.opensaas.sh/guides/authentication/), [billing providers](https://docs.opensaas.sh/guides/payment-integrations/), file uploads, AI integrations, analytics, and more. We want to make sure Open SaaS is a flexible and modular platform that can be tailored to the needs of (almost) any SaaS product. +This means having the most essential features you need to launch your SaaS quickly, and being able to easily remove the things you don't. + +### 3. AI-first developer experience + +
+ +Open SaaS is AI-ready + +
+ +Whether you use Cursor, VSCode + Copilot, Claude, or others, Open SaaS should have top-notch code quality and be able to “explain itself” well to AI-driven coding tools, making it enjoyable to develop with in 2026 and beyond. + +We also want to provide demos and templates for AI-powered SaaS products, so you can get started building SaaS apps that leverage the newest technologies to create powerful and innovative products. + + + +### 4. Community-powered evolution + +We want Open SaaS to be shaped by real feedback, real PRs, and real use cases. Roadmap ideas are only valuable when they reflect what people actually need. +So your [feedback and contributions](https://github.com/wasp-lang/open-saas/issues) are important to us! + +--- + +## What's in the roadmap + +We just got finished with a major UI redesign, which we dubbed "Open SaaS v2.0". Take a look at the announcement below. + + +With the new UI, based on [Shadcn UI](https://ui.shadcn.com/), finished and tucked away, we've turned back towards adding highly-requested features, and improving the codebase with smaller fixes. + +### 1. Payment Provider Expansion + +Today, Open SaaS supports Stripe, Polar, and Lemon Squeezy as payment providers. It's super [easy to get started](https://docs.opensaas.sh/guides/payment-integrations/) with one -- just plug and play. + +**Upcoming features:** + +* Polar.sh integration (merged in [#461](https://github.com/wasp-lang/open-saas/pull/461)) +* Paddle, and additional gateways (especially regional-friendly options) +* Supporting up- or down-grading between different billing plans and models (proration) + +--- + +### 2. AI-First Workflows & Templates + +Open SaaS already includes a simple OpenAI integration example, but we’re looking to expand and improve it. + +**Coming soon:** + +* Exploring using Vercel's AI SDK within our demo app (issue [#567](https://github.com/wasp-lang/open-saas/issues/567)). +* Cursor / Claude prompt presets for smoother onboarding (issue [#579](https://github.com/wasp-lang/open-saas/issues/579)) +* Creating better docs and guides for AI-powered SaaS development + +--- + +### 3. Core Development Improvements + +We want to keep Open SaaS relevant and up-to-date with the latest trends, as well as with the latest Wasp (the framework it's built on) features and improvements . + +**Efforts underway:** + +* Improving OpenSaaS.sh development workflows (issue [#552](https://github.com/wasp-lang/open-saas/issues/552)) +* Improving e2e tests (issue [#558](https://github.com/wasp-lang/open-saas/issues/558)) + +--- + +# How to Participate + +So that's just a quick overview of the current state of the roadmap. But we're not done yet! + +Open SaaS is community-driven — and we’d love your help. + +### ⭐ Star the repo + +This is super easy and helps a ton! + +[https://github.com/wasp-lang/open-saas](https://github.com/wasp-lang/open-saas) + +### 🧩 File issues or feature requests + +Especially around real-world SaaS requirements you’re running into. + +[https://github.com/wasp-lang/open-saas/issues](https://github.com/wasp-lang/open-saas/issues) + +### 🔧 Contribute code + +If you’re interested in payments, dashboarding, AI workflows, or dev-experience improvements — we’ll happily support and guide. + +[https://github.com/orgs/wasp-lang/projects/6](https://github.com/orgs/wasp-lang/projects/6) + +### 🚀 Build with it + +The best feedback always comes from people deploying real products. +Drop us a line on [Discord](https://discord.com/invite/aCamt5wCpS) or [Twitter](https://x.com/wasplang) and let us know what you're building! + +--- + +# Roadmap Updates + +We’ll keep updating this roadmap alongside major releases and aim for a quarterly revision cycle. + +You can follow progress in the GitHub Project board: + +👉 **[https://github.com/orgs/wasp-lang/projects/6](https://github.com/orgs/wasp-lang/projects/6)** + +See you there!