Define the WASP_SERVER_URL env var (#1856)

This commit is contained in:
Mihovil Ilakovac 2024-03-18 12:56:46 +01:00
parent 4c3216f349
commit 7329465974
44 changed files with 224 additions and 119 deletions

View File

@ -1,6 +1,10 @@
# Changelog
## 0.12.4 (2024-03-12)
## 0.13.0 (2024-03-18)
### 🎉 New features
- Wasp now supports defining the `WASP_SERVER_URL` environment variable and exposes it as `serverUrl` in the server config which can be imported from `wasp/server`.
### 🐞 Bug fixes
@ -173,13 +177,13 @@ By adding a `vite.config.ts` or `vite.config.js` to your `client` directory, you
not to open the browser automatically:
```ts
import { defineConfig } from 'vite'
import { defineConfig } from "vite";
export default defineConfig({
server: {
open: false,
},
})
});
```
⚠️ Be careful when changing the dev server port, you'll need to update the `WASP_WEB_CLIENT_URL` env var in your `.env.server` file.
@ -221,27 +225,27 @@ app crudTesting {
Then, you need to define the `fields` object in your `auth.js` file:
```js
import { defineAdditionalSignupFields } from '@wasp/auth/index.js'
import { defineAdditionalSignupFields } from "@wasp/auth/index.js";
export const fields = defineAdditionalSignupFields({
address: (data) => {
// Validate the address field
if (typeof data.address !== 'string') {
throw new Error('Address is required.')
if (typeof data.address !== "string") {
throw new Error("Address is required.");
}
if (data.address.length < 10) {
throw new Error('Address must be at least 10 characters long.')
throw new Error("Address must be at least 10 characters long.");
}
// Return the address field
return data.address
return data.address;
},
})
});
```
Finally, you can extend the `SignupForm` component on the client:
```jsx
import { SignupForm } from '@wasp/auth/forms/Signup'
import { SignupForm } from "@wasp/auth/forms/Signup";
export const SignupPage = () => {
return (
@ -251,19 +255,19 @@ export const SignupPage = () => {
<SignupForm
additionalFields={[
{
name: 'address',
label: 'Address',
type: 'input',
name: "address",
label: "Address",
type: "input",
validations: {
required: 'Address is required',
required: "Address is required",
},
},
]}
/>
</main>
</div>
)
}
);
};
```
### 🎉 [New Feature] Support for PostgreSQL Extensions
@ -305,8 +309,8 @@ job simplePrintJob {
```
```typescript
import { SimplePrintJob } from '@wasp/jobs/simplePrintJob'
import { Task } from '@wasp/entities'
import { SimplePrintJob } from "@wasp/jobs/simplePrintJob";
import { Task } from "@wasp/entities";
export const simplePrint: SimplePrintJob<
{ name: string },
@ -314,11 +318,11 @@ export const simplePrint: SimplePrintJob<
> = async (args, context) => {
// 👆 args are typed e.g. { name: string }
// 👆 context is typed e.g. { entitites: { Task: ... } }
const tasks = await context.entities.Task.findMany({})
const tasks = await context.entities.Task.findMany({});
return {
tasks,
}
}
};
};
```
When you use the job, you can pass the arguments and receive the result with the correct types:
@ -373,9 +377,9 @@ export const TaskList = () => {
You can also get all the pages in your app with the `routes` object:
```jsx
import { routes } from '@wasp/router'
import { routes } from "@wasp/router";
const linkToTask = routes.TaskRoute({ params: { id: 1 } })
const linkToTask = routes.TaskRoute({ params: { id: 1 } });
```
### 🐞 Bug fixes
@ -499,67 +503,67 @@ app todoApp {
Then implement it on the server with optional types:
```typescript
import type { WebSocketDefinition } from '@wasp/webSocket'
import type { WebSocketDefinition } from "@wasp/webSocket";
export const webSocketFn: WebSocketFn = (io, context) => {
io.on('connection', (socket) => {
io.on("connection", (socket) => {
// ...
})
}
});
};
type WebSocketFn = WebSocketDefinition<
ClientToServerEvents,
ServerToClientEvents
>
>;
interface ServerToClientEvents {
chatMessage: (msg: { id: string; username: string; text: string }) => void
chatMessage: (msg: { id: string; username: string; text: string }) => void;
}
interface ClientToServerEvents {
chatMessage: (msg: string) => void
chatMessage: (msg: string) => void;
}
```
And use it on the client with automatic type inference:
```typescript
import React, { useState } from 'react'
import React, { useState } from "react";
import {
useSocket,
useSocketListener,
ServerToClientPayload,
} from '@wasp/webSocket'
} from "@wasp/webSocket";
export const ChatPage = () => {
const [messageText, setMessageText] = useState<
// We are using a helper type to get the payload type for the "chatMessage" event.
ClientToServerPayload<'chatMessage'>
>('')
ClientToServerPayload<"chatMessage">
>("");
const [messages, setMessages] = useState<
ServerToClientPayload<'chatMessage'>[]
>([])
ServerToClientPayload<"chatMessage">[]
>([]);
// The "socket" instance is typed with the types you defined on the server.
const { socket, isConnected } = useSocket()
const { socket, isConnected } = useSocket();
// This is a type-safe event handler: "chatMessage" event and its payload type
// are defined on the server.
useSocketListener('chatMessage', logMessage)
useSocketListener("chatMessage", logMessage);
function logMessage(msg: ServerToClientPayload<'chatMessage'>) {
setMessages((priorMessages) => [msg, ...priorMessages])
function logMessage(msg: ServerToClientPayload<"chatMessage">) {
setMessages((priorMessages) => [msg, ...priorMessages]);
}
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault()
e.preventDefault();
// This is a type-safe event emitter: "chatMessage" event and its payload type
// are defined on the server.
socket.emit('chatMessage', messageText)
socket.emit("chatMessage", messageText);
// ...
}
// ...
}
};
```
### 🎉 [New feature] Automatic CRUD backend generation
@ -588,21 +592,21 @@ crud Tasks {
This gives us the following operations: `getAll`, `get`, `create`, `update` and `delete`, which we can use in our client like this:
```typescript
import { Tasks } from '@wasp/crud/Tasks'
import { useState } from 'react'
import { Tasks } from "@wasp/crud/Tasks";
import { useState } from "react";
export const MainPage = () => {
const { data: tasks, isLoading, error } = Tasks.getAll.useQuery()
const createTask = Tasks.create.useAction()
const { data: tasks, isLoading, error } = Tasks.getAll.useQuery();
const createTask = Tasks.create.useAction();
// ...
function handleCreateTask() {
createTask({ description: taskDescription, isDone: false })
setTaskDescription('')
createTask({ description: taskDescription, isDone: false });
setTaskDescription("");
}
// ...
}
};
```
### 🎉 [New feature] IDE tooling improvements
@ -723,20 +727,20 @@ Frontend code can now infer correct payload/response types for Queries and Actio
Define a Query on the server:
```typescript
export const getTask: GetTaskInfo<Pick<Task, 'id'>, Task> = async (
export const getTask: GetTaskInfo<Pick<Task, "id">, Task> = async (
{ id },
context
) => {
// ...
}
};
```
Get properly typed functions and data on the frontend:
```typescript
import { useQuery } from '@wasp/queries'
import { useQuery } from "@wasp/queries";
// Wasp knows the type of `getTask` thanks to your backend definition.
import getTask from '@wasp/queries/getTask'
import getTask from "@wasp/queries/getTask";
export const TaskInfo = () => {
const {
@ -749,10 +753,12 @@ export const TaskInfo = () => {
error,
// TypeScript knows the second argument must be a `Pick<Task, "id">` thanks
// to the backend definition.
} = useQuery(getTask, { id: 1 })
} = useQuery(getTask, { id: 1 });
if (isError) {
return <div> Error during fetching tasks: {error.message || 'unknown'}</div>
return (
<div> Error during fetching tasks: {error.message || "unknown"}</div>
);
}
// TypeScript forces you to perform this check.
@ -760,8 +766,8 @@ export const TaskInfo = () => {
<div>Waiting for info...</div>
) : (
<div>{taskInfo}</div>
)
}
);
};
```
The same feature is available for Actions.
@ -773,25 +779,25 @@ Client and the server can now communicate with richer payloads.
Return a Superjson-compatible object from your Operation:
```typescript
type FooInfo = { foos: Foo[]; message: string; queriedAt: Date }
type FooInfo = { foos: Foo[]; message: string; queriedAt: Date };
const getFoos: GetFoo<void, FooInfo> = (_args, context) => {
const foos = context.entities.Foo.findMany()
const foos = context.entities.Foo.findMany();
return {
foos,
message: 'Here are some foos!',
message: "Here are some foos!",
queriedAt: new Date(),
}
}
};
};
```
And seamlessly use it on the frontend:
```typescript
import getfoos from '@wasp/queries/getTask'
import getfoos from "@wasp/queries/getTask";
const { data } = useQuery(getfoos)
const { foos, message, queriedAt } = data
const { data } = useQuery(getfoos);
const { foos, message, queriedAt } = data;
// foos: Foo[]
// message: string
// queriedAt: Date
@ -834,11 +840,11 @@ Wasp now provides a set of UI components for authentication. You can use them to
We provide `LoginForm`, `SignupForm`, `ForgotPassworForm`, `ResetPasswordForm` and`VerifyEmailForm` components. You can import them from `@wasp/auth/forms` like:
```js
import { LoginForm } from '@wasp/auth/forms/Login'
import { SignupForm } from '@wasp/auth/forms/Signup'
import { ForgotPasswordForm } from '@wasp/auth/forms/ForgotPassword'
import { ResetPasswordForm } from '@wasp/auth/forms/ResetPassword'
import { VerifyEmailForm } from '@wasp/auth/forms/VerifyEmail'
import { LoginForm } from "@wasp/auth/forms/Login";
import { SignupForm } from "@wasp/auth/forms/Signup";
import { ForgotPasswordForm } from "@wasp/auth/forms/ForgotPassword";
import { ResetPasswordForm } from "@wasp/auth/forms/ResetPassword";
import { VerifyEmailForm } from "@wasp/auth/forms/VerifyEmail";
```
### Database seeding
@ -858,18 +864,18 @@ app MyApp {
```
```js
import { createTask } from './actions.js'
import { createTask } from "./actions.js";
export const devSeedSimple = async (prismaClient) => {
const { password, ...newUser } = await prismaClient.user.create({
username: 'RiuTheDog',
password: 'bark1234',
})
username: "RiuTheDog",
password: "bark1234",
});
await createTask(
{ description: 'Chase the cat' },
{ description: "Chase the cat" },
{ user: newUser, entities: { Task: prismaClient.task } }
)
}
);
};
//...
```
@ -1011,17 +1017,17 @@ And here's how you can to the same in a frontend file:
```typescript
// ...
import { useQuery } from '@wasp/queries'
import getTasks from '@wasp/queries/getTasks.js'
import { Task } from '@wasp/entities'
import { useQuery } from "@wasp/queries";
import getTasks from "@wasp/queries/getTasks.js";
import { Task } from "@wasp/entities";
type TaskPayload = Pick<Task, 'id'>
type TaskPayload = Pick<Task, "id">;
const Todo = (props: any) => {
// The variable 'task' will now have the type Task.
const { data: task } = useQuery<TaskPayload, Task>(getTask, { id: taskId })
const { data: task } = useQuery<TaskPayload, Task>(getTask, { id: taskId });
// ...
}
};
```
### Automatically generated types for Queries and Actions
@ -1041,10 +1047,10 @@ query getTasks {
You'll get the following feature:
```typescript
import { Task } from '@wasp/entities'
import { GetTasks } from '@wasp/queries'
import { Task } from "@wasp/entities";
import { GetTasks } from "@wasp/queries";
type Payload = Pick<Task, 'isDone'>
type Payload = Pick<Task, "isDone">;
// Use the type parameters to specify the Query's argument and return types.
const getTasks: GetTasks<Payload, Task[]> = (args, context) => {
@ -1056,7 +1062,7 @@ const getTasks: GetTasks<Payload, Task[]> = (args, context) => {
//
// Thanks to the second type argument in `GetTasks`, the compiler knows the
// function must return a value of type `Task[]`.
}
};
```
### Uninstall command

View File

@ -1,9 +1,10 @@
{{={= =}=}}
import { stripTrailingSlash } from 'wasp/universal/url'
const apiUrl = stripTrailingSlash(import.meta.env.REACT_APP_API_URL) || 'http://localhost:3001';
const apiUrl = stripTrailingSlash(import.meta.env.REACT_APP_API_URL) || '{= defaultServerUrl =}';
const config = {
apiUrl,
}
export default config
export default config

View File

@ -28,6 +28,7 @@ type CommonConfig = BaseConfig & {
type EnvConfig = BaseConfig & {
frontendUrl: string;
serverUrl: string;
}
type Config = CommonConfig & EnvConfig
@ -40,7 +41,7 @@ const config: {
all: {
env,
isDevelopment: env === 'development',
port: parseInt(process.env.PORT) || 3001,
port: parseInt(process.env.PORT) || {= defaultServerPort =},
databaseUrl: process.env.{= databaseUrlEnvVarName =},
allowedCORSOrigins: [],
{=# isAuthEnabled =}
@ -59,8 +60,10 @@ export default resolvedConfig
function getDevelopmentConfig(): EnvConfig {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL || '{= defaultClientUrl =}');
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL || '{= defaultServerUrl =}');
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: '*',
{=# isAuthEnabled =}
auth: {
@ -72,8 +75,10 @@ function getDevelopmentConfig(): EnvConfig {
function getProductionConfig(): EnvConfig {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL);
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL);
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: [frontendUrl],
{=# isAuthEnabled =}
auth: {

View File

@ -2,3 +2,4 @@ import { throwIfNotValidAbsoluteURL } from 'wasp/universal/validators';
console.info("🔍 Validating environment variables...");
throwIfNotValidAbsoluteURL(process.env.WASP_WEB_CLIENT_URL, 'Environment variable WASP_WEB_CLIENT_URL');
throwIfNotValidAbsoluteURL(process.env.WASP_SERVER_URL, 'Environment variable WASP_SERVER_URL');

View File

@ -242,7 +242,7 @@
"file",
"../out/sdk/wasp/server/config.ts"
],
"4976e545d8fcf019508e95f472305e9ef27dfb3423c71e428a5414e35cdd52be"
"e5388a9259a22671ee2d2ef46d2c09fdd46c3b3ec24248c7a0b471c0fbf7aa54"
],
[
[
@ -424,7 +424,7 @@
"file",
"server/scripts/validate-env.mjs"
],
"65168a764fc6cbe785ee40a8e8533b4694ef9019fc5a73f60f7252152330d0a2"
"100177b4326ccab7362eff378315d532ad1cc17cd28d1ed5978cb167fd627746"
],
[
[

View File

@ -9,6 +9,7 @@ type CommonConfig = BaseConfig & {
};
type EnvConfig = BaseConfig & {
frontendUrl: string;
serverUrl: string;
};
type Config = CommonConfig & EnvConfig;
declare const resolvedConfig: Config;

View File

@ -17,15 +17,19 @@ const resolvedConfig = merge(config.all, config[env]);
export default resolvedConfig;
function getDevelopmentConfig() {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL || 'http://localhost:3000/');
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL || 'http://localhost:3001');
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: '*',
};
}
function getProductionConfig() {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL);
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL);
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: [frontendUrl],
};
}

View File

@ -1 +1 @@
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../server/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,cAAc,CAAA;AAEhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAA;AAwBjD,MAAM,MAAM,GAIR;IACF,GAAG,EAAE;QACH,GAAG;QACH,aAAa,EAAE,GAAG,KAAK,aAAa;QACpC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI;QACxC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QACrC,kBAAkB,EAAE,EAAE;KACvB;IACD,WAAW,EAAE,oBAAoB,EAAE;IACnC,UAAU,EAAE,mBAAmB,EAAE;CAClC,CAAA;AAED,MAAM,cAAc,GAAW,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;AAC7D,aAAa;AACb,eAAe,cAAc,CAAA;AAE7B,SAAS,oBAAoB;IAC3B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,CAAC,CAAC;IACpG,OAAO;QACL,WAAW;QACX,kBAAkB,EAAE,GAAG;KACxB,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACxE,OAAO;QACL,WAAW;QACX,kBAAkB,EAAE,CAAC,WAAW,CAAC;KAClC,CAAA;AACH,CAAC"}
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../server/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,cAAc,CAAA;AAEhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAA;AAyBjD,MAAM,MAAM,GAIR;IACF,GAAG,EAAE;QACH,GAAG;QACH,aAAa,EAAE,GAAG,KAAK,aAAa;QACpC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI;QACxC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QACrC,kBAAkB,EAAE,EAAE;KACvB;IACD,WAAW,EAAE,oBAAoB,EAAE;IACnC,UAAU,EAAE,mBAAmB,EAAE;CAClC,CAAA;AAED,MAAM,cAAc,GAAW,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;AAC7D,aAAa;AACb,eAAe,cAAc,CAAA;AAE7B,SAAS,oBAAoB;IAC3B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,CAAC,CAAC;IACpG,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,uBAAuB,CAAC,CAAC;IAC7F,OAAO;QACL,WAAW;QACX,SAAS;QACT,kBAAkB,EAAE,GAAG;KACxB,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACxE,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAClE,OAAO;QACL,WAAW;QACX,SAAS;QACT,kBAAkB,EAAE,CAAC,WAAW,CAAC;KAClC,CAAA;AACH,CAAC"}

View File

@ -22,6 +22,7 @@ type CommonConfig = BaseConfig & {
type EnvConfig = BaseConfig & {
frontendUrl: string;
serverUrl: string;
}
type Config = CommonConfig & EnvConfig
@ -48,16 +49,20 @@ export default resolvedConfig
function getDevelopmentConfig(): EnvConfig {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL || 'http://localhost:3000/');
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL || 'http://localhost:3001');
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: '*',
}
}
function getProductionConfig(): EnvConfig {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL);
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL);
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: [frontendUrl],
}
}

View File

@ -2,3 +2,4 @@ import { throwIfNotValidAbsoluteURL } from 'wasp/universal/validators';
console.info("🔍 Validating environment variables...");
throwIfNotValidAbsoluteURL(process.env.WASP_WEB_CLIENT_URL, 'Environment variable WASP_WEB_CLIENT_URL');
throwIfNotValidAbsoluteURL(process.env.WASP_SERVER_URL, 'Environment variable WASP_SERVER_URL');

View File

@ -9,6 +9,7 @@ type CommonConfig = BaseConfig & {
};
type EnvConfig = BaseConfig & {
frontendUrl: string;
serverUrl: string;
};
type Config = CommonConfig & EnvConfig;
declare const resolvedConfig: Config;

View File

@ -17,15 +17,19 @@ const resolvedConfig = merge(config.all, config[env]);
export default resolvedConfig;
function getDevelopmentConfig() {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL || 'http://localhost:3000/');
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL || 'http://localhost:3001');
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: '*',
};
}
function getProductionConfig() {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL);
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL);
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: [frontendUrl],
};
}

View File

@ -1 +1 @@
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../server/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,cAAc,CAAA;AAEhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAA;AAwBjD,MAAM,MAAM,GAIR;IACF,GAAG,EAAE;QACH,GAAG;QACH,aAAa,EAAE,GAAG,KAAK,aAAa;QACpC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI;QACxC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QACrC,kBAAkB,EAAE,EAAE;KACvB;IACD,WAAW,EAAE,oBAAoB,EAAE;IACnC,UAAU,EAAE,mBAAmB,EAAE;CAClC,CAAA;AAED,MAAM,cAAc,GAAW,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;AAC7D,aAAa;AACb,eAAe,cAAc,CAAA;AAE7B,SAAS,oBAAoB;IAC3B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,CAAC,CAAC;IACpG,OAAO;QACL,WAAW;QACX,kBAAkB,EAAE,GAAG;KACxB,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACxE,OAAO;QACL,WAAW;QACX,kBAAkB,EAAE,CAAC,WAAW,CAAC;KAClC,CAAA;AACH,CAAC"}
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../server/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,cAAc,CAAA;AAEhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAA;AAyBjD,MAAM,MAAM,GAIR;IACF,GAAG,EAAE;QACH,GAAG;QACH,aAAa,EAAE,GAAG,KAAK,aAAa;QACpC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI;QACxC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QACrC,kBAAkB,EAAE,EAAE;KACvB;IACD,WAAW,EAAE,oBAAoB,EAAE;IACnC,UAAU,EAAE,mBAAmB,EAAE;CAClC,CAAA;AAED,MAAM,cAAc,GAAW,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;AAC7D,aAAa;AACb,eAAe,cAAc,CAAA;AAE7B,SAAS,oBAAoB;IAC3B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,CAAC,CAAC;IACpG,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,uBAAuB,CAAC,CAAC;IAC7F,OAAO;QACL,WAAW;QACX,SAAS;QACT,kBAAkB,EAAE,GAAG;KACxB,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACxE,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAClE,OAAO;QACL,WAAW;QACX,SAAS;QACT,kBAAkB,EAAE,CAAC,WAAW,CAAC;KAClC,CAAA;AACH,CAAC"}

View File

@ -22,6 +22,7 @@ type CommonConfig = BaseConfig & {
type EnvConfig = BaseConfig & {
frontendUrl: string;
serverUrl: string;
}
type Config = CommonConfig & EnvConfig
@ -48,16 +49,20 @@ export default resolvedConfig
function getDevelopmentConfig(): EnvConfig {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL || 'http://localhost:3000/');
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL || 'http://localhost:3001');
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: '*',
}
}
function getProductionConfig(): EnvConfig {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL);
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL);
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: [frontendUrl],
}
}

View File

@ -242,7 +242,7 @@
"file",
"../out/sdk/wasp/server/config.ts"
],
"4976e545d8fcf019508e95f472305e9ef27dfb3423c71e428a5414e35cdd52be"
"e5388a9259a22671ee2d2ef46d2c09fdd46c3b3ec24248c7a0b471c0fbf7aa54"
],
[
[
@ -431,7 +431,7 @@
"file",
"server/scripts/validate-env.mjs"
],
"65168a764fc6cbe785ee40a8e8533b4694ef9019fc5a73f60f7252152330d0a2"
"100177b4326ccab7362eff378315d532ad1cc17cd28d1ed5978cb167fd627746"
],
[
[

View File

@ -9,6 +9,7 @@ type CommonConfig = BaseConfig & {
};
type EnvConfig = BaseConfig & {
frontendUrl: string;
serverUrl: string;
};
type Config = CommonConfig & EnvConfig;
declare const resolvedConfig: Config;

View File

@ -17,15 +17,19 @@ const resolvedConfig = merge(config.all, config[env]);
export default resolvedConfig;
function getDevelopmentConfig() {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL || 'http://localhost:3000/');
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL || 'http://localhost:3001');
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: '*',
};
}
function getProductionConfig() {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL);
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL);
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: [frontendUrl],
};
}

View File

@ -1 +1 @@
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../server/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,cAAc,CAAA;AAEhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAA;AAwBjD,MAAM,MAAM,GAIR;IACF,GAAG,EAAE;QACH,GAAG;QACH,aAAa,EAAE,GAAG,KAAK,aAAa;QACpC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI;QACxC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QACrC,kBAAkB,EAAE,EAAE;KACvB;IACD,WAAW,EAAE,oBAAoB,EAAE;IACnC,UAAU,EAAE,mBAAmB,EAAE;CAClC,CAAA;AAED,MAAM,cAAc,GAAW,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;AAC7D,aAAa;AACb,eAAe,cAAc,CAAA;AAE7B,SAAS,oBAAoB;IAC3B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,CAAC,CAAC;IACpG,OAAO;QACL,WAAW;QACX,kBAAkB,EAAE,GAAG;KACxB,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACxE,OAAO;QACL,WAAW;QACX,kBAAkB,EAAE,CAAC,WAAW,CAAC;KAClC,CAAA;AACH,CAAC"}
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../server/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,cAAc,CAAA;AAEhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAA;AAyBjD,MAAM,MAAM,GAIR;IACF,GAAG,EAAE;QACH,GAAG;QACH,aAAa,EAAE,GAAG,KAAK,aAAa;QACpC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI;QACxC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QACrC,kBAAkB,EAAE,EAAE;KACvB;IACD,WAAW,EAAE,oBAAoB,EAAE;IACnC,UAAU,EAAE,mBAAmB,EAAE;CAClC,CAAA;AAED,MAAM,cAAc,GAAW,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;AAC7D,aAAa;AACb,eAAe,cAAc,CAAA;AAE7B,SAAS,oBAAoB;IAC3B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,CAAC,CAAC;IACpG,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,uBAAuB,CAAC,CAAC;IAC7F,OAAO;QACL,WAAW;QACX,SAAS;QACT,kBAAkB,EAAE,GAAG;KACxB,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACxE,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAClE,OAAO;QACL,WAAW;QACX,SAAS;QACT,kBAAkB,EAAE,CAAC,WAAW,CAAC;KAClC,CAAA;AACH,CAAC"}

View File

@ -22,6 +22,7 @@ type CommonConfig = BaseConfig & {
type EnvConfig = BaseConfig & {
frontendUrl: string;
serverUrl: string;
}
type Config = CommonConfig & EnvConfig
@ -48,16 +49,20 @@ export default resolvedConfig
function getDevelopmentConfig(): EnvConfig {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL || 'http://localhost:3000/');
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL || 'http://localhost:3001');
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: '*',
}
}
function getProductionConfig(): EnvConfig {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL);
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL);
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: [frontendUrl],
}
}

View File

@ -2,3 +2,4 @@ import { throwIfNotValidAbsoluteURL } from 'wasp/universal/validators';
console.info("🔍 Validating environment variables...");
throwIfNotValidAbsoluteURL(process.env.WASP_WEB_CLIENT_URL, 'Environment variable WASP_WEB_CLIENT_URL');
throwIfNotValidAbsoluteURL(process.env.WASP_SERVER_URL, 'Environment variable WASP_SERVER_URL');

View File

@ -529,7 +529,7 @@
"file",
"../out/sdk/wasp/server/config.ts"
],
"5d933eb55d44f4c3c42df7e8387dbd4b8b02f47191e59ee50d59c08a1f86634e"
"0cb590d15087323479f4a0e3622c464b6f172979e01a35c71521d31f6457a46f"
],
[
[
@ -823,7 +823,7 @@
"file",
"server/scripts/validate-env.mjs"
],
"65168a764fc6cbe785ee40a8e8533b4694ef9019fc5a73f60f7252152330d0a2"
"100177b4326ccab7362eff378315d532ad1cc17cd28d1ed5978cb167fd627746"
],
[
[

View File

@ -12,6 +12,7 @@ type CommonConfig = BaseConfig & {
};
type EnvConfig = BaseConfig & {
frontendUrl: string;
serverUrl: string;
};
type Config = CommonConfig & EnvConfig;
declare const resolvedConfig: Config;

View File

@ -20,8 +20,10 @@ const resolvedConfig = merge(config.all, config[env]);
export default resolvedConfig;
function getDevelopmentConfig() {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL || 'http://localhost:3000/');
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL || 'http://localhost:3001');
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: '*',
auth: {
jwtSecret: 'DEVJWTSECRET'
@ -30,8 +32,10 @@ function getDevelopmentConfig() {
}
function getProductionConfig() {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL);
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL);
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: [frontendUrl],
auth: {
jwtSecret: process.env.JWT_SECRET

View File

@ -1 +1 @@
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../server/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,cAAc,CAAA;AAEhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAA;AA2BjD,MAAM,MAAM,GAIR;IACF,GAAG,EAAE;QACH,GAAG;QACH,aAAa,EAAE,GAAG,KAAK,aAAa;QACpC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI;QACxC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QACrC,kBAAkB,EAAE,EAAE;QACtB,IAAI,EAAE;YACJ,SAAS,EAAE,SAAS;SACrB;KACF;IACD,WAAW,EAAE,oBAAoB,EAAE;IACnC,UAAU,EAAE,mBAAmB,EAAE;CAClC,CAAA;AAED,MAAM,cAAc,GAAW,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;AAC7D,aAAa;AACb,eAAe,cAAc,CAAA;AAE7B,SAAS,oBAAoB;IAC3B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,CAAC,CAAC;IACpG,OAAO;QACL,WAAW;QACX,kBAAkB,EAAE,GAAG;QACvB,IAAI,EAAE;YACJ,SAAS,EAAE,cAAc;SAC1B;KACF,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACxE,OAAO;QACL,WAAW;QACX,kBAAkB,EAAE,CAAC,WAAW,CAAC;QACjC,IAAI,EAAE;YACJ,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU;SAClC;KACF,CAAA;AACH,CAAC"}
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../server/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,cAAc,CAAA;AAEhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAA;AA4BjD,MAAM,MAAM,GAIR;IACF,GAAG,EAAE;QACH,GAAG;QACH,aAAa,EAAE,GAAG,KAAK,aAAa;QACpC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI;QACxC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QACrC,kBAAkB,EAAE,EAAE;QACtB,IAAI,EAAE;YACJ,SAAS,EAAE,SAAS;SACrB;KACF;IACD,WAAW,EAAE,oBAAoB,EAAE;IACnC,UAAU,EAAE,mBAAmB,EAAE;CAClC,CAAA;AAED,MAAM,cAAc,GAAW,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;AAC7D,aAAa;AACb,eAAe,cAAc,CAAA;AAE7B,SAAS,oBAAoB;IAC3B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,CAAC,CAAC;IACpG,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,uBAAuB,CAAC,CAAC;IAC7F,OAAO;QACL,WAAW;QACX,SAAS;QACT,kBAAkB,EAAE,GAAG;QACvB,IAAI,EAAE;YACJ,SAAS,EAAE,cAAc;SAC1B;KACF,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACxE,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAClE,OAAO;QACL,WAAW;QACX,SAAS;QACT,kBAAkB,EAAE,CAAC,WAAW,CAAC;QACjC,IAAI,EAAE;YACJ,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU;SAClC;KACF,CAAA;AACH,CAAC"}

View File

@ -25,6 +25,7 @@ type CommonConfig = BaseConfig & {
type EnvConfig = BaseConfig & {
frontendUrl: string;
serverUrl: string;
}
type Config = CommonConfig & EnvConfig
@ -54,8 +55,10 @@ export default resolvedConfig
function getDevelopmentConfig(): EnvConfig {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL || 'http://localhost:3000/');
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL || 'http://localhost:3001');
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: '*',
auth: {
jwtSecret: 'DEVJWTSECRET'
@ -65,8 +68,10 @@ function getDevelopmentConfig(): EnvConfig {
function getProductionConfig(): EnvConfig {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL);
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL);
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: [frontendUrl],
auth: {
jwtSecret: process.env.JWT_SECRET

View File

@ -2,3 +2,4 @@ import { throwIfNotValidAbsoluteURL } from 'wasp/universal/validators';
console.info("🔍 Validating environment variables...");
throwIfNotValidAbsoluteURL(process.env.WASP_WEB_CLIENT_URL, 'Environment variable WASP_WEB_CLIENT_URL');
throwIfNotValidAbsoluteURL(process.env.WASP_SERVER_URL, 'Environment variable WASP_SERVER_URL');

View File

@ -249,7 +249,7 @@
"file",
"../out/sdk/wasp/server/config.ts"
],
"4976e545d8fcf019508e95f472305e9ef27dfb3423c71e428a5414e35cdd52be"
"e5388a9259a22671ee2d2ef46d2c09fdd46c3b3ec24248c7a0b471c0fbf7aa54"
],
[
[
@ -487,7 +487,7 @@
"file",
"server/scripts/validate-env.mjs"
],
"65168a764fc6cbe785ee40a8e8533b4694ef9019fc5a73f60f7252152330d0a2"
"100177b4326ccab7362eff378315d532ad1cc17cd28d1ed5978cb167fd627746"
],
[
[

View File

@ -9,6 +9,7 @@ type CommonConfig = BaseConfig & {
};
type EnvConfig = BaseConfig & {
frontendUrl: string;
serverUrl: string;
};
type Config = CommonConfig & EnvConfig;
declare const resolvedConfig: Config;

View File

@ -17,15 +17,19 @@ const resolvedConfig = merge(config.all, config[env]);
export default resolvedConfig;
function getDevelopmentConfig() {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL || 'http://localhost:3000/');
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL || 'http://localhost:3001');
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: '*',
};
}
function getProductionConfig() {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL);
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL);
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: [frontendUrl],
};
}

View File

@ -1 +1 @@
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../server/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,cAAc,CAAA;AAEhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAA;AAwBjD,MAAM,MAAM,GAIR;IACF,GAAG,EAAE;QACH,GAAG;QACH,aAAa,EAAE,GAAG,KAAK,aAAa;QACpC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI;QACxC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QACrC,kBAAkB,EAAE,EAAE;KACvB;IACD,WAAW,EAAE,oBAAoB,EAAE;IACnC,UAAU,EAAE,mBAAmB,EAAE;CAClC,CAAA;AAED,MAAM,cAAc,GAAW,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;AAC7D,aAAa;AACb,eAAe,cAAc,CAAA;AAE7B,SAAS,oBAAoB;IAC3B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,CAAC,CAAC;IACpG,OAAO;QACL,WAAW;QACX,kBAAkB,EAAE,GAAG;KACxB,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACxE,OAAO;QACL,WAAW;QACX,kBAAkB,EAAE,CAAC,WAAW,CAAC;KAClC,CAAA;AACH,CAAC"}
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../server/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,cAAc,CAAA;AAEhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAA;AAyBjD,MAAM,MAAM,GAIR;IACF,GAAG,EAAE;QACH,GAAG;QACH,aAAa,EAAE,GAAG,KAAK,aAAa;QACpC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI;QACxC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QACrC,kBAAkB,EAAE,EAAE;KACvB;IACD,WAAW,EAAE,oBAAoB,EAAE;IACnC,UAAU,EAAE,mBAAmB,EAAE;CAClC,CAAA;AAED,MAAM,cAAc,GAAW,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;AAC7D,aAAa;AACb,eAAe,cAAc,CAAA;AAE7B,SAAS,oBAAoB;IAC3B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,CAAC,CAAC;IACpG,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,uBAAuB,CAAC,CAAC;IAC7F,OAAO;QACL,WAAW;QACX,SAAS;QACT,kBAAkB,EAAE,GAAG;KACxB,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACxE,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAClE,OAAO;QACL,WAAW;QACX,SAAS;QACT,kBAAkB,EAAE,CAAC,WAAW,CAAC;KAClC,CAAA;AACH,CAAC"}

View File

@ -22,6 +22,7 @@ type CommonConfig = BaseConfig & {
type EnvConfig = BaseConfig & {
frontendUrl: string;
serverUrl: string;
}
type Config = CommonConfig & EnvConfig
@ -48,16 +49,20 @@ export default resolvedConfig
function getDevelopmentConfig(): EnvConfig {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL || 'http://localhost:3000/');
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL || 'http://localhost:3001');
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: '*',
}
}
function getProductionConfig(): EnvConfig {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL);
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL);
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: [frontendUrl],
}
}

View File

@ -2,3 +2,4 @@ import { throwIfNotValidAbsoluteURL } from 'wasp/universal/validators';
console.info("🔍 Validating environment variables...");
throwIfNotValidAbsoluteURL(process.env.WASP_WEB_CLIENT_URL, 'Environment variable WASP_WEB_CLIENT_URL');
throwIfNotValidAbsoluteURL(process.env.WASP_SERVER_URL, 'Environment variable WASP_SERVER_URL');

View File

@ -242,7 +242,7 @@
"file",
"../out/sdk/wasp/server/config.ts"
],
"4976e545d8fcf019508e95f472305e9ef27dfb3423c71e428a5414e35cdd52be"
"e5388a9259a22671ee2d2ef46d2c09fdd46c3b3ec24248c7a0b471c0fbf7aa54"
],
[
[
@ -431,7 +431,7 @@
"file",
"server/scripts/validate-env.mjs"
],
"65168a764fc6cbe785ee40a8e8533b4694ef9019fc5a73f60f7252152330d0a2"
"100177b4326ccab7362eff378315d532ad1cc17cd28d1ed5978cb167fd627746"
],
[
[

View File

@ -1,6 +1,7 @@
{{={= =}=}}
import { stripTrailingSlash } from 'wasp/universal/url'
const apiUrl = stripTrailingSlash(import.meta.env.REACT_APP_API_URL) || 'http://localhost:3001';
const apiUrl = stripTrailingSlash(import.meta.env.REACT_APP_API_URL) || '{= defaultServerUrl =}';
const config = {
apiUrl,

View File

@ -9,6 +9,7 @@ type CommonConfig = BaseConfig & {
};
type EnvConfig = BaseConfig & {
frontendUrl: string;
serverUrl: string;
};
type Config = CommonConfig & EnvConfig;
declare const resolvedConfig: Config;

View File

@ -17,15 +17,19 @@ const resolvedConfig = merge(config.all, config[env]);
export default resolvedConfig;
function getDevelopmentConfig() {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL || 'http://localhost:3000/');
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL || 'http://localhost:3001');
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: '*',
};
}
function getProductionConfig() {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL);
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL);
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: [frontendUrl],
};
}

View File

@ -1 +1 @@
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../server/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,cAAc,CAAA;AAEhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAA;AAwBjD,MAAM,MAAM,GAIR;IACF,GAAG,EAAE;QACH,GAAG;QACH,aAAa,EAAE,GAAG,KAAK,aAAa;QACpC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI;QACxC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QACrC,kBAAkB,EAAE,EAAE;KACvB;IACD,WAAW,EAAE,oBAAoB,EAAE;IACnC,UAAU,EAAE,mBAAmB,EAAE;CAClC,CAAA;AAED,MAAM,cAAc,GAAW,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;AAC7D,aAAa;AACb,eAAe,cAAc,CAAA;AAE7B,SAAS,oBAAoB;IAC3B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,CAAC,CAAC;IACpG,OAAO;QACL,WAAW;QACX,kBAAkB,EAAE,GAAG;KACxB,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACxE,OAAO;QACL,WAAW;QACX,kBAAkB,EAAE,CAAC,WAAW,CAAC;KAClC,CAAA;AACH,CAAC"}
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../server/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,cAAc,CAAA;AAEhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAA;AAyBjD,MAAM,MAAM,GAIR;IACF,GAAG,EAAE;QACH,GAAG;QACH,aAAa,EAAE,GAAG,KAAK,aAAa;QACpC,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI;QACxC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QACrC,kBAAkB,EAAE,EAAE;KACvB;IACD,WAAW,EAAE,oBAAoB,EAAE;IACnC,UAAU,EAAE,mBAAmB,EAAE;CAClC,CAAA;AAED,MAAM,cAAc,GAAW,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;AAC7D,aAAa;AACb,eAAe,cAAc,CAAA;AAE7B,SAAS,oBAAoB;IAC3B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,wBAAwB,CAAC,CAAC;IACpG,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,uBAAuB,CAAC,CAAC;IAC7F,OAAO;QACL,WAAW;QACX,SAAS;QACT,kBAAkB,EAAE,GAAG;KACxB,CAAA;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACxE,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAClE,OAAO;QACL,WAAW;QACX,SAAS;QACT,kBAAkB,EAAE,CAAC,WAAW,CAAC;KAClC,CAAA;AACH,CAAC"}

View File

@ -22,6 +22,7 @@ type CommonConfig = BaseConfig & {
type EnvConfig = BaseConfig & {
frontendUrl: string;
serverUrl: string;
}
type Config = CommonConfig & EnvConfig
@ -48,16 +49,20 @@ export default resolvedConfig
function getDevelopmentConfig(): EnvConfig {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL || 'http://localhost:3000/');
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL || 'http://localhost:3001');
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: '*',
}
}
function getProductionConfig(): EnvConfig {
const frontendUrl = stripTrailingSlash(process.env.WASP_WEB_CLIENT_URL);
const serverUrl = stripTrailingSlash(process.env.WASP_SERVER_URL);
return {
frontendUrl,
serverUrl,
allowedCORSOrigins: [frontendUrl],
}
}

View File

@ -2,3 +2,4 @@ import { throwIfNotValidAbsoluteURL } from 'wasp/universal/validators';
console.info("🔍 Validating environment variables...");
throwIfNotValidAbsoluteURL(process.env.WASP_WEB_CLIENT_URL, 'Environment variable WASP_WEB_CLIENT_URL');
throwIfNotValidAbsoluteURL(process.env.WASP_SERVER_URL, 'Environment variable WASP_SERVER_URL');

View File

@ -119,6 +119,7 @@ Press any key to continue or Ctrl+C to cancel.`);
// doesn't provide a way to set envars that persist to fly.toml.
'PORT=8080',
`WASP_WEB_CLIENT_URL=${deploymentInfo.clientUrl}`,
`WASP_SERVER_URL=${deploymentInfo.serverUrl}`,
];
if (deploymentInfo.options.serverSecret.length > 0) {

View File

@ -53,6 +53,7 @@ import qualified Wasp.Generator.SdkGenerator.Server.OperationsGenerator as Serve
import Wasp.Generator.SdkGenerator.ServerApiG (genServerApi)
import Wasp.Generator.SdkGenerator.WebSocketGenerator (depsRequiredByWebSockets, genWebSockets)
import qualified Wasp.Generator.ServerGenerator.AuthG as ServerAuthG
import qualified Wasp.Generator.ServerGenerator.Common as Server
import qualified Wasp.Generator.WebAppGenerator.Common as WebApp
import qualified Wasp.Node.Version as NodeVersion
import Wasp.Project.Common (WaspProjectDir)
@ -82,7 +83,6 @@ genSdkReal spec =
[ genFileCopy [relfile|vite-env.d.ts|],
genFileCopy [relfile|api/index.ts|],
genFileCopy [relfile|api/events.ts|],
genFileCopy [relfile|client/config.ts|],
genFileCopy [relfile|core/storage.ts|],
genFileCopy [relfile|server/index.ts|],
genFileCopy [relfile|server/HttpError.ts|],
@ -90,6 +90,7 @@ genSdkReal spec =
genFileCopy [relfile|client/test/index.ts|],
genFileCopy [relfile|client/index.ts|],
genFileCopy [relfile|dev/index.ts|],
genClientConfigFile,
genServerConfigFile spec,
genTsConfigJson,
genServerUtils spec,
@ -259,9 +260,17 @@ genServerConfigFile spec = return $ C.mkTmplFdWithData relConfigFilePath tmplDat
object
[ "isAuthEnabled" .= isAuthEnabled spec,
"databaseUrlEnvVarName" .= Db.databaseUrlEnvVarName,
"defaultClientUrl" .= WebApp.getDefaultClientUrl spec
"defaultClientUrl" .= WebApp.getDefaultDevClientUrl spec,
"defaultServerUrl" .= Server.defaultDevServerUrl,
"defaultServerPort" .= Server.defaultServerPort
]
genClientConfigFile :: Generator FileDraft
genClientConfigFile = return $ C.mkTmplFdWithData relConfigFilePath tmplData
where
relConfigFilePath = [relfile|client/config.ts|]
tmplData = object ["defaultServerUrl" .= Server.defaultDevServerUrl]
-- todo(filip): remove this duplication, we have almost the same thing in the
-- ServerGenerator.
genTsConfigJson :: Generator FileDraft

View File

@ -17,6 +17,8 @@ module Wasp.Generator.ServerGenerator.Common
ServerSrcDir,
ServerTemplatesDir,
ServerTemplatesSrcDir,
defaultDevServerUrl,
defaultServerPort,
)
where
@ -124,3 +126,9 @@ toESModulesImportPath :: FilePath -> FilePath
toESModulesImportPath = changeExtensionTo "js"
where
changeExtensionTo ext = (++ '.' : ext) . fst . splitExtension
defaultServerPort :: Int
defaultServerPort = 3001
defaultDevServerUrl :: String
defaultDevServerUrl = "http://localhost:" ++ show defaultServerPort

View File

@ -22,7 +22,7 @@ module Wasp.Generator.WebAppGenerator.Common
staticAssetsDirInWebAppDir,
WebAppStaticAssetsDir,
getBaseDir,
getDefaultClientUrl,
getDefaultDevClientUrl,
defaultClientPort,
)
where
@ -148,5 +148,5 @@ getBaseDir spec = fromMaybe [absdirP|/|] maybeBaseDir
defaultClientPort :: Int
defaultClientPort = 3000
getDefaultClientUrl :: AppSpec -> String
getDefaultClientUrl spec = "http://localhost:" ++ show defaultClientPort ++ SP.fromAbsDirP (getBaseDir spec)
getDefaultDevClientUrl :: AppSpec -> String
getDefaultDevClientUrl spec = "http://localhost:" ++ show defaultClientPort ++ SP.fromAbsDirP (getBaseDir spec)

View File

@ -71,6 +71,11 @@ Here are the environment variables your server will be looking for:
The URL where you plan to deploy your frontend app is running (e.g., `https://<app-name>.netlify.app`).
The server needs to know about it to properly configure Same-Origin Policy (CORS) headers.
- `WASP_SERVER_URL` <Required />
The URL where the server is running (e.g., `https://<app-name>.fly.dev`).
The server needs it to properly redirect users when logging in with OAuth providers like Google or GitHub.
- `JWT_SECRET` (<Required /> if using Wasp Auth)
You only need this environment variable if you're using Wasp's `auth` features.
@ -178,11 +183,12 @@ Next, let's add a few more environment variables:
```bash
flyctl secrets set PORT=8080
flyctl secrets set JWT_SECRET=<random_string_at_least_32_characters_long>
flyctl secrets set WASP_WEB_CLIENT_URL=<url_of_where_frontend_will_be_deployed>
flyctl secrets set WASP_WEB_CLIENT_URL=<url_of_where_client_will_be_deployed>
flyctl secrets set WASP_SERVER_URL=<url_of_where_server_will_be_deployed>
```
:::note
If you do not know what your frontend URL is yet, don't worry. You can set `WASP_WEB_CLIENT_URL` after you deploy your frontend.
If you do not know what your client URL is yet, don't worry. You can set `WASP_WEB_CLIENT_URL` after you deploy your client.
:::
<AddExternalAuthEnvVarsReminder />
@ -199,7 +205,7 @@ flyctl deploy --remote-only --config ../../fly.toml
This will build and deploy the backend of your Wasp app on Fly.io to `https://<app-name>.fly.dev` 🤘🎸
Now, if you haven't, you can deploy your frontend and add the client url by running `flyctl secrets set WASP_WEB_CLIENT_URL=<url_of_deployed_frontend>`. We suggest using [Netlify](#netlify) for your frontend, but you can use any static hosting provider.
Now, if you haven't, you can deploy your client and add the client URL by running `flyctl secrets set WASP_WEB_CLIENT_URL=<url_of_deployed_client>`. We suggest using [Netlify](#netlify) for your client, but you can use any static hosting provider.
Additionally, some useful `flyctl` commands:
@ -325,6 +331,7 @@ Let's deploy our server first:
- click **Variable reference** and select `DATABASE_URL` (it will populate it with the correct value)
- add `WASP_WEB_CLIENT_URL` - enter the the `client` domain (e.g. `https://client-production-XXXX.up.railway.app`)
- add `WASP_SERVER_URL` - enter the the `server` domain (e.g. `https://server-production-XXXX.up.railway.app`)
- add `JWT_SECRET` - enter a random string at least 32 characters long (use an [online generator](https://djecrety.ir/))
<AddExternalAuthEnvVarsReminder />
@ -502,15 +509,16 @@ Heroku does not offer a free plan anymore and `mini` is their cheapest database
Heroku will also set `DATABASE_URL` env var for us at this point. If you are using an external database, you will have to set it up yourself.
The `PORT` env var will also be provided by Heroku, so the only two left to set are the `JWT_SECRET` and `WASP_WEB_CLIENT_URL` env vars:
The `PORT` env var will also be provided by Heroku, so the ones left to set are the `JWT_SECRET`, `WASP_WEB_CLIENT_URL` and `WASP_SERVER_URL` env vars:
```
heroku config:set --app <app-name> JWT_SECRET=<random_string_at_least_32_characters_long>
heroku config:set --app <app-name> WASP_WEB_CLIENT_URL=<url_of_where_frontend_will_be_deployed>
heroku config:set --app <app-name> WASP_WEB_CLIENT_URL=<url_of_where_client_will_be_deployed>
heroku config:set --app <app-name> WASP_SERVER_URL=<url_of_where_server_will_be_deployed>
```
:::note
If you do not know what your frontend URL is yet, don't worry. You can set `WASP_WEB_CLIENT_URL` after you deploy your frontend.
If you do not know what your client URL is yet, don't worry. You can set `WASP_WEB_CLIENT_URL` after you deploy your client.
:::
### Deploy to a Heroku App