wasp-lang / open-saas Goto Github PK
View Code? Open in Web Editor NEWA free, open-source SaaS app starter for React & Node.js with superpowers. Production-ready. Community-driven.
Home Page: https://opensaas.sh
License: MIT License
A free, open-source SaaS app starter for React & Node.js with superpowers. Production-ready. Community-driven.
Home Page: https://opensaas.sh
License: MIT License
Open SaaS currently has subscription payments via Stripe.
It would be nice to add similar support for Lemon Squeezy as mentioned by @shengxinjing
stripePayment
from app/src/server/actions.ts
to app/src/server/stripeUtils.ts
app/src/server/lemonsqueezyUtils.ts
and add the complimentary checkout logic for lemon squeezy. If possible, we want to make the checkout action interchangeable with the stripePayment
action, so that these actions can swapped 1:1 on the clientapp/src/server/webhooks
if necessary.app/src/client/app/PricingPage.tsx
if necessaryCurrently we are using the default Astro Starlight docs theme.
Lets update it to make it look sexy and fit the style of our landing page:
Tasks:
I'm trying to run this project on my CentOS7 server, and since the system version is not compatible with some of the project's dependencies I'm using docker to run the project and the database.
Errors are consistently encountered while executing the wasp start
command:
My consultation with ChatGPT resulted in saying that my system is low on memory, I have only 1G of RAM and only about 500M free, but I'm not convinced that this is the cause of the problem as I've manually installed all the dependencies to minimize the memory usage of wasp, but the problem is still not solved. Can anyone help me?
Hi, maybe my issue will be useful to others users.
I'm trying to implement Flask in the backend to get some financial information thanks to a python library.
main.wasp
route FinanceRoute { path: "/finance", to: FinancePage }
page FinancePage {
authRequired: true,
component: import FinancePage from "@client/app/FinancePage"
}
query getStockInfo {
fn: import { getStockInfo } from "@server/queries.js"
}
src/server/queries.ts
import axios from 'axios';
export const getStockInfo = async ({ symbol }) => {
console.log("getStockInfo called with symbol:", symbol); // Log del simbolo in ingresso
try {
const response = await axios.post('http://localhost:5000/getStockInfo', { symbol });
console.log("Response from Flask server:", response.data); // Log della risposta dal server Flask
return response.data.longName;
} catch (error) {
console.error("Error calling Flask server:", error.message); // Log dell'errore, se presente
throw new HttpError(500, error.response ? error.response.data.error : "Server error");
}
};
src/server/finance_server.py
from flask import Flask, request, jsonify
from flask_cors import CORS
import yfinance as yf
app = Flask(__name__)
CORS(app)
@app.route('/getStockInfo', methods=['POST'])
def get_stock_info():
data = request.json
print("Dati ricevuti:", data) # Logging dei dati ricevuti
symbol = data.get('symbol')
if not symbol:
return jsonify({'error': 'Missing symbol parameter'}), 400
try:
stock = yf.Ticker(symbol)
info = stock.info
return jsonify({'longName': info.get('longName', 'Name not found')})
except Exception as e:
return jsonify({'error': str(e)}), 500
if __name__ == '__main__':
app.run(debug=True, port=5000)
src/client/FinancePage.tsx
import React, { useState } from 'react';
import { useQuery } from '@wasp/queries';
import getStockInfo from '@wasp/queries/getStockInfo';
const FinancePage = () => {
const [inputSymbol, setInputSymbol] = useState('');
const [longName, setLongName] = useState('');
const [error, setError] = useState('');
const handleSearch = async (e) => {
e.preventDefault();
if (!inputSymbol) {
console.error("Symbol is undefined or empty");
setError("Symbol is undefined or empty");
return;
}
try {
const name = await getStockInfo({ symbol: inputSymbol });
setLongName(name);
setError('');
} catch (err) {
setError(err.message);
}
};
return (
<div>
<form onSubmit={handleSearch}>
<input
type="text"
value={inputSymbol}
onChange={(e) => setInputSymbol(e.target.value)}
/>
<button type="submit">Get Stock Info</button>
</form>
{longName && <p>Long Name: {longName}</p>}
{error && <p>Error: {error}</p>}
</div>
);
};
export default FinancePage;
But i retrive this error:
[Server!] Error calling Flask server: Request failed with status code 403
[Server] POST /operations/get-stock-info 500 12.396 ms - 14
Surely there is a communication problem between the server and flask, would anyone know how to solve it?
The Total Revenue chart only shows the total revenue metric per day for the past week (week
and month
buttons are non-functional)
Tasks:
weeklyStats
from the getDailyStats()
query in src/server/queries.ts
.main.wasp
, getWeeklyStats()
.getWeeklyStats()
query in src/server/queries.ts
to calculate revenue on a weekly basis, starting from the 1st of each month.src/client/admin/pages/Dashboard/ECommerce.tsx
to take dailyStats
(total revenue per day for the last week) and the newly defined weeklyStats
(total revenue per each week for a defined time period).src/client/admin/pages/Dashboard/ECommerce.tsx
and pass it as a prop to <RevenueAndProfitChart />
Questions to Answer:
RevenueAndProfitChart
(see above), we currently show running total revenue per day, rather than the revenue made that day alone. Should we refactor the chart to show daily incoming revenue rather than the running total?week
view on the RevenueAndProfitChart
? Should we show a set amount of weeks, e.g. the past 9 weeks, or should we make it programmable?at the moment, no deployment guide exists for the Astro blog. The recommended approach would be to build it and deploy it to a static hosting provider like netlify, following these steps: https://wasp-lang.dev/docs/advanced/deployment/manually#netlify
for analytics (in the case of using Starlight blog for SEO), the astro-google-analytics package seems to be a good option, but I'm still waiting to hear back from the Astro team on the recommended approach.
Github login just returns me back to login/
screen, and I can't log in with Github, if I already logged in previously with Google which has same email address.
I know that accounts won't get merged, but I would expect to either have new account crated, or to get a useful error message.
It seems this is caused by the fact that email
on User
entity has unique
on it.
The project lacks specific requirements, such as server system, which has made the compilation process very difficult. It is not as straightforward as described in the documentation, where it claims that it can be up and running with just a few lines of code. I'm unsure if this is due to my technical limitations, but I have made every effort to address all the encountered issues, only to find new problems continuously emerging.
in main.wasp
, we already have a ContactFormMessage
database entity:
entity ContactFormMessage {=psl
id String @id @default(uuid())
content String
user User @relation(fields: [userId], references: [id])
userId Int
createdAt DateTime @default(now())
isRead Boolean @default(false)
repliedAt DateTime?
psl=}
This should correspond to the AdminMessagesRoute
within the Admin Dashboard:
route AdminMessagesRoute { path: "/admin/messages", to: AdminMessagesPage }
It would also be necessary to add functionality within the User App Dashboard to allow user's to fill out a contact form and send messages to the Admin
Describe the bug
The email auth is not working.
To Reproduce
Steps to reproduce the behavior:
entity User {=psl
id Int @id @default(autoincrement())
email String? @unique
username String @unique
password String?
createdAt DateTime @default(now())
...
[Server] src/auth/providers/email/signup.ts(48,39): error TS2345: Argument of type '{ email: any; password: any; }' is not assignable to parameter of type 'UserCreateInput'.
[Server] Property 'username' is missing in type '{ email: any; password: any; }' but required in type 'UserCreateInput'.
And If I change the code wasp generated in .wasp/out/server/src/auth/providers/email/signup.ts
from
const user = await createUser({
...additionalFields,
email: userFields.email,
password: userFields.password,
});
to
const user = await createUser({
...additionalFields,
email: userFields.email,
username: userFields.email,
password: userFields.password,
});
The user signed up successfully.
Expected behavior
When I change the auth to email auth, the user can sign up correctly.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Additional context
Add any other context about the problem here.
File upload is something that you often need, but it is never straightforward. If Open SaaS could help with that, that would be amazing!
这个能部署到vercel上面去吗?
Follow the instruction on docs to add a custom route. the response message not show up. it seems the response message for every page is the same. How should adding a custom route? how to remove the default response message?
I see there is a new LTS for node as of a few months ago. https://nodejs.org/en/blog/release/v20.9.0
Based on the wording here it looks like you're trying to keep up with the latest LTS so its probably time to upgrade.
I went through the installation process shown here
As I stepped through I was able to run wasp db studio
and have it work. I briefly clicked around but there was no data there so it was uninteresting. I continued to follow the installation instructions. I started the app and created a user and a todo item. Then I went back to run wasp db studio
again and its failing to start up.
I see this:
➜ app git:(main) wasp db studio
🐝 --- Compiling wasp project... --------------------------------------------------
🐝 --- Setting up database... -----------------------------------------------------
✅ --- Database successfully set up. ----------------------------------------------
✅ --- Your wasp project has successfully compiled. -------------------------------
🐝 --- Running studio... ----------------------------------------------------------
[Db] Environment variables loaded from .env
[Db] Prisma schema loaded from ../db/schema.prisma
[Db] Prisma Studio is up on http://localhost:5555
[Db!] node:internal/process/promises:288
[Db!] triggerUncaughtException(err, true /* fromPromise */);
[Db!] ^
[Db!]
[Db!] [Error: ENOENT: no such file or directory, rename '/Users/chris/Library/Caches/checkpoint-nodejs/.77865.0' -> '/Users/chris/Library/Caches/checkpoint-nodejs/prisma-studio-default'] {
[Db!] errno: -2,
[Db!] code: 'ENOENT',
[Db!] syscall: 'rename',
[Db!] path: '/Users/chris/Library/Caches/checkpoint-nodejs/.77865.0',
[Db!] dest: '/Users/chris/Library/Caches/checkpoint-nodejs/prisma-studio-default'
[Db!] }
[Db!]
[Db!] Node.js v18.19.0
Internal Wasp error (bug in compiler):
This should never happen, studio should never stop.
CallStack (from HasCallStack):
error, called at cli/src/Wasp/Cli/Command/Db/Studio.hs:29:3 in waspc-0.11.8-inplace-cli-lib:Wasp.Cli.Command.Db.Studio
Looking in that checkpoint-nodejs directory, I see that there is indeed not a file or directory named .77865.0. I see these:
➜ app git:(main) ls /Users/chris/Library/Caches/checkpoint-nodejs/.
prisma-a5a31701 prisma-f3929fa9 prisma-studio-default signature
Do you have any thoughts on what I need to do to get that working again?
At the moment, we only calculate the total revenue from Stripe and display it on the RevenueAndProfitChart
.
It would be great to provide a universal way for Admins to add their costs and calculate their profit to display here as well.
Tasks:
calculateProfit()
function to the daily stats cron job at src/server/workers/calculateDailyStats.ts
.Hello everyone, first of all congratulations for the work done.
Maybe I'm too ignorant :( but I can't understand how the communication between clinet and server takes place in your project managed with wsap.
For example, if I wanted to create a page where on the client side if the user types red the server replies "you won", if he types any other word the server replies "you lost". How should this be implemented?
I created the page src/server/api-google.ts:
export const searchGoogle = async ({ query }) => { if (query === "red") { console.log("you won"); return "you won"; } else { console.log("you lost"); return "you lost"; } };
and the page src/client/app/SearchGooglePage.tsx:
`import React, { useState } from 'react';
import api from '@wasp/api';
const SearchGooglePage = () => {
const [searchQuery, setSearchQuery] = useState('');
const handleSearch = async (event) => {
event.preventDefault();
try {
const result = await api.searchGoogle({ query: searchQuery });
alert(result);
} catch (error) {
console.error('Search failed:', error);
alert('Search failed, please try again.');
}
};
return (
export default SearchGooglePage;
`
and in main.wasp i have added:
api searchGoogle { fn: import { searchGoogle } from "@ext/api-google.js" }
But nothing happens :( could you help me understand this? If I can do this simple exercise I will be able to understand more how client-server communicate.
Many thanks
Added to Discord channel.
In the docs, there is no remark for Windows that it requires users to use WSL. I suggest a similar guide as it was written in the Wasp documentation.
If you think it is useful addition, feel free to assign me to this, and I'll make it happen.
I made sure I had the db running in one shell:
~/Projects/food_truck/open-saas/app $ wasp start db
✨ Starting a PostgreSQL dev database (based on your Wasp config) ✨
Additional info:
ℹ Connection URL, in case you might want to connect with external tools:
postgresql://postgresWaspDevUser:postgresWaspDevPass@localhost:5432/SaaSTemplate-c879beb36e
ℹ Database data is persisted in a docker volume with the following name (useful to know if you will want to delete it at some point):
wasp-dev-db-SaaSTemplate-c879beb36e
...
PostgreSQL Database directory appears to contain a database; Skipping initialization
2024-02-23 14:06:51.382 UTC [1] LOG: starting PostgreSQL 15.1 (Debian 15.1-1.pgdg110+1) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
2024-02-23 14:06:51.382 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
2024-02-23 14:06:51.382 UTC [1] LOG: listening on IPv6 address "::", port 5432
2024-02-23 14:06:51.383 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2024-02-23 14:06:51.386 UTC [28] LOG: database system was shut down at 2024-02-23 14:06:29 UTC
2024-02-23 14:06:51.388 UTC [1] LOG: database system is ready to accept connections
2024-02-23 14:11:51.481 UTC [26] LOG: checkpoint starting: time
2024-02-23 14:11:51.496 UTC [26] LOG: checkpoint complete: wrote 3 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.004 s, sync=0.002 s, total=0.016 s; sync files=2, longest=0.001 s, average=0.001 s; distance=0 kB, estimate=0 kB
confirmed the ports are correct:
~/Projects/food_truck/open-saas/app $ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
234e2b584710 postgres "docker-entrypoint.s…" 6 minutes ago Up 6 minutes 0.0.0.0:5432->5432/tcp wasp-dev-db-SaaSTemplate-c879beb36e
but I still am unable to connect to the db:
~/Projects/food_truck/open-saas/app $ wasp db migrate-dev
🐝 --- Compiling wasp project... --------------------------------------------------
🐝 --- Setting up database... -----------------------------------------------------
✅ --- Database successfully set up. ----------------------------------------------
✅ --- Your wasp project has successfully compiled. -------------------------------
❌ --- [Error] Can not connect to database: ---------------------------------------
The database needs to be running in order to execute this command. You can easily start a managed dev database with `wasp start db`.
I can just nuke and restart, but I dont think i've changed very many things beyond the landing page, so I would like to learn how to troubleshoot this in the future if i get an app more built out.
😅 sorry if this is something obvious and im just missing it.
Community request
When I execute open-saas from command "wasp start" and following settings at main.wasp:
The compile process returns to me this error:
[https://gist.github.com/MiqueiasGFernandes/365a800aa7a1a5b091aad89745be7fc2](Gist URL)
`➜ app git:(main) ✗ wasp start
🐝 --- Starting compilation and setup phase. Hold tight... ------------------------
🐝 --- Compiling wasp project... --------------------------------------------------
❌ --- [Error] Your wasp project failed to compile: -------------------------------
❌ --- [Error] Compilation of wasp project failed: --------------------------------
2 errors found`
Describe the bug
<—A clear and concise description of what the bug is.—>
When you turn on dark mode in the demo page and get redirected from the payment page, the text turns white but the background remains white, therefore invisible.
To Reproduce
Steps to reproduce the behavior:
0. Go to the demo page with the AI scheduler app
Expected behavior
<—A clear and concise description of what you expected to happen.—>
I expected the background to adjust its color for the dark theme.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context
Add any other context about the problem here.
Plausible analytics has the benefit that it's privacy-focused, open-source, and free when you self-host it.
It would be great to add a user-friendly guide on the best/easiest way to do this as a good alternative to Google Analytics
Hello! Are there any plans/PoCs/plugins for using OpenSaaS with KeyCloak? Or contraindications to it?
on
Account page
Checkout page
DemoApp page
Is that the idea, did I get it right? I got across this at https://docs.opensaas.sh/guides/authentication/#google-auth, where it is mentioned to add stuff to .env.server
file, but we never created it in the first place. So I wasn't sure if I should create a new one, reuse the example one or sth else. Would be nice to have some tip about this.
mixtral endpoint is 3x cheaper!
Love the project.
There seems to be some UI responsive issues on mobile screens, specifically the Admin Dashboard. Check out the Users List to replicate the issue.
Let's mention it in the docs somewhere once you clone the repo. The next thing you need to do is change the dir name, and another thing is to change the origin to your own repo. It took me a bit to remember/find out how that is done, so it would be nice to add it to the docs.
Hi, it's possible to add "Keep me signed in" flag on Login form?
I'm opening this in response to this tweet
Good Internationalisation and Localisation can greatly increase the potential market for a service. If you live / work in a country with multiple languages it may even be a hard requirement. (I live in Switzerland, everything needs 2-4 Languages)
I'm proposing to add a default i18n setup to this template, which would entail:
localStorage
to store the language, since SEO isn't as necessary for the AppI am not proposing to ship the template in multiple languages by default, only to have setup in place to add more languages.
I would be happy to contribute this if you're interested!
please add simple to do app with picture upload to open-saas
There is a piece of code at "Getting Started" docs page that has curl ...
command for installing Wasp, but it doesn't say that it is not for native Windows, but for Linux/Mac/WSL. We should mention this, so people don't try it on Windows and get stuck/confused (we had such cases, which is I am writing this).
And allow users to submit the apps they’ve built with Open SaaS, similar to the showcase section for Astro starlight
Is this an intended way to start a new project, by cloning the open-saas repo? It is a bit strange to start out with 102 commits and 8 contributors to the project. I squashed all 102 commits into one, but I'm still left with the contributors.
Maybe that's the why to go, but I'm just wondering what would the best practice be. Another question is how I should apply updates to OS template - e.g. since I started there are 2 new commits that fix bugs. I guess I should just rebase on it.
Maybe adding a few sentences about this in the docs would be helpful.
At the moment, dark mode is only defined and accessible via the Admin Dashboard. The dark mode is configured within Tailwind CSS's dark
class, e.g.:
<Component
className="bg-white dark:bg-black" />
We would like to implement a suitable dark mode theme and make it accessible across the entire app
Currently, the call to the function stripePayment
checks for the following:
if (!context.user || !context.user.email) {
throw new HttpError(401);
}
However, the check for email is not made clear, and the default authentication method does not let a user add an email. This means that the default authentication will never work with stripe integration as-is.
In my opinion, there are a few ways to resolve this:
I can open a PR to fix this, but would like confirmation before going ahead and implementing solution 2
Hi, how easy is it to add Linkedin auth? I don't see this in https://wasp-lang.dev/docs/auth/overview
looks great for international payments
https://docs.cloud.coinbase.com/commerce-onchain/docs/getting-started
Can it support lemonsqueezy’s payment system?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.