-```c
+```wasp
auth: {
userEntity: User,
externalAuthEntity: SocialLogin,
@@ -1452,7 +1452,7 @@ It is also posslbe to [override the default](features#overrides-for-social-login
#### `externalAuthEntity`
Anytime an authentication method is used that relies on an external authorization provider, for example, Google, we require an `externalAuthEntity` specified in `auth`, in addition to the `userEntity`, that contains the following configuration:
-```c {4,14}
+```wasp {4,14}
//...
auth: {
userEntity: User,
@@ -1519,7 +1519,7 @@ Alternatively, you could add a `displayName` property to your User entity and as
We also show you how to customize the configuration of the Provider's settings using:
- the `configFn` function
-```c title=main.wasp {9,10,13,14,26}
+```wasp title=main.wasp {9,10,13,14,26}
app Example {
//...
@@ -1634,15 +1634,15 @@ import AuthError from '@wasp/core/AuthError.js'
##### Example of usage:
```js
- try {
- await context.entities.User.update(...)
- } catch (e) {
- if (e instanceof AuthError) {
- throw new HttpError(422, 'Validation failed', { message: e.message })
- } else {
- throw e
- }
+try {
+ await context.entities.User.update(...)
+} catch (e) {
+ if (e instanceof AuthError) {
+ throw new HttpError(422, 'Validation failed', { message: e.message })
+ } else {
+ throw e
}
+}
```
## Accessing the currently logged in user
@@ -1726,7 +1726,7 @@ should be denied access to it.
You can configure the client using the `client` field inside the `app`
declaration,
-```c
+```wasp
app MyApp {
title: "My app",
// ...
@@ -1870,7 +1870,7 @@ explained in
Via `server` field of `app` declaration, you can configure behaviour of the Node.js server (one that is executing wasp operations).
-```c
+```wasp
app MyApp {
title: "My app",
// ...
@@ -1978,7 +1978,7 @@ console.log(process.env.DATABASE_URL)
Via `db` field of `app` declaration, you can configure the database used by Wasp.
-```c
+```wasp
app MyApp {
title: "My app",
// ...
@@ -2046,7 +2046,7 @@ Seeding is most commonly used for two following scenarios:
Wasp enables you to define multiple **seed functions** via `app.db.seeds`:
-```c
+```wasp
app MyApp {
// ...
db: {
@@ -2127,7 +2127,7 @@ Check out [our guide](/docs/guides/sending-emails#using-the-mailgun-provider) fo
You can optionally provide a default sender info that will be used when you don't provide it explicitly when sending an e-mail.
-```c
+```wasp
app MyApp {
title: "My app",
// ...
diff --git a/web/docs/language/overview.md b/web/docs/language/overview.md
index 1c05ccad6..d47c08cb8 100644
--- a/web/docs/language/overview.md
+++ b/web/docs/language/overview.md
@@ -42,7 +42,7 @@ TodoApp/
- shared/
```
-```css title="main.wasp"
+```wasp title="main.wasp"
app todoApp {
wasp: {
version: "^0.6.0"
diff --git a/web/docs/language/syntax.md b/web/docs/language/syntax.md
index 2e3d9a5ad..eddf4b78c 100644
--- a/web/docs/language/syntax.md
+++ b/web/docs/language/syntax.md
@@ -8,7 +8,7 @@ Wasp is a declarative, statically typed, domain specific language (DSL).
The central point of Wasp language are **declarations**, and Wasp source is at the end just a bunch of declarations, each of them describing a part of your web app.
-```c
+```wasp
app MyApp {
title: "My app"
}
diff --git a/web/docs/tutorials/todo-app/01-creating-new-project.md b/web/docs/tutorials/todo-app/01-creating-new-project.md
index 26ab42df8..0b11a1289 100644
--- a/web/docs/tutorials/todo-app/01-creating-new-project.md
+++ b/web/docs/tutorials/todo-app/01-creating-new-project.md
@@ -85,7 +85,7 @@ Let's start with the `main.wasp` file, which introduces 3 new concepts:
[page](language/features.md#page) and
[route](language/features.md#route).
-```c title="main.wasp"
+```wasp title="main.wasp"
app TodoApp { // Main declaration, defines a new web app.
wasp: {
version: "^0.10.0"
diff --git a/web/docs/tutorials/todo-app/02-task-entity.md b/web/docs/tutorials/todo-app/02-task-entity.md
index 048456419..c640b50d7 100644
--- a/web/docs/tutorials/todo-app/02-task-entity.md
+++ b/web/docs/tutorials/todo-app/02-task-entity.md
@@ -8,7 +8,7 @@ import useBaseUrl from '@docusaurus/useBaseUrl';
[Entities](language/features.md#entity) are one of the very central concepts in Wasp, and they mainly play the role of data models.
Since our TodoApp is all about tasks, we will define a Task entity in Wasp:
-```c title="main.wasp"
+```wasp title="main.wasp"
// ...
entity Task {=psl
diff --git a/web/docs/tutorials/todo-app/03-listing-tasks.md b/web/docs/tutorials/todo-app/03-listing-tasks.md
index be9bb5f29..436974207 100644
--- a/web/docs/tutorials/todo-app/03-listing-tasks.md
+++ b/web/docs/tutorials/todo-app/03-listing-tasks.md
@@ -25,7 +25,7 @@ It consists of a declaration in Wasp and implementation in JS (in `src/server/`
### Wasp declaration
Add the following code to `main.wasp`:
-```c title="main.wasp"
+```wasp title="main.wasp"
// ...
query getTasks {
diff --git a/web/docs/tutorials/todo-app/04-creating-tasks.md b/web/docs/tutorials/todo-app/04-creating-tasks.md
index d5983cc8e..ceee1e91f 100644
--- a/web/docs/tutorials/todo-app/04-creating-tasks.md
+++ b/web/docs/tutorials/todo-app/04-creating-tasks.md
@@ -15,7 +15,7 @@ Creating an action is very similar to creating a query.
### Wasp declaration
First, we declare the action in Wasp:
-```c title="main.wasp"
+```wasp title="main.wasp"
// ...
action createTask {
diff --git a/web/docs/tutorials/todo-app/05-updating-tasks.md b/web/docs/tutorials/todo-app/05-updating-tasks.md
index 122de8a77..be45423c3 100644
--- a/web/docs/tutorials/todo-app/05-updating-tasks.md
+++ b/web/docs/tutorials/todo-app/05-updating-tasks.md
@@ -16,7 +16,7 @@ For that, we will need to do two things:
### Wasp declaration
We declare a Wasp action:
-```c title="main.wasp"
+```wasp title="main.wasp"
// ...
action updateTask {
diff --git a/web/docs/tutorials/todo-app/06-auth.md b/web/docs/tutorials/todo-app/06-auth.md
index d6218143c..445bccfae 100644
--- a/web/docs/tutorials/todo-app/06-auth.md
+++ b/web/docs/tutorials/todo-app/06-auth.md
@@ -18,7 +18,7 @@ Let's define a Todo list (luckily we have an app for that now ;)) to get this do
## Adding entity User
First, let's define the `User` entity:
-```c title="main.wasp"
+```wasp title="main.wasp"
// ...
entity User {=psl
@@ -37,7 +37,7 @@ to propagate the schema change (we added User).
## Defining `app.auth`
Next, we want to tell Wasp that we want full-stack [authentication](language/features.md#authentication--authorization) in our app, and that it should use the `User` entity for it:
-```c {7-16} title="main.wasp"
+```wasp {7-16} title="main.wasp"
app TodoApp {
wasp: {
version: "^0.7.0"
@@ -76,7 +76,7 @@ To recap, so far we have defined:
When we defined `app.auth` we got login and signup forms generated for us, but now we have to create Login and Signup pages that use them. In our `main.wasp` file we'll add the following:
-```c title="main.wasp"
+```wasp title="main.wasp"
// ...
route SignupRoute { path: "/signup", to: SignupPage }
@@ -141,7 +141,7 @@ Now, let's see how we're going to handle the situation when the user is not logg
`MainPage` page is a private page and we want users to be able to see it only if they are authenticated.
Wasp allows you to simply enforce private pages using the `authRequired` field:
-```c {3} title="main.wasp"
+```wasp {3} title="main.wasp"
// ...
page MainPage {
authRequired: true,
@@ -186,7 +186,7 @@ That is because we did not yet update queries and actions to work only on the cu
## Defining User-Task relation in entities
First, let's define a one-to-many relation between User and Task (check the [prisma docs on relations](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-schema/relations)):
-```c {6,13-14} title="main.wasp"
+```wasp {6,13-14} title="main.wasp"
// ...
entity User {=psl
id Int @id @default(autoincrement())
diff --git a/web/docs/tutorials/todo-app/07-dependencies.md b/web/docs/tutorials/todo-app/07-dependencies.md
index 3cabbae48..27e3db7d9 100644
--- a/web/docs/tutorials/todo-app/07-dependencies.md
+++ b/web/docs/tutorials/todo-app/07-dependencies.md
@@ -10,7 +10,7 @@ What is a Todo app without some clocks!? Well, still a Todo app, but certainly n
So, let's add a couple of clocks to our app, to help us track time while we perform our tasks (and to demonstrate the `app.dependencies` feature).
For this, we will use the `react-clock` library from NPM. We can add it to our project as a [dependency](language/features.md#dependencies) like this:
-```c {4-6} title="main.wasp"
+```wasp {4-6} title="main.wasp"
app TodoApp {
// ...
diff --git a/web/docs/typescript.md b/web/docs/typescript.md
index f67b30af4..a861a6950 100644
--- a/web/docs/typescript.md
+++ b/web/docs/typescript.md
@@ -35,7 +35,7 @@ Our scaffolding already includes TypeScript, so migrating your project to TypeSc
Let's first assume your Wasp file contains the following definitions:
-```c title=main.wasp
+```wasp title=main.wasp
entity Task {=psl
id Int @id @default(autoincrement())
description String
@@ -103,7 +103,7 @@ You don't need to change anything inside the `.wasp` file.
Even when you use TypeScript, and your file is called `queries.ts`, you still need to import it using the `.js` extension:
-```c
+```wasp
query getTaskInfo {
fn: import { getTaskInfo } from "@server/queries.js",
entities: [Task]
@@ -166,7 +166,7 @@ The mentioned type safety mechanisms also apply here: changing the task entity i
Wasp automatically generates the appropriate types for all Operations (i.e., Actions and Queries) you define inside your `.wasp` file. Assuming your `.wasp` file contains the following definition:
-```c title=main.wasp
+```wasp title=main.wasp
// ...
query GetTaskInfo {
diff --git a/web/docusaurus.config.js b/web/docusaurus.config.js
index 1e5541a36..43a6f2d51 100644
--- a/web/docusaurus.config.js
+++ b/web/docusaurus.config.js
@@ -1,5 +1,4 @@
const lightCodeTheme = require("prism-react-renderer/themes/github");
-const darkCodeTheme = require("prism-react-renderer/themes/dracula");
/** @type {import('@docusaurus/types').DocusaurusConfig} */
module.exports = {
@@ -82,6 +81,7 @@ module.exports = {
},
prism: {
additionalLanguages: ["shell-session", "haskell"],
+ theme: lightCodeTheme,
},
footer: {
style: "dark",
@@ -157,7 +157,7 @@ module.exports = {
// Please change this to your repo.
blogSidebarCount: "ALL",
blogSidebarTitle: "All our posts",
- postsPerPage: 'ALL',
+ postsPerPage: "ALL",
editUrl: "https://github.com/wasp-lang/wasp/edit/main/web/blog",
},
theme: {
diff --git a/web/package-lock.json b/web/package-lock.json
index 65e2c539e..52329071c 100644
--- a/web/package-lock.json
+++ b/web/package-lock.json
@@ -20,11 +20,11 @@
"plugin-image-zoom": "github:flexanalytics/plugin-image-zoom",
"postcss": "^8.4.19",
"prism-react-renderer": "^1.3.5",
+ "prismjs": "^1.29.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-feather": "^2.0.10",
"react-modal": "^3.14.3",
- "react-syntax-highlighter": "^15.5.0",
"react-tooltip": "^4.5.1",
"react-transition-group": "^4.4.5",
"tailwindcss": "^3.2.4"
@@ -5844,17 +5844,6 @@
"reusify": "^1.0.4"
}
},
- "node_modules/fault": {
- "version": "1.0.4",
- "license": "MIT",
- "dependencies": {
- "format": "^0.2.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/faye-websocket": {
"version": "0.11.4",
"license": "Apache-2.0",
@@ -6124,12 +6113,6 @@
"node": ">=6"
}
},
- "node_modules/format": {
- "version": "0.2.2",
- "engines": {
- "node": ">=0.4.x"
- }
- },
"node_modules/forwarded": {
"version": "0.2.0",
"license": "MIT",
@@ -6554,13 +6537,6 @@
"he": "bin/he"
}
},
- "node_modules/highlight.js": {
- "version": "10.7.3",
- "license": "BSD-3-Clause",
- "engines": {
- "node": "*"
- }
- },
"node_modules/history": {
"version": "4.10.1",
"license": "MIT",
@@ -7453,18 +7429,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/lowlight": {
- "version": "1.20.0",
- "license": "MIT",
- "dependencies": {
- "fault": "^1.0.0",
- "highlight.js": "~10.7.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/lru-cache": {
"version": "5.1.1",
"license": "ISC",
@@ -8965,7 +8929,8 @@
},
"node_modules/prismjs": {
"version": "1.29.0",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
+ "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==",
"engines": {
"node": ">=6"
}
@@ -9431,20 +9396,6 @@
"react": ">=15"
}
},
- "node_modules/react-syntax-highlighter": {
- "version": "15.5.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.3.1",
- "highlight.js": "^10.4.1",
- "lowlight": "^1.17.0",
- "prismjs": "^1.27.0",
- "refractor": "^3.6.0"
- },
- "peerDependencies": {
- "react": ">= 0.14.0"
- }
- },
"node_modules/react-textarea-autosize": {
"version": "8.4.1",
"resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.4.1.tgz",
@@ -9543,26 +9494,6 @@
"node": ">=6.0.0"
}
},
- "node_modules/refractor": {
- "version": "3.6.0",
- "license": "MIT",
- "dependencies": {
- "hastscript": "^6.0.0",
- "parse-entities": "^2.0.0",
- "prismjs": "~1.27.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/refractor/node_modules/prismjs": {
- "version": "1.27.0",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/regenerate": {
"version": "1.4.2",
"license": "MIT"
@@ -16030,12 +15961,6 @@
"reusify": "^1.0.4"
}
},
- "fault": {
- "version": "1.0.4",
- "requires": {
- "format": "^0.2.0"
- }
- },
"faye-websocket": {
"version": "0.11.4",
"requires": {
@@ -16203,9 +16128,6 @@
}
}
},
- "format": {
- "version": "0.2.2"
- },
"forwarded": {
"version": "0.2.0"
},
@@ -16468,9 +16390,6 @@
"he": {
"version": "1.2.0"
},
- "highlight.js": {
- "version": "10.7.3"
- },
"history": {
"version": "4.10.1",
"requires": {
@@ -16979,13 +16898,6 @@
"lowercase-keys": {
"version": "1.0.1"
},
- "lowlight": {
- "version": "1.20.0",
- "requires": {
- "fault": "^1.0.0",
- "highlight.js": "~10.7.0"
- }
- },
"lru-cache": {
"version": "5.1.1",
"requires": {
@@ -17774,7 +17686,9 @@
"requires": {}
},
"prismjs": {
- "version": "1.29.0"
+ "version": "1.29.0",
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
+ "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q=="
},
"process-nextick-args": {
"version": "2.0.1"
@@ -18074,16 +17988,6 @@
"tiny-warning": "^1.0.0"
}
},
- "react-syntax-highlighter": {
- "version": "15.5.0",
- "requires": {
- "@babel/runtime": "^7.3.1",
- "highlight.js": "^10.4.1",
- "lowlight": "^1.17.0",
- "prismjs": "^1.27.0",
- "refractor": "^3.6.0"
- }
- },
"react-textarea-autosize": {
"version": "8.4.1",
"resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.4.1.tgz",
@@ -18147,19 +18051,6 @@
"minimatch": "^3.0.5"
}
},
- "refractor": {
- "version": "3.6.0",
- "requires": {
- "hastscript": "^6.0.0",
- "parse-entities": "^2.0.0",
- "prismjs": "~1.27.0"
- },
- "dependencies": {
- "prismjs": {
- "version": "1.27.0"
- }
- }
- },
"regenerate": {
"version": "1.4.2"
},
diff --git a/web/package.json b/web/package.json
index cda6d09d2..c80d6b02f 100644
--- a/web/package.json
+++ b/web/package.json
@@ -26,11 +26,11 @@
"plugin-image-zoom": "github:flexanalytics/plugin-image-zoom",
"postcss": "^8.4.19",
"prism-react-renderer": "^1.3.5",
+ "prismjs": "^1.29.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-feather": "^2.0.10",
"react-modal": "^3.14.3",
- "react-syntax-highlighter": "^15.5.0",
"react-tooltip": "^4.5.1",
"react-transition-group": "^4.4.5",
"tailwindcss": "^3.2.4"
diff --git a/web/src/components/CodeHighlight.js b/web/src/components/CodeHighlight.js
new file mode 100644
index 000000000..49019bab3
--- /dev/null
+++ b/web/src/components/CodeHighlight.js
@@ -0,0 +1,39 @@
+import React, { useEffect } from "react";
+import Prism from "prismjs";
+import "../css/prismjs-github-theme.css";
+
+export default function CodeHighlight(props = {}) {
+ const codeRef = React.createRef();
+ const {
+ prefixCls = "code-highlight-wrapper",
+ className,
+ language,
+ source,
+ children,
+ ...others
+ } = props;
+ const langCls = language ? `language-${language}` : "";
+ async function highlight() {
+ if (codeRef.current) {
+ Prism.highlightElement(codeRef.current);
+ }
+ }
+ useEffect(() => {
+ highlight();
+ }, [language, source]);
+ return (
+
+
+ {source || children}
+
+
+ );
+}
diff --git a/web/src/components/Hero.js b/web/src/components/Hero.js
index 728d0b4ed..9bf7e93a8 100644
--- a/web/src/components/Hero.js
+++ b/web/src/components/Hero.js
@@ -1,7 +1,10 @@
import React from 'react'
import Link from '@docusaurus/Link'
-import SyntaxHighlighter from 'react-syntax-highlighter'
-import { qtcreatorLight, atomOneLight, atomOneDark, a11ylight } from 'react-syntax-highlighter/dist/cjs/styles/hljs'
+
+import './prismCustomization'
+
+import CodeHighlight from './CodeHighlight'
+
import { Terminal, ArrowUpRight, Play, BookOpen, Grid, Layout, Trello } from 'react-feather'
// Terminal, BookOpen, Grid, Layout, Trello, FileText
@@ -174,20 +177,12 @@ entity Task {=psl ... psl=} // Your Prisma data model.
-
{/* Editor body */}
-
- {codeString}
-
+
{/* EOF code block wrapper */}
{/* EOF wrapper of header + code */}
{/* EOF col-span-6 */}
diff --git a/web/src/components/prismCustomization.js b/web/src/components/prismCustomization.js
new file mode 100644
index 000000000..31ce6a080
--- /dev/null
+++ b/web/src/components/prismCustomization.js
@@ -0,0 +1,6 @@
+import Prism from "prismjs";
+import addWaspLangauge from "../prism/wasp";
+import addPrismaLanguage from "../prism/prisma";
+
+addPrismaLanguage(Prism);
+addWaspLangauge(Prism);
diff --git a/web/src/css/custom.css b/web/src/css/custom.css
index 8d9f19a27..c91d5be77 100644
--- a/web/src/css/custom.css
+++ b/web/src/css/custom.css
@@ -5,7 +5,7 @@
* work well for content-centric websites.
*/
-@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap');
+@import url("https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap");
@tailwind base;
@tailwind components;
@@ -15,24 +15,43 @@
* Issue on Tailwind's repo: https://github.com/tailwindlabs/tailwindcss/discussions/2984
*/
@layer base {
- html {
- -webkit-tap-highlight-color: transparent;
- -webkit-font-smoothing: auto;
- }
+ html {
+ -webkit-tap-highlight-color: transparent;
+ -webkit-font-smoothing: auto;
+ }
}
-
-
/* Docusaurus stuff */
.blog-list-page {
background-color: var(--custom-blog-list-background-color);
}
+.pill {
+ padding: 0.2rem 0.5rem;
+ border-radius: 0.375rem;
+}
+
+.pill.pill-username-password {
+ background-color: var(--auth-ui-username-password-bg);
+}
+
+.pill.pill-email {
+ background-color: var(--auth-ui-email-bg);
+}
+
+/* Highlight Prisma field types properly */
+.token.type-class-name {
+ color: rgb(54, 172, 170);
+}
+.token.annotation {
+ color: rgb(116, 116, 116) !important;
+}
+
/* You can override the default Infima variables here. */
:root {
/* Our custom values */
- --custom-background-color: #FDFDFD;
+ --custom-background-color: #fdfdfd;
--custom-background-color-diff: #f4f4f4;
--custom-shadow-lw: 0 3px 5px 0px rgba(0, 0, 0, 0.1);
--custom-border-radius: 3px;
@@ -52,8 +71,8 @@
/* Infima overrides */
--ifm-container-width-xl: 1280px;
- --ifm-font-family-base: 'Inter';
- --ifm-color-primary: #BF9900; /* wasp color (ffcc00) darkened by 25% */
+ --ifm-font-family-base: "Inter";
+ --ifm-color-primary: #bf9900; /* wasp color (ffcc00) darkened by 25% */
--ifm-color-primary-dark: #8a6f04;
--ifm-color-primary-darker: rgb(31, 165, 136);
--ifm-color-primary-darkest: rgb(26, 136, 112);
@@ -76,14 +95,19 @@
--ifm-h2-font-size: 2rem;
--ifm-col-spacing-vertical: 0.5rem;
+ --docusaurus-highlighted-code-line-bg: #e8edf2;
+ --auth-ui-username-password-bg: #fee;
+ --auth-ui-email-bg: #eef;
}
-:root[data-theme='dark'] {
- --custom-background-color-diff: #2A2A2A;
+:root[data-theme="dark"] {
+ --custom-background-color-diff: #2a2a2a;
/* Blog */
--custom-blog-list-background-color: var(--ifm-background-color);
--custom-blog-card-timestamp-color: #a3a3a3;
--custom-blog-card-background-color: black;
+ --docusaurus-highlighted-code-line-bg: #dee6ed;
+ --auth-ui-username-password-bg: rgb(93, 57, 57);
+ --auth-ui-email-bg: rgb(71, 71, 112);
}
-
diff --git a/web/src/css/prismjs-github-theme.css b/web/src/css/prismjs-github-theme.css
new file mode 100644
index 000000000..8127de36e
--- /dev/null
+++ b/web/src/css/prismjs-github-theme.css
@@ -0,0 +1,127 @@
+/**
+ * GHColors theme by Avi Aryan (http://aviaryan.in)
+ * Inspired by Github syntax coloring
+ */
+
+code[class*="language-"],
+pre[class*="language-"] {
+ color: #393a34;
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
+ "Liberation Mono", "Courier New", monospace;
+ direction: ltr;
+ text-align: left;
+ white-space: pre;
+ word-spacing: normal;
+ word-break: normal;
+ font-size: 0.9em;
+ line-height: 1.2em;
+
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+
+ -webkit-hyphens: none;
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ hyphens: none;
+}
+
+pre > code[class*="language-"] {
+ font-size: 1em;
+}
+
+pre[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+code[class*="language-"] ::-moz-selection {
+ background: #b3d4fc;
+}
+
+pre[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+code[class*="language-"] ::selection {
+ background: #b3d4fc;
+}
+
+/* Code blocks */
+pre[class*="language-"] {
+ /* padding: 1em; */
+ /* margin: 0.5em 0; */
+ overflow: auto;
+ /* border: 1px solid #dddddd; */
+ background-color: #f6f8fa;
+}
+
+/* Inline code */
+:not(pre) > code[class*="language-"] {
+ padding: 0.2em;
+ padding-top: 1px;
+ padding-bottom: 1px;
+ background: #f8f8f8;
+ border: 1px solid #dddddd;
+}
+
+.token.comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+ color: #999988;
+ font-style: italic;
+}
+
+.token.namespace {
+ opacity: 0.7;
+}
+
+.token.string,
+.token.attr-value {
+ color: #e3116c;
+}
+
+.token.punctuation,
+.token.operator {
+ color: #393a34; /* no highlight */
+}
+
+.token.entity,
+.token.url,
+.token.symbol,
+.token.number,
+.token.boolean,
+.token.variable,
+.token.constant,
+.token.property,
+.token.regex,
+.token.inserted {
+ color: #36acaa;
+}
+
+.token.atrule,
+.token.keyword,
+.token.attr-name,
+.language-autohotkey .token.selector {
+ color: #00009f;
+}
+
+.token.function,
+.token.deleted,
+.language-autohotkey .token.tag {
+ color: #9a050f;
+}
+
+.token.tag,
+.token.selector,
+.language-autohotkey .token.keyword {
+ color: #00009f;
+}
+
+.token.important,
+.token.function,
+.token.bold {
+ font-weight: bold;
+}
+
+.token.italic {
+ font-style: italic;
+}
diff --git a/web/src/prism/prisma.js b/web/src/prism/prisma.js
new file mode 100644
index 000000000..7a970f6f5
--- /dev/null
+++ b/web/src/prism/prisma.js
@@ -0,0 +1,26 @@
+// Taken from the Prisma docs
+module.exports = (Prism) => {
+ Prism.languages.prisma = Prism.languages.extend("clike", {
+ keyword: /\b(?:datasource|enum|generator|model|type|view)\b/,
+ "type-class-name": /(\s+)[A-Z]\w+/, ///(\b)(\s+)[A-Z]\w+/
+ });
+
+ Prism.languages.javascript["class-name"][0].pattern =
+ /(\b(?:model|datasource|enum|generator|type)\s+)[\w.\\]+/;
+
+ Prism.languages.insertBefore("prisma", "function", {
+ annotation: {
+ pattern: /(^|[^.])@+\w+/,
+ lookbehind: true,
+ alias: "punctuation",
+ },
+ });
+
+ Prism.languages.insertBefore("prisma", "punctuation", {
+ "type-args": /\b(?:references|fields|onDelete|onUpdate):/,
+ });
+
+ Prism.languages.insertBefore("prisma", "type-class-name", {
+ "not-class": /\n(\s+)[A-Z]\w+/,
+ });
+};
diff --git a/web/src/prism/wasp.js b/web/src/prism/wasp.js
new file mode 100644
index 000000000..9e54b7cd9
--- /dev/null
+++ b/web/src/prism/wasp.js
@@ -0,0 +1,83 @@
+// Converted from the TextMate definition at https://github.com/wasp-lang/vscode-wasp/blob/main/syntaxes/wasp.tmLanguage.yaml
+module.exports = (Prism) => {
+ Prism.languages.wasp = {
+ "prisma-closure": {
+ pattern: /{=psl[\s\S]*?psl=}/,
+ inside: {
+ prisma: {
+ pattern: /[\s\S]+/,
+ inside: Prism.languages.prisma,
+ },
+ },
+ },
+ comment: {
+ pattern: /\/\/.*|\/\*[\s\S]*?\*\//,
+ greedy: true,
+ },
+ "json-closure": {
+ pattern: /{=json[\s\S]*?json=}/,
+ inside: {
+ punctuation: /[{}[\],]/,
+ property: {
+ pattern: /(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,
+ lookbehind: true,
+ greedy: true,
+ },
+ string: {
+ pattern: /(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,
+ lookbehind: true,
+ greedy: true,
+ },
+ number: /-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,
+ operator: /:/,
+ boolean: /\b(?:false|true)\b/,
+ null: {
+ pattern: /\bnull\b/,
+ alias: "keyword",
+ },
+ },
+ },
+ "js-import": {
+ pattern: /import.*",?/,
+ inside: Prism.languages.javascript,
+ },
+ string: {
+ pattern: /"(?:\\.|[^\\"\r\n])*"/,
+ greedy: true,
+ },
+ number: /-?\d+(?:\.\d+)?/,
+ boolean: /\b(?:true|false)\b/,
+ enum: {
+ pattern:
+ /\b(EmailAndPassword|PostgreSQL|SQLite|Simple|PgBoss|SMTP|SendGrid|Mailgun)\b/,
+ alias: "constant",
+ },
+ "dict-key": {
+ pattern: /[a-zA-Z]+(?=:)/,
+ alias: "plain",
+ },
+ "declaration-type": {
+ pattern: /\b(action|apiNamespace|api|app|entity|job|page|query|route)\b/,
+ alias: "keyword",
+ },
+ "class-name": {
+ pattern: /[a-zA-Z][0-9a-zA-Z]*/,
+ alias: "variable",
+ },
+ "http-method": {
+ pattern: /\b(ALL|GET|POST|PUT|DELETE)\b/,
+ alias: "constant",
+ },
+ array: {
+ pattern: /\[[\s\S]*?\]/,
+ inside: {
+ punctuation: /[{}[\],]/,
+ value: {
+ pattern: /[^,\s\]]+/,
+ alias: "variable",
+ },
+ },
+ },
+ punctuation: /[{}[\],]/,
+ };
+};
diff --git a/web/src/theme/prism-include-languages.js b/web/src/theme/prism-include-languages.js
new file mode 100644
index 000000000..311094ddc
--- /dev/null
+++ b/web/src/theme/prism-include-languages.js
@@ -0,0 +1,24 @@
+// This file gets auto-generated when you "eject" to add custom languages to Docosaurus
+// We use it to add support for Prisma and Wasp syntax highlighting
+import siteConfig from "@generated/docusaurus.config";
+export default function prismIncludeLanguages(PrismObject) {
+ const {
+ themeConfig: { prism },
+ } = siteConfig;
+ const { additionalLanguages } = prism;
+ // Prism components work on the Prism instance on the window, while prism-
+ // react-renderer uses its own Prism instance. We temporarily mount the
+ // instance onto window, import components to enhance it, then remove it to
+ // avoid polluting global namespace.
+ // You can mutate PrismObject: registering plugins, deleting languages... As
+ // long as you don't re-assign it
+ globalThis.Prism = PrismObject;
+ additionalLanguages.forEach((lang) => {
+ // eslint-disable-next-line global-require, import/no-dynamic-require
+ require(`prismjs/components/prism-${lang}`);
+ });
+
+ require("./prism-prisma");
+ require("./prism-wasp");
+ delete globalThis.Prism;
+}
diff --git a/web/src/theme/prism-prisma.js b/web/src/theme/prism-prisma.js
new file mode 100644
index 000000000..a74b43524
--- /dev/null
+++ b/web/src/theme/prism-prisma.js
@@ -0,0 +1 @@
+require("../prism/prisma")(Prism);
diff --git a/web/src/theme/prism-wasp.js b/web/src/theme/prism-wasp.js
new file mode 100644
index 000000000..914ac8cb6
--- /dev/null
+++ b/web/src/theme/prism-wasp.js
@@ -0,0 +1 @@
+require("../prism/wasp")(Prism);