Tags:
- { article.tags.map(tag => ) }
+ { article.tags.map(tag => ) }
{ isMyArticle && (
diff --git a/examples/realworld/ext/auth/LoginPage.js b/examples/realworld/src/client/auth/LoginPage.js
similarity index 100%
rename from examples/realworld/ext/auth/LoginPage.js
rename to examples/realworld/src/client/auth/LoginPage.js
diff --git a/examples/realworld/ext/auth/SignupPage.js b/examples/realworld/src/client/auth/SignupPage.js
similarity index 100%
rename from examples/realworld/ext/auth/SignupPage.js
rename to examples/realworld/src/client/auth/SignupPage.js
diff --git a/examples/realworld/src/client/jsconfig.json b/examples/realworld/src/client/jsconfig.json
new file mode 100644
index 0000000000..e9b5551fd7
--- /dev/null
+++ b/examples/realworld/src/client/jsconfig.json
@@ -0,0 +1,27 @@
+{
+ "compilerOptions": {
+ // The following settings enable IDE support in user-provided source files.
+ // Editing them might break features like import autocompletion and
+ // definition lookup. Don't change them unless you know what you're doing.
+ //
+ // The relative path to the generated web app's root directory. This must be
+ // set to define the "paths" option.
+ "baseUrl": "../../.wasp/out/web-app/",
+ "paths": {
+ // Resolve all "@wasp" imports to the generated source code.
+ "@wasp/*": [
+ "src/*"
+ ],
+ // Resolve all non-relative imports to the correct node module. Source:
+ // https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
+ "*": [
+ // Start by looking for the definiton inside the node modules root
+ // directory...
+ "node_modules/*",
+ // ... If that fails, try to find it inside definitely-typed type
+ // definitions.
+ "node_modules/@types/*"
+ ]
+ }
+ }
+}
diff --git a/examples/realworld/ext/smiley.jpg b/examples/realworld/src/client/smiley.jpg
similarity index 100%
rename from examples/realworld/ext/smiley.jpg
rename to examples/realworld/src/client/smiley.jpg
diff --git a/examples/realworld/ext/user/components/UserProfilePage.js b/examples/realworld/src/client/user/components/UserProfilePage.js
similarity index 100%
rename from examples/realworld/ext/user/components/UserProfilePage.js
rename to examples/realworld/src/client/user/components/UserProfilePage.js
diff --git a/examples/realworld/ext/user/components/UserSettingsPage.js b/examples/realworld/src/client/user/components/UserSettingsPage.js
similarity index 100%
rename from examples/realworld/ext/user/components/UserSettingsPage.js
rename to examples/realworld/src/client/user/components/UserSettingsPage.js
diff --git a/examples/realworld/ext/utils.js b/examples/realworld/src/client/utils.js
similarity index 100%
rename from examples/realworld/ext/utils.js
rename to examples/realworld/src/client/utils.js
diff --git a/examples/realworld/ext/waspLogo.png b/examples/realworld/src/client/waspLogo.png
similarity index 100%
rename from examples/realworld/ext/waspLogo.png
rename to examples/realworld/src/client/waspLogo.png
diff --git a/examples/realworld/ext/article/actions.js b/examples/realworld/src/server/article/actions.js
similarity index 100%
rename from examples/realworld/ext/article/actions.js
rename to examples/realworld/src/server/article/actions.js
diff --git a/examples/realworld/ext/article/queries.js b/examples/realworld/src/server/article/queries.js
similarity index 100%
rename from examples/realworld/ext/article/queries.js
rename to examples/realworld/src/server/article/queries.js
diff --git a/examples/realworld/src/server/jsconfig.json b/examples/realworld/src/server/jsconfig.json
new file mode 100644
index 0000000000..9e996fc5df
--- /dev/null
+++ b/examples/realworld/src/server/jsconfig.json
@@ -0,0 +1,27 @@
+{
+ "compilerOptions": {
+ // The following settings enable IDE support in user-provided source files.
+ // Editing them might break features like import autocompletion and
+ // definition lookup. Don't change them unless you know what you're doing.
+ //
+ // The relative path to the generated web app's root directory. This must be
+ // set to define the "paths" option.
+ "baseUrl": "../../.wasp/out/server/",
+ "paths": {
+ // Resolve all "@wasp" imports to the generated source code.
+ "@wasp/*": [
+ "src/*"
+ ],
+ // Resolve all non-relative imports to the correct node module. Source:
+ // https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
+ "*": [
+ // Start by looking for the definiton inside the node modules root
+ // directory...
+ "node_modules/*",
+ // ... If that fails, Try to find it inside definitely-typed type
+ // definitions.
+ "node_modules/@types/*"
+ ]
+ }
+ }
+}
diff --git a/examples/realworld/ext/user/actions.js b/examples/realworld/src/server/user/actions.js
similarity index 100%
rename from examples/realworld/ext/user/actions.js
rename to examples/realworld/src/server/user/actions.js
diff --git a/examples/realworld/ext/user/queries.js b/examples/realworld/src/server/user/queries.js
similarity index 100%
rename from examples/realworld/ext/user/queries.js
rename to examples/realworld/src/server/user/queries.js
diff --git a/examples/realworld/src/shared/jsconfig.json b/examples/realworld/src/shared/jsconfig.json
new file mode 100644
index 0000000000..0c4e7f7eb1
--- /dev/null
+++ b/examples/realworld/src/shared/jsconfig.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ // The following settings enable IDE support in user-provided source files.
+ // Editing them might break features like import autocompletion and
+ // definition lookup. Don't change them unless you know what you're doing.
+ //
+ // The relative path to the generated web app's root directory. This must be
+ // set to define the "paths" option.
+ "baseUrl": "../../.wasp/out/server",
+ "paths": {
+ // Resolve all non-relative imports to the correct node module. Source:
+ // https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
+ "*": [
+ // Start by looking for the definiton inside the node modules root
+ // directory...
+ "node_modules/*",
+ // ... If that fails, try to find it inside definitely-typed type
+ // definitions.
+ "node_modules/@types/*"
+ ]
+ }
+ }
+}
diff --git a/examples/thoughts/.env b/examples/thoughts/.env
deleted file mode 100644
index fe236cf6f5..0000000000
--- a/examples/thoughts/.env
+++ /dev/null
@@ -1 +0,0 @@
-DATABASE_URL=postgresql://postgres:devpass@localhost:5432/thoughts-dev
diff --git a/examples/thoughts/.gitignore b/examples/thoughts/.gitignore
index 8867bf3557..c51177f6dc 100644
--- a/examples/thoughts/.gitignore
+++ b/examples/thoughts/.gitignore
@@ -1 +1,3 @@
/.wasp/
+/.env.server
+/.env.client
diff --git a/examples/thoughts/ext/.waspignore b/examples/thoughts/.waspignore
similarity index 100%
rename from examples/thoughts/ext/.waspignore
rename to examples/thoughts/.waspignore
diff --git a/examples/thoughts/.wasproot b/examples/thoughts/.wasproot
index 3caa053db5..ca2cfdb482 100644
--- a/examples/thoughts/.wasproot
+++ b/examples/thoughts/.wasproot
@@ -1 +1 @@
-File marking the root of Wasp project.
\ No newline at end of file
+File marking the root of Wasp project.
diff --git a/examples/thoughts/main.wasp b/examples/thoughts/main.wasp
index b4173bb770..be43d308af 100644
--- a/examples/thoughts/main.wasp
+++ b/examples/thoughts/main.wasp
@@ -19,38 +19,38 @@ app Thoughts {
route MainRoute { path: "/", to: MainPage }
page MainPage {
- component: import Main from "@ext/MainPage.js",
+ component: import Main from "@client/MainPage.js",
authRequired: true
}
route ThoughtsRoute { path: "/thoughts", to: ThoughtsPage }
page ThoughtsPage {
- component: import Thoughts from "@ext/ThoughtsPage.js",
+ component: import Thoughts from "@client/ThoughtsPage.js",
authRequired: true
}
route LoginRoute { path: "/login", to: LoginPage }
page LoginPage {
- component: import Login from "@ext/LoginPage.js"
+ component: import Login from "@client/LoginPage.js"
}
route SignupRoute { path: "/signup", to: SignupPage }
page SignupPage {
- component: import Signup from "@ext/SignupPage"
+ component: import Signup from "@client/SignupPage"
}
action createThought {
- fn: import { createThought } from "@ext/actions.js",
+ fn: import { createThought } from "@server/actions.js",
entities: [Thought, Tag]
}
query getThoughts {
- fn: import { getThoughts } from "@ext/queries.js",
+ fn: import { getThoughts } from "@server/queries.js",
entities: [Thought]
}
query getTags {
- fn: import { getTags } from "@ext/queries.js",
+ fn: import { getTags } from "@server/queries.js",
entities: [Tag]
}
diff --git a/examples/thoughts/ext/Layout.css b/examples/thoughts/src/client/Layout.css
similarity index 100%
rename from examples/thoughts/ext/Layout.css
rename to examples/thoughts/src/client/Layout.css
diff --git a/examples/thoughts/ext/Layout.js b/examples/thoughts/src/client/Layout.js
similarity index 100%
rename from examples/thoughts/ext/Layout.js
rename to examples/thoughts/src/client/Layout.js
diff --git a/examples/thoughts/ext/LoginPage.js b/examples/thoughts/src/client/LoginPage.js
similarity index 100%
rename from examples/thoughts/ext/LoginPage.js
rename to examples/thoughts/src/client/LoginPage.js
diff --git a/examples/thoughts/ext/Main.css b/examples/thoughts/src/client/Main.css
similarity index 100%
rename from examples/thoughts/ext/Main.css
rename to examples/thoughts/src/client/Main.css
diff --git a/examples/thoughts/ext/MainPage.js b/examples/thoughts/src/client/MainPage.js
similarity index 100%
rename from examples/thoughts/ext/MainPage.js
rename to examples/thoughts/src/client/MainPage.js
diff --git a/examples/thoughts/ext/SignupPage.js b/examples/thoughts/src/client/SignupPage.js
similarity index 100%
rename from examples/thoughts/ext/SignupPage.js
rename to examples/thoughts/src/client/SignupPage.js
diff --git a/examples/thoughts/ext/Tag.css b/examples/thoughts/src/client/Tag.css
similarity index 100%
rename from examples/thoughts/ext/Tag.css
rename to examples/thoughts/src/client/Tag.css
diff --git a/examples/thoughts/ext/Tag.js b/examples/thoughts/src/client/Tag.js
similarity index 100%
rename from examples/thoughts/ext/Tag.js
rename to examples/thoughts/src/client/Tag.js
diff --git a/examples/thoughts/ext/TagsSidebar.css b/examples/thoughts/src/client/TagsSidebar.css
similarity index 100%
rename from examples/thoughts/ext/TagsSidebar.css
rename to examples/thoughts/src/client/TagsSidebar.css
diff --git a/examples/thoughts/ext/TagsSidebar.js b/examples/thoughts/src/client/TagsSidebar.js
similarity index 100%
rename from examples/thoughts/ext/TagsSidebar.js
rename to examples/thoughts/src/client/TagsSidebar.js
diff --git a/examples/thoughts/ext/Thought.css b/examples/thoughts/src/client/Thought.css
similarity index 100%
rename from examples/thoughts/ext/Thought.css
rename to examples/thoughts/src/client/Thought.css
diff --git a/examples/thoughts/ext/ThoughtsPage.css b/examples/thoughts/src/client/ThoughtsPage.css
similarity index 100%
rename from examples/thoughts/ext/ThoughtsPage.css
rename to examples/thoughts/src/client/ThoughtsPage.css
diff --git a/examples/thoughts/ext/ThoughtsPage.js b/examples/thoughts/src/client/ThoughtsPage.js
similarity index 100%
rename from examples/thoughts/ext/ThoughtsPage.js
rename to examples/thoughts/src/client/ThoughtsPage.js
diff --git a/examples/thoughts/ext/TopNavbar.css b/examples/thoughts/src/client/TopNavbar.css
similarity index 100%
rename from examples/thoughts/ext/TopNavbar.css
rename to examples/thoughts/src/client/TopNavbar.css
diff --git a/examples/thoughts/ext/TopNavbar.js b/examples/thoughts/src/client/TopNavbar.js
similarity index 100%
rename from examples/thoughts/ext/TopNavbar.js
rename to examples/thoughts/src/client/TopNavbar.js
diff --git a/examples/thoughts/ext/WaspSourceHeader.js b/examples/thoughts/src/client/WaspSourceHeader.js
similarity index 100%
rename from examples/thoughts/ext/WaspSourceHeader.js
rename to examples/thoughts/src/client/WaspSourceHeader.js
diff --git a/examples/thoughts/ext/addWaspSourceHeader.js b/examples/thoughts/src/client/addWaspSourceHeader.js
similarity index 100%
rename from examples/thoughts/ext/addWaspSourceHeader.js
rename to examples/thoughts/src/client/addWaspSourceHeader.js
diff --git a/examples/thoughts/src/client/jsconfig.json b/examples/thoughts/src/client/jsconfig.json
new file mode 100644
index 0000000000..e9b5551fd7
--- /dev/null
+++ b/examples/thoughts/src/client/jsconfig.json
@@ -0,0 +1,27 @@
+{
+ "compilerOptions": {
+ // The following settings enable IDE support in user-provided source files.
+ // Editing them might break features like import autocompletion and
+ // definition lookup. Don't change them unless you know what you're doing.
+ //
+ // The relative path to the generated web app's root directory. This must be
+ // set to define the "paths" option.
+ "baseUrl": "../../.wasp/out/web-app/",
+ "paths": {
+ // Resolve all "@wasp" imports to the generated source code.
+ "@wasp/*": [
+ "src/*"
+ ],
+ // Resolve all non-relative imports to the correct node module. Source:
+ // https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
+ "*": [
+ // Start by looking for the definiton inside the node modules root
+ // directory...
+ "node_modules/*",
+ // ... If that fails, try to find it inside definitely-typed type
+ // definitions.
+ "node_modules/@types/*"
+ ]
+ }
+ }
+}
diff --git a/examples/thoughts/ext/waspLogo.png b/examples/thoughts/src/client/waspLogo.png
similarity index 100%
rename from examples/thoughts/ext/waspLogo.png
rename to examples/thoughts/src/client/waspLogo.png
diff --git a/examples/thoughts/ext/actions.js b/examples/thoughts/src/server/actions.js
similarity index 100%
rename from examples/thoughts/ext/actions.js
rename to examples/thoughts/src/server/actions.js
diff --git a/examples/thoughts/src/server/jsconfig.json b/examples/thoughts/src/server/jsconfig.json
new file mode 100644
index 0000000000..9e996fc5df
--- /dev/null
+++ b/examples/thoughts/src/server/jsconfig.json
@@ -0,0 +1,27 @@
+{
+ "compilerOptions": {
+ // The following settings enable IDE support in user-provided source files.
+ // Editing them might break features like import autocompletion and
+ // definition lookup. Don't change them unless you know what you're doing.
+ //
+ // The relative path to the generated web app's root directory. This must be
+ // set to define the "paths" option.
+ "baseUrl": "../../.wasp/out/server/",
+ "paths": {
+ // Resolve all "@wasp" imports to the generated source code.
+ "@wasp/*": [
+ "src/*"
+ ],
+ // Resolve all non-relative imports to the correct node module. Source:
+ // https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
+ "*": [
+ // Start by looking for the definiton inside the node modules root
+ // directory...
+ "node_modules/*",
+ // ... If that fails, Try to find it inside definitely-typed type
+ // definitions.
+ "node_modules/@types/*"
+ ]
+ }
+ }
+}
diff --git a/examples/thoughts/ext/queries.js b/examples/thoughts/src/server/queries.js
similarity index 100%
rename from examples/thoughts/ext/queries.js
rename to examples/thoughts/src/server/queries.js
diff --git a/examples/thoughts/src/shared/jsconfig.json b/examples/thoughts/src/shared/jsconfig.json
new file mode 100644
index 0000000000..0c4e7f7eb1
--- /dev/null
+++ b/examples/thoughts/src/shared/jsconfig.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ // The following settings enable IDE support in user-provided source files.
+ // Editing them might break features like import autocompletion and
+ // definition lookup. Don't change them unless you know what you're doing.
+ //
+ // The relative path to the generated web app's root directory. This must be
+ // set to define the "paths" option.
+ "baseUrl": "../../.wasp/out/server",
+ "paths": {
+ // Resolve all non-relative imports to the correct node module. Source:
+ // https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
+ "*": [
+ // Start by looking for the definiton inside the node modules root
+ // directory...
+ "node_modules/*",
+ // ... If that fails, try to find it inside definitely-typed type
+ // definitions.
+ "node_modules/@types/*"
+ ]
+ }
+ }
+}
diff --git a/examples/tutorials/ItWaspsOnMyMachine/.gitignore b/examples/tutorials/ItWaspsOnMyMachine/.gitignore
index 706b2ddffd..c51177f6dc 100644
--- a/examples/tutorials/ItWaspsOnMyMachine/.gitignore
+++ b/examples/tutorials/ItWaspsOnMyMachine/.gitignore
@@ -1,2 +1,3 @@
/.wasp/
-/.env
+/.env.server
+/.env.client
diff --git a/examples/tutorials/ItWaspsOnMyMachine/.wasproot b/examples/tutorials/ItWaspsOnMyMachine/.wasproot
index 3caa053db5..ca2cfdb482 100644
--- a/examples/tutorials/ItWaspsOnMyMachine/.wasproot
+++ b/examples/tutorials/ItWaspsOnMyMachine/.wasproot
@@ -1 +1 @@
-File marking the root of Wasp project.
\ No newline at end of file
+File marking the root of Wasp project.
diff --git a/examples/tutorials/ItWaspsOnMyMachine/main.wasp b/examples/tutorials/ItWaspsOnMyMachine/main.wasp
index b5da61620a..941e882492 100644
--- a/examples/tutorials/ItWaspsOnMyMachine/main.wasp
+++ b/examples/tutorials/ItWaspsOnMyMachine/main.wasp
@@ -16,7 +16,7 @@ app ItWaspsOnMyMachine {
route RootRoute { path: "/", to: MainPage }
page MainPage {
- component: import Main from "@ext/MainPage.js"
+ component: import Main from "@client/MainPage.js"
}
entity Excuse {=psl
@@ -25,17 +25,17 @@ entity Excuse {=psl
psl=}
query getExcuse {
- fn: import { getExcuse } from "@ext/queries.js",
+ fn: import { getExcuse } from "@client/queries.js",
entities: [Excuse]
}
query getAllSavedExcuses {
- fn: import { getAllSavedExcuses } from "@ext/queries.js",
+ fn: import { getAllSavedExcuses } from "@server/queries.js",
entities: [Excuse]
}
action saveExcuse {
- fn: import { saveExcuse } from "@ext/actions.js",
+ fn: import { saveExcuse } from "@server/actions.js",
entities: [Excuse]
}
diff --git a/examples/tutorials/ItWaspsOnMyMachine/migrations/20220819110846_init/migration.sql b/examples/tutorials/ItWaspsOnMyMachine/migrations/20220819110846_init/migration.sql
deleted file mode 100644
index 345b870e02..0000000000
--- a/examples/tutorials/ItWaspsOnMyMachine/migrations/20220819110846_init/migration.sql
+++ /dev/null
@@ -1,5 +0,0 @@
--- CreateTable
-CREATE TABLE "Excuse" (
- "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
- "text" TEXT NOT NULL
-);
diff --git a/examples/tutorials/ItWaspsOnMyMachine/ext/.waspignore b/examples/tutorials/ItWaspsOnMyMachine/src/.waspignore
similarity index 100%
rename from examples/tutorials/ItWaspsOnMyMachine/ext/.waspignore
rename to examples/tutorials/ItWaspsOnMyMachine/src/.waspignore
diff --git a/examples/tutorials/ItWaspsOnMyMachine/ext/MainPage.js b/examples/tutorials/ItWaspsOnMyMachine/src/client/MainPage.js
similarity index 100%
rename from examples/tutorials/ItWaspsOnMyMachine/ext/MainPage.js
rename to examples/tutorials/ItWaspsOnMyMachine/src/client/MainPage.js
diff --git a/examples/tutorials/ItWaspsOnMyMachine/src/client/jsconfig.json b/examples/tutorials/ItWaspsOnMyMachine/src/client/jsconfig.json
new file mode 100644
index 0000000000..e9b5551fd7
--- /dev/null
+++ b/examples/tutorials/ItWaspsOnMyMachine/src/client/jsconfig.json
@@ -0,0 +1,27 @@
+{
+ "compilerOptions": {
+ // The following settings enable IDE support in user-provided source files.
+ // Editing them might break features like import autocompletion and
+ // definition lookup. Don't change them unless you know what you're doing.
+ //
+ // The relative path to the generated web app's root directory. This must be
+ // set to define the "paths" option.
+ "baseUrl": "../../.wasp/out/web-app/",
+ "paths": {
+ // Resolve all "@wasp" imports to the generated source code.
+ "@wasp/*": [
+ "src/*"
+ ],
+ // Resolve all non-relative imports to the correct node module. Source:
+ // https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
+ "*": [
+ // Start by looking for the definiton inside the node modules root
+ // directory...
+ "node_modules/*",
+ // ... If that fails, try to find it inside definitely-typed type
+ // definitions.
+ "node_modules/@types/*"
+ ]
+ }
+ }
+}
diff --git a/examples/tutorials/ItWaspsOnMyMachine/ext/sponge-bob-excuses.jpg b/examples/tutorials/ItWaspsOnMyMachine/src/client/sponge-bob-excuses.jpg
similarity index 100%
rename from examples/tutorials/ItWaspsOnMyMachine/ext/sponge-bob-excuses.jpg
rename to examples/tutorials/ItWaspsOnMyMachine/src/client/sponge-bob-excuses.jpg
diff --git a/examples/tutorials/ItWaspsOnMyMachine/ext/actions.js b/examples/tutorials/ItWaspsOnMyMachine/src/server/actions.js
similarity index 100%
rename from examples/tutorials/ItWaspsOnMyMachine/ext/actions.js
rename to examples/tutorials/ItWaspsOnMyMachine/src/server/actions.js
diff --git a/examples/tutorials/ItWaspsOnMyMachine/src/server/jsconfig.json b/examples/tutorials/ItWaspsOnMyMachine/src/server/jsconfig.json
new file mode 100644
index 0000000000..9e996fc5df
--- /dev/null
+++ b/examples/tutorials/ItWaspsOnMyMachine/src/server/jsconfig.json
@@ -0,0 +1,27 @@
+{
+ "compilerOptions": {
+ // The following settings enable IDE support in user-provided source files.
+ // Editing them might break features like import autocompletion and
+ // definition lookup. Don't change them unless you know what you're doing.
+ //
+ // The relative path to the generated web app's root directory. This must be
+ // set to define the "paths" option.
+ "baseUrl": "../../.wasp/out/server/",
+ "paths": {
+ // Resolve all "@wasp" imports to the generated source code.
+ "@wasp/*": [
+ "src/*"
+ ],
+ // Resolve all non-relative imports to the correct node module. Source:
+ // https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
+ "*": [
+ // Start by looking for the definiton inside the node modules root
+ // directory...
+ "node_modules/*",
+ // ... If that fails, Try to find it inside definitely-typed type
+ // definitions.
+ "node_modules/@types/*"
+ ]
+ }
+ }
+}
diff --git a/examples/tutorials/ItWaspsOnMyMachine/ext/queries.js b/examples/tutorials/ItWaspsOnMyMachine/src/server/queries.js
similarity index 100%
rename from examples/tutorials/ItWaspsOnMyMachine/ext/queries.js
rename to examples/tutorials/ItWaspsOnMyMachine/src/server/queries.js
diff --git a/examples/tutorials/ItWaspsOnMyMachine/src/shared/jsconfig.json b/examples/tutorials/ItWaspsOnMyMachine/src/shared/jsconfig.json
new file mode 100644
index 0000000000..0c4e7f7eb1
--- /dev/null
+++ b/examples/tutorials/ItWaspsOnMyMachine/src/shared/jsconfig.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ // The following settings enable IDE support in user-provided source files.
+ // Editing them might break features like import autocompletion and
+ // definition lookup. Don't change them unless you know what you're doing.
+ //
+ // The relative path to the generated web app's root directory. This must be
+ // set to define the "paths" option.
+ "baseUrl": "../../.wasp/out/server",
+ "paths": {
+ // Resolve all non-relative imports to the correct node module. Source:
+ // https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
+ "*": [
+ // Start by looking for the definiton inside the node modules root
+ // directory...
+ "node_modules/*",
+ // ... If that fails, try to find it inside definitely-typed type
+ // definitions.
+ "node_modules/@types/*"
+ ]
+ }
+ }
+}
diff --git a/examples/waspello/.gitignore b/examples/waspello/.gitignore
index 706b2ddffd..c51177f6dc 100644
--- a/examples/waspello/.gitignore
+++ b/examples/waspello/.gitignore
@@ -1,2 +1,3 @@
/.wasp/
-/.env
+/.env.server
+/.env.client
diff --git a/examples/waspello/.wasproot b/examples/waspello/.wasproot
index 3caa053db5..ca2cfdb482 100644
--- a/examples/waspello/.wasproot
+++ b/examples/waspello/.wasproot
@@ -1 +1 @@
-File marking the root of Wasp project.
\ No newline at end of file
+File marking the root of Wasp project.
diff --git a/examples/waspello/main.wasp b/examples/waspello/main.wasp
index 2b4a340bc2..81ded14ee8 100644
--- a/examples/waspello/main.wasp
+++ b/examples/waspello/main.wasp
@@ -28,17 +28,17 @@ app trello {
route MainRoute { path: "/", to: Main }
page Main {
authRequired: true,
- component: import Main from "@ext/MainPage.js"
+ component: import Main from "@client/MainPage.js"
}
route SignupRoute { path: "/signup", to: Signup }
page Signup {
- component: import Signup from "@ext/SignupPage"
+ component: import Signup from "@client/SignupPage"
}
route LoginRoute { path: "/login", to: Login }
page Login {
- component: import Login from "@ext/LoginPage"
+ component: import Login from "@client/LoginPage"
}
// Entities
@@ -80,41 +80,41 @@ psl=}
// ------------------- Queries and actions
query getListsAndCards {
- fn: import { getListsAndCards } from "@ext/queries.js",
+ fn: import { getListsAndCards } from "@server/queries.js",
entities: [List, Card]
}
// Lists
action createList {
- fn: import { createList } from "@ext/actions.js",
+ fn: import { createList } from "@server/actions.js",
entities: [List]
}
action updateList {
- fn: import { updateList } from "@ext/actions.js",
+ fn: import { updateList } from "@server/actions.js",
entities: [List]
}
action deleteList {
- fn: import { deleteList } from "@ext/actions.js",
+ fn: import { deleteList } from "@server/actions.js",
entities: [List, Card]
}
action createListCopy {
- fn: import { createListCopy } from "@ext/actions.js",
+ fn: import { createListCopy } from "@server/actions.js",
entities: [List, Card]
}
// Cards
action createCard {
- fn: import { createCard } from "@ext/actions.js",
+ fn: import { createCard } from "@server/actions.js",
entities: [Card]
}
action updateCard {
- fn: import { updateCard } from "@ext/actions.js",
+ fn: import { updateCard } from "@server/actions.js",
entities: [Card]
}
diff --git a/examples/waspello/ext/.waspignore b/examples/waspello/src/.waspignore
similarity index 100%
rename from examples/waspello/ext/.waspignore
rename to examples/waspello/src/.waspignore
diff --git a/examples/waspello/ext/LoginPage.js b/examples/waspello/src/client/LoginPage.js
similarity index 100%
rename from examples/waspello/ext/LoginPage.js
rename to examples/waspello/src/client/LoginPage.js
diff --git a/examples/waspello/ext/Main.css b/examples/waspello/src/client/Main.css
similarity index 100%
rename from examples/waspello/ext/Main.css
rename to examples/waspello/src/client/Main.css
diff --git a/examples/waspello/ext/MainPage.js b/examples/waspello/src/client/MainPage.js
similarity index 100%
rename from examples/waspello/ext/MainPage.js
rename to examples/waspello/src/client/MainPage.js
diff --git a/examples/waspello/ext/Navbar.css b/examples/waspello/src/client/Navbar.css
similarity index 100%
rename from examples/waspello/ext/Navbar.css
rename to examples/waspello/src/client/Navbar.css
diff --git a/examples/waspello/ext/Navbar.js b/examples/waspello/src/client/Navbar.js
similarity index 100%
rename from examples/waspello/ext/Navbar.js
rename to examples/waspello/src/client/Navbar.js
diff --git a/examples/waspello/ext/PositionContext.js b/examples/waspello/src/client/PositionContext.js
similarity index 100%
rename from examples/waspello/ext/PositionContext.js
rename to examples/waspello/src/client/PositionContext.js
diff --git a/examples/waspello/ext/Signup.css b/examples/waspello/src/client/Signup.css
similarity index 100%
rename from examples/waspello/ext/Signup.css
rename to examples/waspello/src/client/Signup.css
diff --git a/examples/waspello/ext/SignupPage.js b/examples/waspello/src/client/SignupPage.js
similarity index 100%
rename from examples/waspello/ext/SignupPage.js
rename to examples/waspello/src/client/SignupPage.js
diff --git a/examples/waspello/ext/UserPageLayout.css b/examples/waspello/src/client/UserPageLayout.css
similarity index 100%
rename from examples/waspello/ext/UserPageLayout.css
rename to examples/waspello/src/client/UserPageLayout.css
diff --git a/examples/waspello/ext/UserPageLayout.js b/examples/waspello/src/client/UserPageLayout.js
similarity index 100%
rename from examples/waspello/ext/UserPageLayout.js
rename to examples/waspello/src/client/UserPageLayout.js
diff --git a/examples/waspello/ext/WaspSourceHeader.js b/examples/waspello/src/client/WaspSourceHeader.js
similarity index 100%
rename from examples/waspello/ext/WaspSourceHeader.js
rename to examples/waspello/src/client/WaspSourceHeader.js
diff --git a/examples/waspello/ext/addWaspSourceHeader.js b/examples/waspello/src/client/addWaspSourceHeader.js
similarity index 100%
rename from examples/waspello/ext/addWaspSourceHeader.js
rename to examples/waspello/src/client/addWaspSourceHeader.js
diff --git a/examples/waspello/src/client/jsconfig.json b/examples/waspello/src/client/jsconfig.json
new file mode 100644
index 0000000000..e9b5551fd7
--- /dev/null
+++ b/examples/waspello/src/client/jsconfig.json
@@ -0,0 +1,27 @@
+{
+ "compilerOptions": {
+ // The following settings enable IDE support in user-provided source files.
+ // Editing them might break features like import autocompletion and
+ // definition lookup. Don't change them unless you know what you're doing.
+ //
+ // The relative path to the generated web app's root directory. This must be
+ // set to define the "paths" option.
+ "baseUrl": "../../.wasp/out/web-app/",
+ "paths": {
+ // Resolve all "@wasp" imports to the generated source code.
+ "@wasp/*": [
+ "src/*"
+ ],
+ // Resolve all non-relative imports to the correct node module. Source:
+ // https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
+ "*": [
+ // Start by looking for the definiton inside the node modules root
+ // directory...
+ "node_modules/*",
+ // ... If that fails, try to find it inside definitely-typed type
+ // definitions.
+ "node_modules/@types/*"
+ ]
+ }
+ }
+}
diff --git a/examples/waspello/ext/waspLogo.png b/examples/waspello/src/client/waspLogo.png
similarity index 100%
rename from examples/waspello/ext/waspLogo.png
rename to examples/waspello/src/client/waspLogo.png
diff --git a/examples/waspello/ext/waspello-logo-navbar.svg b/examples/waspello/src/client/waspello-logo-navbar.svg
similarity index 100%
rename from examples/waspello/ext/waspello-logo-navbar.svg
rename to examples/waspello/src/client/waspello-logo-navbar.svg
diff --git a/examples/waspello/ext/waspello-logo.svg b/examples/waspello/src/client/waspello-logo.svg
similarity index 100%
rename from examples/waspello/ext/waspello-logo.svg
rename to examples/waspello/src/client/waspello-logo.svg
diff --git a/examples/waspello/ext/actions.js b/examples/waspello/src/server/actions.js
similarity index 100%
rename from examples/waspello/ext/actions.js
rename to examples/waspello/src/server/actions.js
diff --git a/examples/waspello/src/server/jsconfig.json b/examples/waspello/src/server/jsconfig.json
new file mode 100644
index 0000000000..9e996fc5df
--- /dev/null
+++ b/examples/waspello/src/server/jsconfig.json
@@ -0,0 +1,27 @@
+{
+ "compilerOptions": {
+ // The following settings enable IDE support in user-provided source files.
+ // Editing them might break features like import autocompletion and
+ // definition lookup. Don't change them unless you know what you're doing.
+ //
+ // The relative path to the generated web app's root directory. This must be
+ // set to define the "paths" option.
+ "baseUrl": "../../.wasp/out/server/",
+ "paths": {
+ // Resolve all "@wasp" imports to the generated source code.
+ "@wasp/*": [
+ "src/*"
+ ],
+ // Resolve all non-relative imports to the correct node module. Source:
+ // https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
+ "*": [
+ // Start by looking for the definiton inside the node modules root
+ // directory...
+ "node_modules/*",
+ // ... If that fails, Try to find it inside definitely-typed type
+ // definitions.
+ "node_modules/@types/*"
+ ]
+ }
+ }
+}
diff --git a/examples/waspello/ext/queries.js b/examples/waspello/src/server/queries.js
similarity index 100%
rename from examples/waspello/ext/queries.js
rename to examples/waspello/src/server/queries.js
diff --git a/examples/waspello/src/shared/jsconfig.json b/examples/waspello/src/shared/jsconfig.json
new file mode 100644
index 0000000000..0c4e7f7eb1
--- /dev/null
+++ b/examples/waspello/src/shared/jsconfig.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ // The following settings enable IDE support in user-provided source files.
+ // Editing them might break features like import autocompletion and
+ // definition lookup. Don't change them unless you know what you're doing.
+ //
+ // The relative path to the generated web app's root directory. This must be
+ // set to define the "paths" option.
+ "baseUrl": "../../.wasp/out/server",
+ "paths": {
+ // Resolve all non-relative imports to the correct node module. Source:
+ // https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
+ "*": [
+ // Start by looking for the definiton inside the node modules root
+ // directory...
+ "node_modules/*",
+ // ... If that fails, try to find it inside definitely-typed type
+ // definitions.
+ "node_modules/@types/*"
+ ]
+ }
+ }
+}
diff --git a/examples/waspleau/.gitignore b/examples/waspleau/.gitignore
index 18686dc05f..4ec620481a 100644
--- a/examples/waspleau/.gitignore
+++ b/examples/waspleau/.gitignore
@@ -1,3 +1,4 @@
/.wasp/
-/.env
+/.env.server
+/.env.client
.DS_Store
diff --git a/examples/waspleau/.wasproot b/examples/waspleau/.wasproot
index 3caa053db5..ca2cfdb482 100644
--- a/examples/waspleau/.wasproot
+++ b/examples/waspleau/.wasproot
@@ -1 +1 @@
-File marking the root of Wasp project.
\ No newline at end of file
+File marking the root of Wasp project.
diff --git a/examples/waspleau/main.wasp b/examples/waspleau/main.wasp
index 1345f2e07e..573455299b 100644
--- a/examples/waspleau/main.wasp
+++ b/examples/waspleau/main.wasp
@@ -6,7 +6,7 @@ app waspleau {
title: "Waspleau",
server: {
- setupFn: import serverSetup from "@ext/serverSetup.js"
+ setupFn: import serverSetup from "@server/serverSetup.js"
},
db: { system: PostgreSQL },
@@ -19,7 +19,7 @@ app waspleau {
job github {
executor: PgBoss,
perform: {
- fn: import { workerFunction } from "@ext/workers/github.js"
+ fn: import { workerFunction } from "@server/workers/github.js"
},
schedule: {
cron: "*/10 * * * *"
@@ -30,7 +30,7 @@ job github {
job loadTime {
executor: PgBoss,
perform: {
- fn: import { workerFunction } from "@ext/workers/loadTime.js"
+ fn: import { workerFunction } from "@server/workers/loadTime.js"
},
schedule: {
cron: "*/5 * * * *",
@@ -51,10 +51,10 @@ psl=}
route RootsRoute { path: "/", to: MainPage }
page MainPage {
- component: import Main from "@ext/MainPage.js"
+ component: import Main from "@client/MainPage.js"
}
query dashboard {
- fn: import { refreshDashboardData } from "@ext/dashboard.js",
+ fn: import { refreshDashboardData } from "@server/dashboard.js",
entities: [Metric]
}
diff --git a/examples/waspleau/ext/.waspignore b/examples/waspleau/src/.waspignore
similarity index 100%
rename from examples/waspleau/ext/.waspignore
rename to examples/waspleau/src/.waspignore
diff --git a/examples/waspleau/ext/MainPage.js b/examples/waspleau/src/client/MainPage.js
similarity index 100%
rename from examples/waspleau/ext/MainPage.js
rename to examples/waspleau/src/client/MainPage.js
diff --git a/examples/waspleau/ext/WaspSourceHeader.js b/examples/waspleau/src/client/WaspSourceHeader.js
similarity index 100%
rename from examples/waspleau/ext/WaspSourceHeader.js
rename to examples/waspleau/src/client/WaspSourceHeader.js
diff --git a/examples/waspleau/ext/addWaspSourceHeader.js b/examples/waspleau/src/client/addWaspSourceHeader.js
similarity index 100%
rename from examples/waspleau/ext/addWaspSourceHeader.js
rename to examples/waspleau/src/client/addWaspSourceHeader.js
diff --git a/examples/waspleau/src/client/jsconfig.json b/examples/waspleau/src/client/jsconfig.json
new file mode 100644
index 0000000000..e9b5551fd7
--- /dev/null
+++ b/examples/waspleau/src/client/jsconfig.json
@@ -0,0 +1,27 @@
+{
+ "compilerOptions": {
+ // The following settings enable IDE support in user-provided source files.
+ // Editing them might break features like import autocompletion and
+ // definition lookup. Don't change them unless you know what you're doing.
+ //
+ // The relative path to the generated web app's root directory. This must be
+ // set to define the "paths" option.
+ "baseUrl": "../../.wasp/out/web-app/",
+ "paths": {
+ // Resolve all "@wasp" imports to the generated source code.
+ "@wasp/*": [
+ "src/*"
+ ],
+ // Resolve all non-relative imports to the correct node module. Source:
+ // https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
+ "*": [
+ // Start by looking for the definiton inside the node modules root
+ // directory...
+ "node_modules/*",
+ // ... If that fails, try to find it inside definitely-typed type
+ // definitions.
+ "node_modules/@types/*"
+ ]
+ }
+ }
+}
diff --git a/examples/waspleau/ext/style.css b/examples/waspleau/src/client/style.css
similarity index 100%
rename from examples/waspleau/ext/style.css
rename to examples/waspleau/src/client/style.css
diff --git a/examples/waspleau/ext/waspLogo.png b/examples/waspleau/src/client/waspLogo.png
similarity index 100%
rename from examples/waspleau/ext/waspLogo.png
rename to examples/waspleau/src/client/waspLogo.png
diff --git a/examples/waspleau/ext/dashboard.js b/examples/waspleau/src/server/dashboard.js
similarity index 100%
rename from examples/waspleau/ext/dashboard.js
rename to examples/waspleau/src/server/dashboard.js
diff --git a/examples/waspleau/src/server/jsconfig.json b/examples/waspleau/src/server/jsconfig.json
new file mode 100644
index 0000000000..9e996fc5df
--- /dev/null
+++ b/examples/waspleau/src/server/jsconfig.json
@@ -0,0 +1,27 @@
+{
+ "compilerOptions": {
+ // The following settings enable IDE support in user-provided source files.
+ // Editing them might break features like import autocompletion and
+ // definition lookup. Don't change them unless you know what you're doing.
+ //
+ // The relative path to the generated web app's root directory. This must be
+ // set to define the "paths" option.
+ "baseUrl": "../../.wasp/out/server/",
+ "paths": {
+ // Resolve all "@wasp" imports to the generated source code.
+ "@wasp/*": [
+ "src/*"
+ ],
+ // Resolve all non-relative imports to the correct node module. Source:
+ // https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
+ "*": [
+ // Start by looking for the definiton inside the node modules root
+ // directory...
+ "node_modules/*",
+ // ... If that fails, Try to find it inside definitely-typed type
+ // definitions.
+ "node_modules/@types/*"
+ ]
+ }
+ }
+}
diff --git a/examples/waspleau/ext/serverSetup.js b/examples/waspleau/src/server/serverSetup.js
similarity index 100%
rename from examples/waspleau/ext/serverSetup.js
rename to examples/waspleau/src/server/serverSetup.js
diff --git a/examples/waspleau/ext/workers/github.js b/examples/waspleau/src/server/workers/github.js
similarity index 100%
rename from examples/waspleau/ext/workers/github.js
rename to examples/waspleau/src/server/workers/github.js
diff --git a/examples/waspleau/ext/workers/loadTime.js b/examples/waspleau/src/server/workers/loadTime.js
similarity index 100%
rename from examples/waspleau/ext/workers/loadTime.js
rename to examples/waspleau/src/server/workers/loadTime.js
diff --git a/examples/waspleau/ext/workers/utils.js b/examples/waspleau/src/server/workers/utils.js
similarity index 100%
rename from examples/waspleau/ext/workers/utils.js
rename to examples/waspleau/src/server/workers/utils.js
diff --git a/examples/waspleau/src/shared/jsconfig.json b/examples/waspleau/src/shared/jsconfig.json
new file mode 100644
index 0000000000..0c4e7f7eb1
--- /dev/null
+++ b/examples/waspleau/src/shared/jsconfig.json
@@ -0,0 +1,23 @@
+{
+ "compilerOptions": {
+ // The following settings enable IDE support in user-provided source files.
+ // Editing them might break features like import autocompletion and
+ // definition lookup. Don't change them unless you know what you're doing.
+ //
+ // The relative path to the generated web app's root directory. This must be
+ // set to define the "paths" option.
+ "baseUrl": "../../.wasp/out/server",
+ "paths": {
+ // Resolve all non-relative imports to the correct node module. Source:
+ // https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
+ "*": [
+ // Start by looking for the definiton inside the node modules root
+ // directory...
+ "node_modules/*",
+ // ... If that fails, try to find it inside definitely-typed type
+ // definitions.
+ "node_modules/@types/*"
+ ]
+ }
+ }
+}
diff --git a/waspc/ChangeLog.md b/waspc/ChangeLog.md
index a69286b04b..e1804c0c61 100644
--- a/waspc/ChangeLog.md
+++ b/waspc/ChangeLog.md
@@ -7,6 +7,110 @@
- Removes default `index.css` file that provided basic `body` defaults. Now, there is no default CSS applied.
- Updates required Node LTS version from version 16 to version 18. This Node ecosystem change happened on 2022-10-25: https://github.com/nodejs/Release
+#### Significant changes to Wasp project structure
+This was the file tree of a newly generated project in the previous version of Wasp
+(i.e., this was what you used to get by running `wasp new project`):
+```
+.
+├── ext
+│ ├── Main.css
+│ ├── MainPage.js
+│ ├── .waspignore
+│ └── waspLogo.png
+├── .gitignore
+├── main.wasp
+└── .wasproot
+```
+This is the file tree of a newly generated project in the newest release of Wasp (i.e., this is what you will
+get by running `wasp new project` from this point onwards):
+```
+.
+├── .gitignore
+├── main.wasp
+├── src
+│ ├── client
+│ │ ├── jsconfig.json
+│ │ ├── Main.css
+│ │ ├── MainPage.js
+│ │ └── waspLogo.png
+│ ├── server
+│ │ └── jsconfig.json
+│ ├── shared
+│ │ └── jsconfig.json
+│ └── .waspignore
+└── .wasproot
+```
+Main differences:
+- All server-side code must be located inside the `src/server` directory. Wasp
+declarations must import this code with `import foo from "@server/foo.js"`
+(instead of `import foo from "@ext/foo.js"`)
+- All client-side code must be located inside the `src/client` directory. Wasp
+declarations must import this code with `import foo from "@client/bar.js"`
+(instead of `import bar from "@ext/bar.js"`)
+- All shared code (i.e., used on both the client and the server) must be
+located inside the `src/shared` and imported where needed through a relative import.
+- Each of these subdirectories (i.e., `src/server`, `src/client`, and
+`src/shared`) comes with a pregenerated `jsconfig.json` file. This file helps
+with IDE support (e.g., jumping to definitions, previewing types, etc.) and you
+shouldn't delete it.
+
+The new structure is fully reflected in [our docs](https://wasp-lang.dev/docs/language/overview), but we'll also
+provide a quick guide for migrating existing projects.
+
+##### Migrating an existing Wasp project to the new structure
+
+You can easily migrate your old Wasp project to the new structure by following a
+series of steps. Assuming you have a project called `foo` inside the
+directory `foo`, you should:
+ 1. Install the latest version of Wasp
+ 2. Rename your project's root directory to something like `foo_old`
+ 3. Create a new project by running `wasp new foo`
+ 4. Copy all server-side code from `foo_old/ext` to `foo/src/server`
+ 5. Copy all client-side code from `foo_old/ext` to `foo/src/client`
+ 6. Copy all shared code (if any) from `foo_old/ext` to `foo/src/shared` and
+ adapt imports in files that reference it:
+ - For example, `import bar from './bar.js'` becomes `import bar from "../shared/bar.js"`
+ 7. Copy all lines you might have added to `foo_old/.gitignore` into
+ `foo/.gitignore`
+ 8. Finally, copy `foo_old/main.wasp` to `foo/main.wasp` and correct external
+ imports:
+ - Queries, Actions, Jobs, and the Server setup function must import their code from `@server`
+ - Pages and the Client setup function must import their code from `@client`
+
+ For example, if you previously had something like:
+ ```js
+ page LoginPage {
+ // This previously resolved to ext/LoginPage.js
+ component: import Login from "@ext/LoginPage.js"
+ }
+
+ // ...
+
+ query getTasks {
+ // This previously resolved to ext/queries.js
+ fn: import { getTasks } from "@ext/queries.js",
+ }
+ ```
+
+ You should change it to:
+
+ ```js
+ page LoginPage {
+ // This resolves to src/client/LoginPage.js
+ component: import Login from "@client/LoginPage.js"
+ }
+
+ // ...
+
+ query getTasks {
+ // This resolves to src/server/queries.js
+ fn: import { getTasks } from "@server/queries.js",
+ }
+ ```
+ Do this for all external imports in your `.wasp` file. After you're done, there shouldn't be any occurences of the string `"@ext"`.
+
+That's it! You should now have a fully working Wasp project in the `foo` directory.
+
### [NEW FEATURE] Dockerfile customization
You can now customize the default Wasp Dockerfile by either extending/replacing our build stages or using your own custom logic. To make use of this feature, simply add a Dockerfile to the root of your project and it will be appended to the bottom of the existing Wasp Dockerfile.
diff --git a/web/blog/2021-12-02-waspello.md b/web/blog/2021-12-02-waspello.md
index 7a732e99f3..b7d8d87a72 100644
--- a/web/blog/2021-12-02-waspello.md
+++ b/web/blog/2021-12-02-waspello.md
@@ -102,7 +102,7 @@ The first step is to declare to Wasp there will be a query, point to the actual
```js title="main.wasp | Declaration of a query in Wasp"
query getListsAndCards {
// Points to the function which contains query logic.
- fn: import { getListsAndCards } from "@ext/queries.js",
+ fn: import { getListsAndCards } from "@server/queries.js",
// This query depends on List and Card entities.
// If any of them changes this query will get re-fetched (cache invalidation).
@@ -113,7 +113,7 @@ query getListsAndCards {
The main point of this declaration is for Wasp to be aware of the query and thus be able to **do a lot of heavy lifting for us - e.g. it will make the query available to the client without any extra code**, all that developer needs to do is import it in their React component. **Another big thing is cache invalidation / automatic re-fetching of the query once the data changes** (this is why it is important to declare which entities it depends on).
The remaining step is to write the function with the query logic:
-```js title="ext/queries.js | Query logic, using Prisma SDK via Node.js"
+```js title="src/server/queries.js | Query logic, using Prisma SDK via Node.js"
export const getListsAndCards = async (args, context) => {
// Only authenticated users can execute this query.
if (!context.user) { throw new HttpError(403) }
@@ -135,15 +135,15 @@ To display all the nice data we have, we'll use React components. There are no l
route MainRoute { path: "/", to: Main }
page Main {
authRequired: true,
- component: import Main from "@ext/MainPage.js"
+ component: import Main from "@client/MainPage.js"
}
```
All pretty straightforward so far! As you can see here, Wasp also provides [authentication out-of-the-box](/docs/language/features#authentication--authorization).
-Currently, the majority of the client logic of Waspello is contained in `ext/MainPage.js` (we should break it down a little 😅 - [you can help us!](https://github.com/wasp-lang/wasp/issues/334)). Just to give you an idea, here's a quick glimpse into it:
+Currently, the majority of the client logic of Waspello is contained in `src/client/MainPage.js` (we should break it down a little 😅 - [you can help us!](https://github.com/wasp-lang/wasp/issues/334)). Just to give you an idea, here's a quick glimpse into it:
-```js title="ext/MainPage.js | Using React component in Wasp"
+```js title="src/client/MainPage.js | Using React component in Wasp"
// "Special" imports provided by Wasp.
import { useQuery } from '@wasp/queries'
import getListsAndCards from '@wasp/queries/getListsAndCards'
diff --git a/web/blog/2022-01-27-waspleau.md b/web/blog/2022-01-27-waspleau.md
index 2ff0720f3c..39c6260bc9 100644
--- a/web/blog/2022-01-27-waspleau.md
+++ b/web/blog/2022-01-27-waspleau.md
@@ -60,12 +60,12 @@ app waspleau {
...
server: {
- setupFn: import serverSetup from "@ext/serverSetup.js"
+ setupFn: import serverSetup from "@server/serverSetup.js"
}
}
```
-```js title="serverSetup.js"
+```js title="src/server/serverSetup.js"
import Queue from 'bull'
const queue = new Queue('waspleau', process.env.REDIS_URL || 'redis://127.0.0.1:6379',
@@ -85,7 +85,7 @@ export default async () => {
Awesome, we can now enqueue and process background jobs, but how can we make it easy to create many different kinds of jobs and schedule them to run at different intervals? For Waspleau, we created our own type of worker object convention to help standardize and simplify adding more:
-```js title="workers/template.js"
+```js title="src/server/workers/template.js"
const workerFunction = async (opts) => {
return [
{ name: 'Metric 1 name', value: 'foo', updatedAt: ... },
@@ -98,7 +98,7 @@ export const workerTemplate = { name: 'Job Name', fn: workerFunction, schedule:
With this `workerFunction` setup, we can return one or more metrics per worker type. Waspleau can easily use any module that exports this shape. Here is a real example from the demo that makes HTTP calls to GitHub’s API with Axios:
-```js title="workers/github.js"
+```js title="src/server/workers/github.js"
import axios from 'axios'
const workerFunction = async (opts) => {
@@ -124,7 +124,7 @@ const workerFunction = async (opts) => {
export const githubWorker = { name: 'GitHub API', fn: workerFunction, schedule: '*/10 * * * *' }
```
-_Note: Please see the [actual serverSetup.js file](https://github.com/wasp-lang/wasp/blob/main/examples/waspleau/ext/serverSetup.js) for how we use this abstraction in practice._
+_Note: Please see the [actual serverSetup.js file](https://github.com/wasp-lang/wasp/blob/main/examples/waspleau/src/server/serverSetup.js) for how we use this abstraction in practice._
### Server → client
@@ -134,11 +134,11 @@ We now have jobs running and data updating at regular intervals, nice, but we st
...
query dashboard {
- fn: import { refreshDashboardData } from "@ext/dashboard.js"
+ fn: import { refreshDashboardData } from "@server/dashboard.js"
}
```
-```js title="dashboard.js"
+```js title="src/server/dashboard.js"
import { getDashboardData } from './serverSetup.js'
export const refreshDashboardData = async (_args, _context) => {
@@ -146,7 +146,7 @@ export const refreshDashboardData = async (_args, _context) => {
}
```
-```js title="serverSetup.js"
+```js title="src/server/serverSetup.js"
...
const dashboardData = {} // This is updated in the queue process callback
@@ -155,7 +155,7 @@ export const getDashboardData = () => Object.values(dashboardData).flat()
From there, we can request it on the frontend in React components as usual and also set a one-minute client-side refetch interval just for good measure:
-```js title="MainPage.js"
+```js title="src/client/MainPage.js"
...
const { data: dashboardData, isFetching, error } = useQuery(refreshDashboardData, null, { refetchInterval: 60 * 1000 })
diff --git a/web/blog/2022-06-15-jobs-feature-announcement.md b/web/blog/2022-06-15-jobs-feature-announcement.md
index c547065fa4..464739c702 100644
--- a/web/blog/2022-06-15-jobs-feature-announcement.md
+++ b/web/blog/2022-06-15-jobs-feature-announcement.md
@@ -45,7 +45,25 @@ You wouldn’t want the server to delay sending its HTTP response until those ar
The typical solution here is to use a job queue of some kind. They are not impossible to set up, of course, but there is a fair amount of boilerplate involved, some operational expertise/overhead required, and moving from one system to another when you outgrow it is usually a challenge. These are the exact areas where we feel Wasp can provide real value, so we are happy to introduce Wasp Jobs to help out with this!
-
+```js title=src/server/workers/github.js
+import axios from 'axios'
+import { upsertMetric } from './utils.js'
+
+export async function workerFunction() {
+ const response = await axios.get('https://api.github.com/repos/wasp-lang/wasp')
+
+ const metrics = [
+ { name: 'Wasp GitHub Stars', value: response.data.stargazers_count },
+ { name: 'Wasp GitHub Language', value: response.data.language },
+ { name: 'Wasp GitHub Forks', value: response.data.forks },
+ { name: 'Wasp GitHub Open Issues', value: response.data.open_issues },
+ ]
+
+ await Promise.all(metrics.map(upsertMetric))
+
+ return metrics
+}
+```
Wasp allows you to write a regular async JavaScript function (like the one above that gathers GitHub metrics and stores them in the DB) and have it run within the context of a job queue system, which we call an executor. You can manually submit work to be done on the server, or specify a cron schedule to have your job automatically invoked. And, best of all, as we add more job executors in the future, you can change where it runs on a single line in your .wasp file.
@@ -72,11 +90,51 @@ However, we will also continue to expand the number of job execution runtimes we
If you are a regular reader of this blog (thank you, you deserve a raise! 😊), you may recall we created an example app of a metrics dashboard called [Waspleau](https://wasp-lang.dev/blog/2022/01/27/waspleau) that used workers in the background to make periodic HTTP calls for data. In that example, we didn’t yet have access to recurring jobs in Wasp, so we used Bull for scheduled jobs instead. To set up our queue-related logic we had to have this huge `setupFn` wiring it all up; but now, we can remove all that code and simply use jobs instead! Here is what the new DSL looks like:
-
+```js title=main.wasp
+// A cron job for fetching GitHub stats
+job getGithubStats {
+ executor: PgBoss,
+ perform: {
+ fn: import { workerFunction } from "@server/workers/github.js"
+ },
+ schedule: {
+ cron: "*/10 * * * *"
+ }
+}
+
+// A cron job to measure how long a webpage takes to load
+job calcPageLoadTime {
+ executor: PgBoss,
+ perform: {
+ fn: import { workerFunction } from "@server/workers/loadTime.js"
+ },
+ schedule: {
+ cron: "*/5 * * * *",
+ args: {=json {
+ "url": "https://wasp-lang.dev",
+ "name": "wasp-lang.dev Load Time"
+ } json=}
+ }
+}
+```
And here is an example of how you can reference and invoke jobs on the server. *Note: We did not even need to do this step since jobs with a schedule are automatically configured to run at the desired time.*
-
-
+```js title=src/server/serverSetup.js
+/**
+* These Jobs are automatically scheduled by Wasp.
+* However, let's kick them off on server setup to ensure we have data right away.
+*/
+import { github } from '@wasp/jobs/getGithubStats.js'
+import { loadTime } from '@wasp/jobs/calcPageLoadTime.js'
+
+export default async function () {
+ await github.submit()
+ await loadTime.submit({
+ url: "https://wasp-lang.dev",
+ name: "wasp-lang.dev Load Time"
+ })
+}
+```
And voila, it is really that simple. Wasp takes care of setting up pg-boss and hooking up all your job callbacks, leaving you to focus on what matters- your own code. Here is a visual of what is happening behind the scenes:
diff --git a/web/blog/2022-09-05-dev-excuses-app-tutrial.md b/web/blog/2022-09-05-dev-excuses-app-tutrial.md
index 4ae364b6a4..9161e7b363 100644
--- a/web/blog/2022-09-05-dev-excuses-app-tutrial.md
+++ b/web/blog/2022-09-05-dev-excuses-app-tutrial.md
@@ -102,9 +102,9 @@ app ItWaspsOnMyMachine {
// Render page MainPage on url `/` (default url).
route RootRoute { path: "/", to: MainPage }
-// ReactJS implementation of our page located in `ext/MainPage.js` as a default export
+// ReactJS implementation of our page located in `src/client/MainPage.js` as a default export.
page MainPage {
- component: import Main from "@ext/MainPage.js"
+ component: import Main from "@client/MainPage.js"
}
// Prisma database entity
@@ -115,19 +115,19 @@ psl=}
// Query declaration to get a new excuse
query getExcuse {
- fn: import { getExcuse } from "@ext/queries.js",
+ fn: import { getExcuse } from "@server/queries.js",
entities: [Excuse]
}
// Query declaration to get all excuses
query getAllSavedExcuses {
- fn: import { getAllSavedExcuses } from "@ext/queries.js",
+ fn: import { getAllSavedExcuses } from "@server/queries.js",
entities: [Excuse]
}
// Action to save current excuse
action saveExcuse {
- fn: import { saveExcuse } from "@ext/actions.js",
+ fn: import { saveExcuse } from "@server/actions.js",
entities: [Excuse]
}
```
@@ -139,9 +139,9 @@ Also, we’ve declared a database entity called `Excuse`, queries, and action. T
`Queries` are here when we need to fetch/read something, while `actions` are here when we need to change/update data. Both query and action declaration consists of two lines – a reference to the file that contains implementation and a data model to operate on. You can find more info [in the docs](https://wasp-lang.dev/docs/tutorials/todo-app/listing-tasks#introducing-operations-queries-and-actions). So let’s proceed with queries/actions.
-**2) Create two files: “actions.js” and “queries.js” in the `ext` folder.**
+**2) Create two files: “actions.js” and “queries.js” in the `src/server` folder.**
-```js title=".../ext/actions.js | Defining an action"
+```js title="src/server/actions.js | Defining an action"
export const saveExcuse = async (excuse, context) => {
return context.entities.Excuse.create({
data: { text: excuse.text }
@@ -149,7 +149,7 @@ export const saveExcuse = async (excuse, context) => {
}
```
-```js title=".../ext/queries.js | Defining queries"
+```js title="src/server/queries.js | Defining queries"
import axios from 'axios';
export const getExcuse = async () => {
@@ -175,7 +175,7 @@ That’s it! We finished our back-end. 🎉 Now, let’s use those queries/actio
**3) Let’s erase everything we had in the `MainPage.js` file and substitute it with our new UI.**
-```js title=".../ext/MainPage.js | Updating the UI"
+```js title="src/client/MainPage.js | Updating the UI"
import React, { useState } from 'react'
import { useQuery } from '@wasp/queries'
import getExcuse from '@wasp/queries/getExcuse'