feat: swagger
|
|
@ -15,7 +15,18 @@
|
|||
"main": "apps/backend/src/main.ts",
|
||||
"tsConfig": "apps/backend/tsconfig.app.json",
|
||||
"assets": ["apps/backend/src/assets"],
|
||||
"webpackConfig": "apps/backend/webpack.config.js"
|
||||
"webpackConfig": "apps/backend/webpack.config.js",
|
||||
"transformers": [
|
||||
{
|
||||
"name": "@nestjs/swagger/plugin",
|
||||
"options": {
|
||||
"dtoFileNameSuffix": [".dto.ts"],
|
||||
"controllerFileNameSuffix": [".controller.ts"],
|
||||
"introspectComments": true,
|
||||
"classValidatorShim": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"configurations": {
|
||||
"development": {},
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import {loadSwagger} from "@gitroom/helpers/swagger/load.swagger";
|
||||
|
||||
process.env.TZ='UTC';
|
||||
|
||||
import cookieParser from 'cookie-parser';
|
||||
|
|
@ -23,6 +25,8 @@ async function bootstrap() {
|
|||
app.use(cookieParser());
|
||||
app.useGlobalFilters(new SubscriptionExceptionFilter());
|
||||
|
||||
loadSwagger(app);
|
||||
|
||||
const port = process.env.PORT || 3000;
|
||||
await app.listen(port);
|
||||
Logger.log(
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
}
|
||||
],
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
# Mintlify Starter Kit
|
||||
|
||||
Click on `Use this template` to copy the Mintlify starter kit. The starter kit contains examples including
|
||||
|
||||
- Guide pages
|
||||
- Navigation
|
||||
- Customizations
|
||||
- API Reference pages
|
||||
- Use of popular components
|
||||
|
||||
### Development
|
||||
|
||||
Install the [Mintlify CLI](https://www.npmjs.com/package/mintlify) to preview the documentation changes locally. To install, use the following command
|
||||
|
||||
```
|
||||
npm i -g mintlify
|
||||
```
|
||||
|
||||
Run the following command at the root of your documentation (where mint.json is)
|
||||
|
||||
```
|
||||
mintlify dev
|
||||
```
|
||||
|
||||
### Publishing Changes
|
||||
|
||||
Install our Github App to autopropagate changes from youre repo to your deployment. Changes will be deployed to production automatically after pushing to the default branch. Find the link to install on your dashboard.
|
||||
|
||||
#### Troubleshooting
|
||||
|
||||
- Mintlify dev isn't running - Run `mintlify install` it'll re-install dependencies.
|
||||
- Page loads as a 404 - Make sure you are running in a folder with `mint.json`
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
## My Snippet
|
||||
|
||||
<Info>This is an example of a reusable snippet</Info>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /auth
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /auth/login
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /auth/registration
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /billing
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /billing/check/{id}
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /billing/cancel
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /billing/modify
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /billing/subscribe
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: delete /categories/{id}
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /categories/{id}
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /categories
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /categories/faq
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /categories
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /categories/order
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: put /categories/{id}
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: delete /faq/{id}
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /faq/{id}
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /faq/jobs/{id}
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /faq
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /faq/answers
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /faq/job
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /faq/jobs/questions
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /faq/order
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: put /faq/{id}/category/{category}
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: put /faq/{id}
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: delete /integrations/{id}
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /integrations/{type}/add
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /integrations
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /integrations
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /invite
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /invite/add
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: delete /settings/delete-domain/{id}
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /settings
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /settings/check-domain/{id}
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /settings/check-subdomain
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /settings/domain
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /settings/subDomain
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /stripe
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /styles
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: put /styles
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /users/self
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /users/sign-in
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: post /users/revalidate
|
||||
---
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
title: 'Introduction'
|
||||
---
|
||||
|
||||
<Note>
|
||||
If you're not looking to build API reference documentation, you can delete
|
||||
this section by removing the api-reference folder.
|
||||
</Note>
|
||||
|
||||
## Welcome
|
||||
|
||||
## How to use the API
|
||||
There are two main options to use the API:
|
||||
1. You can send an header called `auth` with the token you received when you logged in.
|
||||
2. You can send a cookie called `auth` with the token you received when you logged in.
|
||||
|
||||
The dashboard mainly uses the cookie method to authenticate requests.<br />
|
||||
But if you want to test the API with Swagger or Postman, you can use the `auth` header.
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
title: 'Code Blocks'
|
||||
description: 'Display inline code and code blocks'
|
||||
icon: 'code'
|
||||
---
|
||||
|
||||
## Basic
|
||||
|
||||
### Inline Code
|
||||
|
||||
To denote a `word` or `phrase` as code, enclose it in backticks (`).
|
||||
|
||||
```
|
||||
To denote a `word` or `phrase` as code, enclose it in backticks (`).
|
||||
```
|
||||
|
||||
### Code Block
|
||||
|
||||
Use [fenced code blocks](https://www.markdownguide.org/extended-syntax/#fenced-code-blocks) by enclosing code in three backticks and follow the leading ticks with the programming language of your snippet to get syntax highlighting. Optionally, you can also write the name of your code after the programming language.
|
||||
|
||||
```java HelloWorld.java
|
||||
class HelloWorld {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Hello, World!");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
````md
|
||||
```java HelloWorld.java
|
||||
class HelloWorld {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Hello, World!");
|
||||
}
|
||||
}
|
||||
```
|
||||
````
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
---
|
||||
title: 'Images and Embeds'
|
||||
description: 'Add image, video, and other HTML elements'
|
||||
icon: 'image'
|
||||
---
|
||||
|
||||
<img
|
||||
style={{ borderRadius: '0.5rem' }}
|
||||
src="https://mintlify-assets.b-cdn.net/bigbend.jpg"
|
||||
/>
|
||||
|
||||
## Image
|
||||
|
||||
### Using Markdown
|
||||
|
||||
The [markdown syntax](https://www.markdownguide.org/basic-syntax/#images) lets you add images using the following code
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
Note that the image file size must be less than 5MB. Otherwise, we recommend hosting on a service like [Cloudinary](https://cloudinary.com/) or [S3](https://aws.amazon.com/s3/). You can then use that URL and embed.
|
||||
|
||||
### Using Embeds
|
||||
|
||||
To get more customizability with images, you can also use [embeds](/writing-content/embed) to add images
|
||||
|
||||
```html
|
||||
<img height="200" src="/path/image.jpg" />
|
||||
```
|
||||
|
||||
## Embeds and HTML elements
|
||||
|
||||
<iframe
|
||||
width="560"
|
||||
height="315"
|
||||
src="https://www.youtube.com/embed/4KzFe50RQkQ"
|
||||
title="YouTube video player"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen
|
||||
style={{ width: '100%', borderRadius: '0.5rem' }}
|
||||
></iframe>
|
||||
|
||||
<br />
|
||||
|
||||
<Tip>
|
||||
|
||||
Mintlify supports [HTML tags in Markdown](https://www.markdownguide.org/basic-syntax/#html). This is helpful if you prefer HTML tags to Markdown syntax, and lets you create documentation with infinite flexibility.
|
||||
|
||||
</Tip>
|
||||
|
||||
### iFrames
|
||||
|
||||
Loads another HTML page within the document. Most commonly used for embedding videos.
|
||||
|
||||
```html
|
||||
<iframe src="https://www.youtube.com/embed/4KzFe50RQkQ"> </iframe>
|
||||
```
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
---
|
||||
title: 'Markdown Syntax'
|
||||
description: 'Text, title, and styling in standard markdown'
|
||||
icon: 'text-size'
|
||||
---
|
||||
|
||||
## Titles
|
||||
|
||||
Best used for section headers.
|
||||
|
||||
```md
|
||||
## Titles
|
||||
```
|
||||
|
||||
### Subtitles
|
||||
|
||||
Best use to subsection headers.
|
||||
|
||||
```md
|
||||
### Subtitles
|
||||
```
|
||||
|
||||
<Tip>
|
||||
|
||||
Each **title** and **subtitle** creates an anchor and also shows up on the table of contents on the right.
|
||||
|
||||
</Tip>
|
||||
|
||||
## Text Formatting
|
||||
|
||||
We support most markdown formatting. Simply add `**`, `_`, or `~` around text to format it.
|
||||
|
||||
| Style | How to write it | Result |
|
||||
| ------------- | ----------------- | --------------- |
|
||||
| Bold | `**bold**` | **bold** |
|
||||
| Italic | `_italic_` | _italic_ |
|
||||
| Strikethrough | `~strikethrough~` | ~strikethrough~ |
|
||||
|
||||
You can combine these. For example, write `**_bold and italic_**` to get **_bold and italic_** text.
|
||||
|
||||
You need to use HTML to write superscript and subscript text. That is, add `<sup>` or `<sub>` around your text.
|
||||
|
||||
| Text Size | How to write it | Result |
|
||||
| ----------- | ------------------------ | ---------------------- |
|
||||
| Superscript | `<sup>superscript</sup>` | <sup>superscript</sup> |
|
||||
| Subscript | `<sub>subscript</sub>` | <sub>subscript</sub> |
|
||||
|
||||
## Linking to Pages
|
||||
|
||||
You can add a link by wrapping text in `[]()`. You would write `[link to google](https://google.com)` to [link to google](https://google.com).
|
||||
|
||||
Links to pages in your docs need to be root-relative. Basically, you should include the entire folder path. For example, `[link to text](/writing-content/text)` links to the page "Text" in our components section.
|
||||
|
||||
Relative links like `[link to text](../text)` will open slower because we cannot optimize them as easily.
|
||||
|
||||
## Blockquotes
|
||||
|
||||
### Singleline
|
||||
|
||||
To create a blockquote, add a `>` in front of a paragraph.
|
||||
|
||||
> Dorothy followed her through many of the beautiful rooms in her castle.
|
||||
|
||||
```md
|
||||
> Dorothy followed her through many of the beautiful rooms in her castle.
|
||||
```
|
||||
|
||||
### Multiline
|
||||
|
||||
> Dorothy followed her through many of the beautiful rooms in her castle.
|
||||
>
|
||||
> The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood.
|
||||
|
||||
```md
|
||||
> Dorothy followed her through many of the beautiful rooms in her castle.
|
||||
>
|
||||
> The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood.
|
||||
```
|
||||
|
||||
### LaTeX
|
||||
|
||||
Mintlify supports [LaTeX](https://www.latex-project.org) through the Latex component.
|
||||
|
||||
<Latex>8 x (vk x H1 - H2) = (0,1)</Latex>
|
||||
|
||||
```md
|
||||
<Latex>8 x (vk x H1 - H2) = (0,1)</Latex>
|
||||
```
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
---
|
||||
title: 'Navigation'
|
||||
description: 'The navigation field in mint.json defines the pages that go in the navigation menu'
|
||||
icon: 'map'
|
||||
---
|
||||
|
||||
The navigation menu is the list of links on every website.
|
||||
|
||||
You will likely update `mint.json` every time you add a new page. Pages do not show up automatically.
|
||||
|
||||
## Navigation syntax
|
||||
|
||||
Our navigation syntax is recursive which means you can make nested navigation groups. You don't need to include `.mdx` in page names.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```json Regular Navigation
|
||||
"navigation": [
|
||||
{
|
||||
"group": "Getting Started",
|
||||
"pages": ["quickstart"]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
```json Nested Navigation
|
||||
"navigation": [
|
||||
{
|
||||
"group": "Getting Started",
|
||||
"pages": [
|
||||
"quickstart",
|
||||
{
|
||||
"group": "Nested Reference Pages",
|
||||
"pages": ["nested-reference-page"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## Folders
|
||||
|
||||
Simply put your MDX files in folders and update the paths in `mint.json`.
|
||||
|
||||
For example, to have a page at `https://yoursite.com/your-folder/your-page` you would make a folder called `your-folder` containing an MDX file called `your-page.mdx`.
|
||||
|
||||
<Warning>
|
||||
|
||||
You cannot use `api` for the name of a folder unless you nest it inside another folder. Mintlify uses Next.js which reserves the top-level `api` folder for internal server calls. A folder name such as `api-reference` would be accepted.
|
||||
|
||||
</Warning>
|
||||
|
||||
```json Navigation With Folder
|
||||
"navigation": [
|
||||
{
|
||||
"group": "Group Name",
|
||||
"pages": ["your-folder/your-page"]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Hidden Pages
|
||||
|
||||
MDX files not included in `mint.json` will not show up in the sidebar but are accessible through the search bar and by linking directly to them.
|
||||
|
|
@ -0,0 +1,318 @@
|
|||
---
|
||||
title: 'Global Settings'
|
||||
description: 'Mintlify gives you complete control over the look and feel of your documentation using the mint.json file'
|
||||
icon: 'gear'
|
||||
---
|
||||
|
||||
Every Mintlify site needs a `mint.json` file with the core configuration settings. Learn more about the [properties](#properties) below.
|
||||
|
||||
## Properties
|
||||
|
||||
<ResponseField name="name" type="string" required>
|
||||
Name of your project. Used for the global title.
|
||||
|
||||
Example: `mintlify`
|
||||
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="navigation" type="Navigation[]" required>
|
||||
An array of groups with all the pages within that group
|
||||
<Expandable title="Navigation">
|
||||
<ResponseField name="group" type="string">
|
||||
The name of the group.
|
||||
|
||||
Example: `Settings`
|
||||
|
||||
</ResponseField>
|
||||
<ResponseField name="pages" type="string[]">
|
||||
The relative paths to the markdown files that will serve as pages.
|
||||
|
||||
Example: `["customization", "page"]`
|
||||
|
||||
</ResponseField>
|
||||
|
||||
</Expandable>
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="logo" type="string or object">
|
||||
Path to logo image or object with path to "light" and "dark" mode logo images
|
||||
<Expandable title="Logo">
|
||||
<ResponseField name="light" type="string">
|
||||
Path to the logo in light mode
|
||||
</ResponseField>
|
||||
<ResponseField name="dark" type="string">
|
||||
Path to the logo in dark mode
|
||||
</ResponseField>
|
||||
<ResponseField name="href" type="string" default="/">
|
||||
Where clicking on the logo links you to
|
||||
</ResponseField>
|
||||
</Expandable>
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="favicon" type="string">
|
||||
Path to the favicon image
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="colors" type="Colors">
|
||||
Hex color codes for your global theme
|
||||
<Expandable title="Colors">
|
||||
<ResponseField name="primary" type="string" required>
|
||||
The primary color. Used for most often for highlighted content, section
|
||||
headers, accents, in light mode
|
||||
</ResponseField>
|
||||
<ResponseField name="light" type="string">
|
||||
The primary color for dark mode. Used for most often for highlighted
|
||||
content, section headers, accents, in dark mode
|
||||
</ResponseField>
|
||||
<ResponseField name="dark" type="string">
|
||||
The primary color for important buttons
|
||||
</ResponseField>
|
||||
<ResponseField name="background" type="object">
|
||||
The color of the background in both light and dark mode
|
||||
<Expandable title="Object">
|
||||
<ResponseField name="light" type="string" required>
|
||||
The hex color code of the background in light mode
|
||||
</ResponseField>
|
||||
<ResponseField name="dark" type="string" required>
|
||||
The hex color code of the background in dark mode
|
||||
</ResponseField>
|
||||
</Expandable>
|
||||
</ResponseField>
|
||||
</Expandable>
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="topbarLinks" type="TopbarLink[]">
|
||||
Array of `name`s and `url`s of links you want to include in the topbar
|
||||
<Expandable title="TopbarLink">
|
||||
<ResponseField name="name" type="string">
|
||||
The name of the button.
|
||||
|
||||
Example: `Contact us`
|
||||
</ResponseField>
|
||||
<ResponseField name="url" type="string">
|
||||
The url once you click on the button. Example: `https://mintlify.com/contact`
|
||||
</ResponseField>
|
||||
|
||||
</Expandable>
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="topbarCtaButton" type="Call to Action">
|
||||
<Expandable title="Topbar Call to Action">
|
||||
<ResponseField name="type" type={'"link" or "github"'} default="link">
|
||||
Link shows a button. GitHub shows the repo information at the url provided including the number of GitHub stars.
|
||||
</ResponseField>
|
||||
<ResponseField name="url" type="string">
|
||||
If `link`: What the button links to.
|
||||
|
||||
If `github`: Link to the repository to load GitHub information from.
|
||||
</ResponseField>
|
||||
<ResponseField name="name" type="string">
|
||||
Text inside the button. Only required if `type` is a `link`.
|
||||
</ResponseField>
|
||||
|
||||
</Expandable>
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="versions" type="string[]">
|
||||
Array of version names. Only use this if you want to show different versions
|
||||
of docs with a dropdown in the navigation bar.
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="anchors" type="Anchor[]">
|
||||
An array of the anchors, includes the `icon`, `color`, and `url`.
|
||||
<Expandable title="Anchor">
|
||||
<ResponseField name="icon" type="string">
|
||||
The [Font Awesome](https://fontawesome.com/search?s=brands%2Cduotone) icon used to feature the anchor.
|
||||
|
||||
Example: `comments`
|
||||
</ResponseField>
|
||||
<ResponseField name="name" type="string">
|
||||
The name of the anchor label.
|
||||
|
||||
Example: `Community`
|
||||
</ResponseField>
|
||||
<ResponseField name="url" type="string">
|
||||
The start of the URL that marks what pages go in the anchor. Generally, this is the name of the folder you put your pages in.
|
||||
</ResponseField>
|
||||
<ResponseField name="color" type="string">
|
||||
The hex color of the anchor icon background. Can also be a gradient if you pass an object with the properties `from` and `to` that are each a hex color.
|
||||
</ResponseField>
|
||||
<ResponseField name="version" type="string">
|
||||
Used if you want to hide an anchor until the correct docs version is selected.
|
||||
</ResponseField>
|
||||
<ResponseField name="isDefaultHidden" type="boolean" default="false">
|
||||
Pass `true` if you want to hide the anchor until you directly link someone to docs inside it.
|
||||
</ResponseField>
|
||||
<ResponseField name="iconType" default="duotone" type="string">
|
||||
One of: "brands", "duotone", "light", "sharp-solid", "solid", or "thin"
|
||||
</ResponseField>
|
||||
|
||||
</Expandable>
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="topAnchor" type="Object">
|
||||
Override the default configurations for the top-most anchor.
|
||||
<Expandable title="Object">
|
||||
<ResponseField name="name" default="Documentation" type="string">
|
||||
The name of the top-most anchor
|
||||
</ResponseField>
|
||||
<ResponseField name="icon" default="book-open" type="string">
|
||||
Font Awesome icon.
|
||||
</ResponseField>
|
||||
<ResponseField name="iconType" default="duotone" type="string">
|
||||
One of: "brands", "duotone", "light", "sharp-solid", "solid", or "thin"
|
||||
</ResponseField>
|
||||
</Expandable>
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="tabs" type="Tabs[]">
|
||||
An array of navigational tabs.
|
||||
<Expandable title="Tabs">
|
||||
<ResponseField name="name" type="string">
|
||||
The name of the tab label.
|
||||
</ResponseField>
|
||||
<ResponseField name="url" type="string">
|
||||
The start of the URL that marks what pages go in the tab. Generally, this
|
||||
is the name of the folder you put your pages in.
|
||||
</ResponseField>
|
||||
</Expandable>
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="api" type="API">
|
||||
Configuration for API settings. Learn more about API pages at [API Components](/api-playground/demo).
|
||||
<Expandable title="API">
|
||||
<ResponseField name="baseUrl" type="string">
|
||||
The base url for all API endpoints. If `baseUrl` is an array, it will enable for multiple base url
|
||||
options that the user can toggle.
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="auth" type="Auth">
|
||||
<Expandable title="Auth">
|
||||
<ResponseField name="method" type='"bearer" | "basic" | "key"'>
|
||||
The authentication strategy used for all API endpoints.
|
||||
</ResponseField>
|
||||
<ResponseField name="name" type="string">
|
||||
The name of the authentication parameter used in the API playground.
|
||||
|
||||
If method is `basic`, the format should be `[usernameName]:[passwordName]`
|
||||
</ResponseField>
|
||||
<ResponseField name="inputPrefix" type="string">
|
||||
The default value that's designed to be a prefix for the authentication input field.
|
||||
|
||||
E.g. If an `inputPrefix` of `AuthKey` would inherit the default input result of the authentication field as `AuthKey`.
|
||||
</ResponseField>
|
||||
</Expandable>
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="playground" type="Playground">
|
||||
Configurations for the API playground
|
||||
|
||||
<Expandable title="Playground">
|
||||
<ResponseField name="mode" default="show" type='"show" | "simple" | "hide"'>
|
||||
Whether the playground is showing, hidden, or only displaying the endpoint with no added user interactivity `simple`
|
||||
|
||||
Learn more at the [playground guides](/api-playground/demo)
|
||||
</ResponseField>
|
||||
</Expandable>
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="maintainOrder" type="boolean">
|
||||
Enabling this flag ensures that key ordering in OpenAPI pages matches the key ordering defined in the OpenAPI file.
|
||||
|
||||
<Warning>This behavior will soon be enabled by default, at which point this field will be deprecated.</Warning>
|
||||
</ResponseField>
|
||||
|
||||
</Expandable>
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="openapi" type="string | string[]">
|
||||
A string or an array of strings of URL(s) or relative path(s) pointing to your
|
||||
OpenAPI file.
|
||||
|
||||
Examples:
|
||||
<CodeGroup>
|
||||
```json Absolute
|
||||
"openapi": "https://example.com/openapi.json"
|
||||
```
|
||||
```json Relative
|
||||
"openapi": "/openapi.json"
|
||||
```
|
||||
```json Multiple
|
||||
"openapi": ["https://example.com/openapi1.json", "/openapi2.json", "/openapi3.json"]
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="footerSocials" type="FooterSocials">
|
||||
An object of social media accounts where the key:property pair represents the social media platform and the account url.
|
||||
|
||||
Example:
|
||||
```json
|
||||
{
|
||||
"twitter": "https://twitter.com/mintlify",
|
||||
"website": "https://mintlify.com"
|
||||
}
|
||||
```
|
||||
<Expandable title="FooterSocials">
|
||||
<ResponseField name="[key]" type="string">
|
||||
One of the following values `website`, `facebook`, `twitter`, `discord`, `slack`, `github`, `linkedin`, `instagram`, `hacker-news`
|
||||
|
||||
Example: `twitter`
|
||||
</ResponseField>
|
||||
<ResponseField name="property" type="string">
|
||||
The URL to the social platform.
|
||||
|
||||
Example: `https://twitter.com/mintlify`
|
||||
</ResponseField>
|
||||
</Expandable>
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="feedback" type="Feedback">
|
||||
Configurations to enable feedback buttons
|
||||
|
||||
<Expandable title="Feedback">
|
||||
<ResponseField name="suggestEdit" type="boolean" default="false">
|
||||
Enables a button to allow users to suggest edits via pull requests
|
||||
</ResponseField>
|
||||
<ResponseField name="raiseIssue" type="boolean" default="false">
|
||||
Enables a button to allow users to raise an issue about the documentation
|
||||
</ResponseField>
|
||||
</Expandable>
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="modeToggle" type="ModeToggle">
|
||||
Customize the dark mode toggle.
|
||||
<Expandable title="ModeToggle">
|
||||
<ResponseField name="default" type={'"light" or "dark"'}>
|
||||
Set if you always want to show light or dark mode for new users. When not
|
||||
set, we default to the same mode as the user's operating system.
|
||||
</ResponseField>
|
||||
<ResponseField name="isHidden" type="boolean" default="false">
|
||||
Set to true to hide the dark/light mode toggle. You can combine `isHidden` with `default` to force your docs to only use light or dark mode. For example:
|
||||
|
||||
<CodeGroup>
|
||||
```json Only Dark Mode
|
||||
"modeToggle": {
|
||||
"default": "dark",
|
||||
"isHidden": true
|
||||
}
|
||||
```
|
||||
|
||||
```json Only Light Mode
|
||||
"modeToggle": {
|
||||
"default": "light",
|
||||
"isHidden": true
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
</ResponseField>
|
||||
|
||||
</Expandable>
|
||||
</ResponseField>
|
||||
|
||||
<ResponseField name="backgroundImage" type="string">
|
||||
A background image to be displayed behind every page. See example with
|
||||
[Infisical](https://infisical.com/docs) and [FRPC](https://frpc.io).
|
||||
</ResponseField>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
|
|
@ -0,0 +1,68 @@
|
|||
---
|
||||
title: How it works
|
||||
description: 'Learn the architecture of the project'
|
||||
---
|
||||
|
||||
crosspublic is a tool to convert private communication into public knowledge.<br />
|
||||
The entire project is built under [NX](https://nx.dev/) to have a monorepo with multiple projects.<br /><br />
|
||||
Unlike other NX project, this project has one `.env` file that is shared between all the apps.<br />
|
||||
It makes it easier to develop and deploy the project.<br /><br />
|
||||
When deploying to websites like [Railway](https://railway.app) or [Heroku](https://heroku.com), you can use a shared environment variables for all the apps.<br /><br />
|
||||
|
||||
**At the moment it has 6 project:**
|
||||
|
||||
- **Backend** - NestJS based system
|
||||
- **Panel** - NextJS based control panel.
|
||||
- **Tenants** - NextJS based multi-tenant website.
|
||||
- **Discord** - NestJS based Discord bot.
|
||||
- **Marketing** - NextJS based marketing website.
|
||||
- **Docs** - Mintlify based documentation website.
|
||||
|
||||
<img
|
||||
src="/images/arch.png"
|
||||
alt="Architecture of crosspublic"
|
||||
/>
|
||||
|
||||
## Architecture
|
||||
### Backend
|
||||
The project has a centralized backend that both the bots and the client interact with.<br />
|
||||
The backend is built with [NestJS](https://nestjs.com/) with a basic architecture of controllers, services, repositories and dtos.<br /><br />
|
||||
It uses [Prisma](https://www.prisma.io/) as an ORM to interact with the database.<br />
|
||||
By default Prisma uses [Postgres](https://www.postgresql.org/) as a database, but it can be easily changed to any other database since there are no native queries.<br /><br />
|
||||
The project doesn't have a control panel login, it works with an SSO using the different bots.<br />
|
||||
Once somebody uses a command like `/add` or `/signin` the backend will receive the server id and the internal user id from the bot.<br /><br />
|
||||
The backend will auto-create an organization and a user if it doesn't exist.<br />
|
||||
It will return a URL with the JWT token embedded in the url to sign in into the control panel.
|
||||
|
||||
### Panel
|
||||
The panel is built with [NextJS](https://nextjs.org/) and [TailwindCSS](https://tailwindcss.com/).<br />
|
||||
The panel has 4 main pages:
|
||||
- The main control panel to create and manage the FAQ.
|
||||
- A style page to customize the FAQ.
|
||||
- A "Create an faq" page, it takes an entire conversation and converts it into an FAQ with OpenAI ChatGPT.
|
||||
- Domains page to manage the domains and subdomains that lead to the tenant website.
|
||||
- An integrations page to add bots to different platforms such as: Discord, Slack, Intercom, etc.
|
||||
|
||||
### Tenants
|
||||
The tenants is built with [NextJS](https://nextjs.org/) and [TailwindCSS](https://tailwindcss.com/).<br />
|
||||
It's the website for the end-users to see the FAQ.<br />
|
||||
It contains a simple search bar and a list of questions.<br />
|
||||
The search bar uses [Algolia](https://www.algolia.com/) to search through the questions.<br />
|
||||
It uses the style from the control panel to customize the website.<br />
|
||||
The tenants cache each pages on the `crosspublic.com/[domainName]` path, it uses a middleware to rewrite the Vercel apex domain or the custom domain to the route.<br />
|
||||
|
||||
### Discord
|
||||
The Discord bot is built with [Discord.JS](https://discord.js.org/) and [NestJS](https://nestjs.com/).<br />
|
||||
It runs in a loop and listens to every message in every server it's in.<br />
|
||||
Once somebody runs a command such as `/add` or `/signin` it will send a request to the backend with the server id and the user id.<br />
|
||||
This is a simple server and in the future there will be many other bots for different platforms.
|
||||
|
||||
### Marketing
|
||||
The marketing website is built with [NextJS](https://nextjs.org/) and [TailwindCSS](https://tailwindcss.com/).<br />
|
||||
It's a simple static websites with a few pages.
|
||||
|
||||
### Docs
|
||||
The documentation website is built with [Mintlify](https://www.mintlify.com/).<br />
|
||||
The reference in the documentation is being auto-generated by the backend.<br />
|
||||
NestJS has a built-in Swagger module that generates a JSON file with all the routes and their documentation.<br />
|
||||
It makes it very easy to track API changes and deploy them.
|
||||
|
After Width: | Height: | Size: 421 KiB |
|
After Width: | Height: | Size: 157 KiB |
|
|
@ -0,0 +1,161 @@
|
|||
<svg width="700" height="320" viewBox="0 0 700 320" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_2862_30)">
|
||||
<rect width="700" height="320" rx="16" fill="url(#paint0_linear_2862_30)"/>
|
||||
<path d="M311.889 247.3C283.097 247.215 258.226 231.466 246.292 201.629C234.357 171.793 238.02 134.523 253.414 101.112C282.206 101.197 307.077 116.945 319.011 146.782C330.946 176.619 327.283 213.888 311.889 247.3Z" fill="white"/>
|
||||
<path d="M311.889 247.3C283.097 247.215 258.226 231.466 246.292 201.629C234.357 171.793 238.02 134.523 253.414 101.112C282.206 101.197 307.077 116.945 319.011 146.782C330.946 176.619 327.283 213.888 311.889 247.3Z" fill="url(#paint1_radial_2862_30)"/>
|
||||
<path d="M311.889 247.3C283.097 247.215 258.226 231.466 246.292 201.629C234.357 171.793 238.02 134.523 253.414 101.112C282.206 101.197 307.077 116.945 319.011 146.782C330.946 176.619 327.283 213.888 311.889 247.3Z" fill="black" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M311.889 247.3C283.097 247.215 258.226 231.466 246.292 201.629C234.357 171.793 238.02 134.523 253.414 101.112C282.206 101.197 307.077 116.945 319.011 146.782C330.946 176.619 327.283 213.888 311.889 247.3Z" fill="url(#paint2_linear_2862_30)" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M311.72 247.034C283.108 246.887 258.409 231.208 246.538 201.531C234.656 171.825 238.271 134.702 253.583 101.377C282.195 101.524 306.894 117.203 318.765 146.88C330.647 176.586 327.031 213.709 311.72 247.034Z" stroke="url(#paint3_linear_2862_30)" stroke-opacity="0.05" stroke-width="0.530516"/>
|
||||
<path d="M305.839 247.174C343.92 237.419 377.154 210.619 393.585 171.64C410.017 132.661 405.98 90.1988 386.347 56.1934C348.266 65.9477 315.032 92.7486 298.601 131.728C282.169 170.706 286.206 213.168 305.839 247.174Z" fill="white"/>
|
||||
<path d="M305.839 247.174C343.92 237.419 377.154 210.619 393.585 171.64C410.017 132.661 405.98 90.1988 386.347 56.1934C348.266 65.9477 315.032 92.7486 298.601 131.728C282.169 170.706 286.206 213.168 305.839 247.174Z" fill="url(#paint4_radial_2862_30)"/>
|
||||
<path d="M393.341 171.537C376.971 210.369 343.89 237.091 305.969 246.867C286.462 212.959 282.476 170.663 298.845 131.831C315.215 92.9978 348.295 66.2765 386.217 56.5004C405.724 90.4077 409.71 132.704 393.341 171.537Z" stroke="url(#paint5_linear_2862_30)" stroke-opacity="0.05" stroke-width="0.530516"/>
|
||||
<path d="M305.686 246.995C329.749 266.114 361.965 272.832 393.67 262.129C425.376 251.426 449.499 225.691 461.03 194.556C436.967 175.437 404.751 168.719 373.045 179.422C341.34 190.125 317.217 215.86 305.686 246.995Z" fill="white"/>
|
||||
<path d="M305.686 246.995C329.749 266.114 361.965 272.832 393.67 262.129C425.376 251.426 449.499 225.691 461.03 194.556C436.967 175.437 404.751 168.719 373.045 179.422C341.34 190.125 317.217 215.86 305.686 246.995Z" fill="url(#paint6_radial_2862_30)"/>
|
||||
<path d="M305.686 246.995C329.749 266.114 361.965 272.832 393.67 262.129C425.376 251.426 449.499 225.691 461.03 194.556C436.967 175.437 404.751 168.719 373.045 179.422C341.34 190.125 317.217 215.86 305.686 246.995Z" fill="black" fill-opacity="0.2" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M305.686 246.995C329.749 266.114 361.965 272.832 393.67 262.129C425.376 251.426 449.499 225.691 461.03 194.556C436.967 175.437 404.751 168.719 373.045 179.422C341.34 190.125 317.217 215.86 305.686 246.995Z" fill="url(#paint7_linear_2862_30)" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M393.586 261.878C362.034 272.529 329.98 265.88 306.002 246.907C317.534 215.919 341.57 190.327 373.13 179.673C404.681 169.023 436.735 175.671 460.714 194.644C449.181 225.632 425.145 251.224 393.586 261.878Z" stroke="url(#paint8_linear_2862_30)" stroke-opacity="0.05" stroke-width="0.530516"/>
|
||||
<g opacity="0.8" filter="url(#filter0_f_2862_30)">
|
||||
<circle cx="660" cy="-60" r="160" fill="#18E244" fill-opacity="0.4"/>
|
||||
</g>
|
||||
<g opacity="0.8" filter="url(#filter1_f_2862_30)">
|
||||
<circle cx="20" cy="213" r="160" fill="#18CAE2" fill-opacity="0.33"/>
|
||||
</g>
|
||||
<g opacity="0.8" filter="url(#filter2_f_2862_30)">
|
||||
<circle cx="660" cy="480" r="160" fill="#18E2B2" fill-opacity="0.52"/>
|
||||
</g>
|
||||
<g opacity="0.8" filter="url(#filter3_f_2862_30)">
|
||||
<circle cx="20" cy="413" r="160" fill="#4018E2" fill-opacity="0.22"/>
|
||||
</g>
|
||||
<path opacity="0.2" d="M0 50H700" stroke="url(#paint9_radial_2862_30)" stroke-dasharray="4 4"/>
|
||||
<path opacity="0.1" d="M0 82H700" stroke="url(#paint10_radial_2862_30)" stroke-dasharray="4 4"/>
|
||||
<path opacity="0.2" d="M239 0L239 320" stroke="url(#paint11_radial_2862_30)" stroke-dasharray="4 4"/>
|
||||
<path opacity="0.1" d="M271 0L271 320" stroke="url(#paint12_radial_2862_30)" stroke-dasharray="4 4"/>
|
||||
<path opacity="0.2" d="M461 0L461 320" stroke="url(#paint13_radial_2862_30)" stroke-dasharray="4 4"/>
|
||||
<path opacity="0.1" d="M429 0L429 320" stroke="url(#paint14_radial_2862_30)" stroke-dasharray="4 4"/>
|
||||
<path opacity="0.2" d="M0 271H700" stroke="url(#paint15_radial_2862_30)" stroke-dasharray="4 4"/>
|
||||
<path opacity="0.1" d="M0 239H700" stroke="url(#paint16_radial_2862_30)" stroke-dasharray="4 4"/>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M0 160H700" stroke="url(#paint17_linear_2862_30)"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.2">
|
||||
<path d="M511 -1L189 321" stroke="url(#paint18_linear_2862_30)"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.2">
|
||||
<path d="M511 321L189 -1" stroke="url(#paint19_linear_2862_30)"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<circle cx="350" cy="160" r="111" stroke="white"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<circle cx="350" cy="160" r="79" stroke="white"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_f_2862_30" x="260" y="-460" width="800" height="800" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="120" result="effect1_foregroundBlur_2862_30"/>
|
||||
</filter>
|
||||
<filter id="filter1_f_2862_30" x="-380" y="-187" width="800" height="800" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="120" result="effect1_foregroundBlur_2862_30"/>
|
||||
</filter>
|
||||
<filter id="filter2_f_2862_30" x="260" y="80" width="800" height="800" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="120" result="effect1_foregroundBlur_2862_30"/>
|
||||
</filter>
|
||||
<filter id="filter3_f_2862_30" x="-380" y="13" width="800" height="800" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="120" result="effect1_foregroundBlur_2862_30"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_2862_30" x1="1.04308e-05" y1="320" x2="710.784" y2="26.0793" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#18E299" stop-opacity="0.09"/>
|
||||
<stop offset="0.729167" stop-color="#0D9373" stop-opacity="0.08"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint1_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(208.697 189.703) rotate(-10.029) scale(169.097 167.466)">
|
||||
<stop stop-color="#00B0BB"/>
|
||||
<stop offset="1" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint2_linear_2862_30" x1="306.587" y1="93.5598" x2="252.341" y2="224.228" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#18E299"/>
|
||||
<stop offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_2862_30" x1="311.84" y1="123.717" x2="253.579" y2="224.761" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint4_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(313.407 243.64) rotate(-75.7542) scale(203.632 223.902)">
|
||||
<stop stop-color="#00BBBB"/>
|
||||
<stop offset="0.712616" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint5_linear_2862_30" x1="308.586" y1="102.284" x2="383.487" y2="201.169" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint6_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(311.446 249.925) rotate(-20.3524) scale(174.776 163.096)">
|
||||
<stop stop-color="#00B0BB"/>
|
||||
<stop offset="1" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint7_linear_2862_30" x1="395.842" y1="169.781" x2="332.121" y2="263.82" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00B1BC"/>
|
||||
<stop offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint8_linear_2862_30" x1="395.842" y1="169.781" x2="370.99" y2="271.799" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint9_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(350 50) scale(398.125 182)">
|
||||
<stop offset="0.348958" stop-color="#84FFD3"/>
|
||||
<stop offset="0.880208" stop-color="#18E299" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint10_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(350 82) scale(398.125 182)">
|
||||
<stop offset="0.348958" stop-color="#84FFD3"/>
|
||||
<stop offset="0.880208" stop-color="#18E299" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint11_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(239 160) rotate(90) scale(182 182)">
|
||||
<stop offset="0.348958" stop-color="#84FFD3"/>
|
||||
<stop offset="0.880208" stop-color="#18E299" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint12_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(271 160) rotate(90) scale(182 182)">
|
||||
<stop offset="0.348958" stop-color="#84FFD3"/>
|
||||
<stop offset="0.880208" stop-color="#18E299" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint13_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(461 160) rotate(90) scale(182 182)">
|
||||
<stop offset="0.348958" stop-color="#84FFD3"/>
|
||||
<stop offset="0.880208" stop-color="#18E299" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint14_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(429 160) rotate(90) scale(182 182)">
|
||||
<stop offset="0.348958" stop-color="#84FFD3"/>
|
||||
<stop offset="0.880208" stop-color="#18E299" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint15_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(350 271) scale(398.125 182)">
|
||||
<stop offset="0.348958" stop-color="#84FFD3"/>
|
||||
<stop offset="0.880208" stop-color="#18E299" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint16_radial_2862_30" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(350 239) scale(398.125 182)">
|
||||
<stop offset="0.348958" stop-color="#84FFD3"/>
|
||||
<stop offset="0.880208" stop-color="#18E299" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint17_linear_2862_30" x1="0" y1="160" x2="700" y2="160" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0.1"/>
|
||||
<stop offset="0.5" stop-color="white"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0.1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint18_linear_2862_30" x1="511" y1="-1" x2="189" y2="321" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0.1"/>
|
||||
<stop offset="0.5" stop-color="white"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0.1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint19_linear_2862_30" x1="511" y1="321" x2="189" y2="-0.999997" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white" stop-opacity="0.1"/>
|
||||
<stop offset="0.5" stop-color="white"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0.1"/>
|
||||
</linearGradient>
|
||||
<clipPath id="clip0_2862_30">
|
||||
<rect width="700" height="320" rx="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
|
|
@ -0,0 +1,155 @@
|
|||
<svg width="700" height="320" viewBox="0 0 700 320" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_2862_278)">
|
||||
<rect width="700" height="320" rx="16" fill="url(#paint0_linear_2862_278)"/>
|
||||
<path d="M311.889 247.3C283.097 247.215 258.226 231.466 246.292 201.629C234.357 171.793 238.02 134.523 253.414 101.112C282.206 101.197 307.077 116.945 319.011 146.782C330.946 176.619 327.283 213.888 311.889 247.3Z" fill="white"/>
|
||||
<path d="M311.889 247.3C283.097 247.215 258.226 231.466 246.292 201.629C234.357 171.793 238.02 134.523 253.414 101.112C282.206 101.197 307.077 116.945 319.011 146.782C330.946 176.619 327.283 213.888 311.889 247.3Z" fill="url(#paint1_radial_2862_278)"/>
|
||||
<path d="M311.889 247.3C283.097 247.215 258.226 231.466 246.292 201.629C234.357 171.793 238.02 134.523 253.414 101.112C282.206 101.197 307.077 116.945 319.011 146.782C330.946 176.619 327.283 213.888 311.889 247.3Z" fill="black" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M311.889 247.3C283.097 247.215 258.226 231.466 246.292 201.629C234.357 171.793 238.02 134.523 253.414 101.112C282.206 101.197 307.077 116.945 319.011 146.782C330.946 176.619 327.283 213.888 311.889 247.3Z" fill="url(#paint2_linear_2862_278)" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M311.72 247.034C283.108 246.887 258.409 231.208 246.538 201.531C234.656 171.825 238.271 134.702 253.583 101.377C282.195 101.524 306.894 117.203 318.765 146.88C330.647 176.586 327.031 213.709 311.72 247.034Z" stroke="url(#paint3_linear_2862_278)" stroke-opacity="0.05" stroke-width="0.530516"/>
|
||||
<path d="M305.839 247.174C343.92 237.419 377.154 210.619 393.585 171.64C410.017 132.661 405.98 90.1988 386.347 56.1934C348.266 65.9477 315.032 92.7486 298.601 131.728C282.169 170.706 286.206 213.168 305.839 247.174Z" fill="white"/>
|
||||
<path d="M305.839 247.174C343.92 237.419 377.154 210.619 393.585 171.64C410.017 132.661 405.98 90.1988 386.347 56.1934C348.266 65.9477 315.032 92.7486 298.601 131.728C282.169 170.706 286.206 213.168 305.839 247.174Z" fill="url(#paint4_radial_2862_278)"/>
|
||||
<path d="M393.341 171.537C376.971 210.369 343.89 237.091 305.969 246.867C286.462 212.959 282.476 170.663 298.845 131.831C315.215 92.9978 348.295 66.2765 386.217 56.5004C405.724 90.4077 409.71 132.704 393.341 171.537Z" stroke="url(#paint5_linear_2862_278)" stroke-opacity="0.05" stroke-width="0.530516"/>
|
||||
<path d="M305.686 246.995C329.75 266.114 361.965 272.832 393.671 262.129C425.376 251.426 449.499 225.691 461.03 194.556C436.967 175.437 404.751 168.719 373.046 179.422C341.34 190.125 317.217 215.86 305.686 246.995Z" fill="white"/>
|
||||
<path d="M305.686 246.995C329.75 266.114 361.965 272.832 393.671 262.129C425.376 251.426 449.499 225.691 461.03 194.556C436.967 175.437 404.751 168.719 373.046 179.422C341.34 190.125 317.217 215.86 305.686 246.995Z" fill="url(#paint6_radial_2862_278)"/>
|
||||
<path d="M305.686 246.995C329.75 266.114 361.965 272.832 393.671 262.129C425.376 251.426 449.499 225.691 461.03 194.556C436.967 175.437 404.751 168.719 373.046 179.422C341.34 190.125 317.217 215.86 305.686 246.995Z" fill="black" fill-opacity="0.2" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M305.686 246.995C329.75 266.114 361.965 272.832 393.671 262.129C425.376 251.426 449.499 225.691 461.03 194.556C436.967 175.437 404.751 168.719 373.046 179.422C341.34 190.125 317.217 215.86 305.686 246.995Z" fill="url(#paint7_linear_2862_278)" fill-opacity="0.5" style="mix-blend-mode:hard-light"/>
|
||||
<path d="M393.586 261.878C362.035 272.529 329.981 265.88 306.002 246.907C317.535 215.919 341.571 190.327 373.13 179.673C404.682 169.023 436.736 175.671 460.715 194.644C449.182 225.632 425.146 251.224 393.586 261.878Z" stroke="url(#paint8_linear_2862_278)" stroke-opacity="0.05" stroke-width="0.530516"/>
|
||||
<g opacity="0.8" filter="url(#filter0_f_2862_278)">
|
||||
<circle cx="660" cy="-60" r="160" fill="#18E299" fill-opacity="0.4"/>
|
||||
</g>
|
||||
<g opacity="0.8" filter="url(#filter1_f_2862_278)">
|
||||
<circle cx="20" cy="213" r="160" fill="#18E299" fill-opacity="0.33"/>
|
||||
</g>
|
||||
<g opacity="0.8" filter="url(#filter2_f_2862_278)">
|
||||
<circle cx="660" cy="480" r="160" fill="#18E299" fill-opacity="0.52"/>
|
||||
</g>
|
||||
<g opacity="0.8" filter="url(#filter3_f_2862_278)">
|
||||
<circle cx="20" cy="413" r="160" fill="#18E299" fill-opacity="0.22"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M0 50H700" stroke="black" stroke-dasharray="4 4"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M0 82H700" stroke="black" stroke-dasharray="4 4"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M239 0L239 320" stroke="black" stroke-dasharray="4 4"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M271 0L271 320" stroke="black" stroke-dasharray="4 4"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M461 0L461 320" stroke="black" stroke-dasharray="4 4"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M350 0L350 320" stroke="url(#paint9_linear_2862_278)"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M429 0L429 320" stroke="black" stroke-dasharray="4 4"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M0 271H700" stroke="black" stroke-dasharray="4 4"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M0 239H700" stroke="black" stroke-dasharray="4 4"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M0 160H700" stroke="url(#paint10_linear_2862_278)"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M511 -1L189 321" stroke="url(#paint11_linear_2862_278)"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.1">
|
||||
<path d="M511 321L189 -1" stroke="url(#paint12_linear_2862_278)"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.05">
|
||||
<circle cx="350" cy="160" r="111" stroke="black"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.05">
|
||||
<circle cx="350" cy="160" r="79" stroke="black"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_f_2862_278" x="260" y="-460" width="800" height="800" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="120" result="effect1_foregroundBlur_2862_278"/>
|
||||
</filter>
|
||||
<filter id="filter1_f_2862_278" x="-380" y="-187" width="800" height="800" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="120" result="effect1_foregroundBlur_2862_278"/>
|
||||
</filter>
|
||||
<filter id="filter2_f_2862_278" x="260" y="80" width="800" height="800" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="120" result="effect1_foregroundBlur_2862_278"/>
|
||||
</filter>
|
||||
<filter id="filter3_f_2862_278" x="-380" y="13" width="800" height="800" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="120" result="effect1_foregroundBlur_2862_278"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_2862_278" x1="1.04308e-05" y1="320" x2="710.784" y2="26.0793" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#18E299" stop-opacity="0.09"/>
|
||||
<stop offset="0.729167" stop-color="#0D9373" stop-opacity="0.08"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint1_radial_2862_278" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(208.697 189.703) rotate(-10.029) scale(169.097 167.466)">
|
||||
<stop stop-color="#00B0BB"/>
|
||||
<stop offset="1" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint2_linear_2862_278" x1="306.587" y1="93.5598" x2="252.341" y2="224.228" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#18E299"/>
|
||||
<stop offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_2862_278" x1="311.84" y1="123.717" x2="253.579" y2="224.761" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint4_radial_2862_278" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(313.407 243.64) rotate(-75.7542) scale(203.632 223.902)">
|
||||
<stop stop-color="#00BBBB"/>
|
||||
<stop offset="0.712616" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint5_linear_2862_278" x1="308.586" y1="102.284" x2="383.487" y2="201.169" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="paint6_radial_2862_278" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(311.447 249.925) rotate(-20.3524) scale(174.776 163.096)">
|
||||
<stop stop-color="#00B0BB"/>
|
||||
<stop offset="1" stop-color="#00DB65"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="paint7_linear_2862_278" x1="395.843" y1="169.781" x2="332.121" y2="263.82" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00B1BC"/>
|
||||
<stop offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint8_linear_2862_278" x1="395.843" y1="169.781" x2="370.991" y2="271.799" gradientUnits="userSpaceOnUse">
|
||||
<stop/>
|
||||
<stop offset="1" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint9_linear_2862_278" x1="350" y1="0" x2="350" y2="320" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-opacity="0"/>
|
||||
<stop offset="0.0001" stop-opacity="0.3"/>
|
||||
<stop offset="0.333333"/>
|
||||
<stop offset="0.666667"/>
|
||||
<stop offset="1" stop-opacity="0.3"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint10_linear_2862_278" x1="0" y1="160" x2="700" y2="160" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-opacity="0.1"/>
|
||||
<stop offset="0.5"/>
|
||||
<stop offset="1" stop-opacity="0.1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint11_linear_2862_278" x1="511" y1="-1" x2="189" y2="321" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-opacity="0.1"/>
|
||||
<stop offset="0.5"/>
|
||||
<stop offset="1" stop-opacity="0.1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint12_linear_2862_278" x1="511" y1="321" x2="189" y2="-0.999997" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-opacity="0.1"/>
|
||||
<stop offset="0.5"/>
|
||||
<stop offset="1" stop-opacity="0.1"/>
|
||||
</linearGradient>
|
||||
<clipPath id="clip0_2862_278">
|
||||
<rect width="700" height="320" rx="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 10 KiB |
|
|
@ -0,0 +1,53 @@
|
|||
---
|
||||
title: Introduction
|
||||
description: 'Welcome to crosspublic documentation'
|
||||
---
|
||||
|
||||
<div className="w-full flex justify-center rounded-full">
|
||||
<img
|
||||
className="block dark:hidden"
|
||||
src="/logo/light.png"
|
||||
alt="Hero Light"
|
||||
/>
|
||||
<img
|
||||
className="hidden dark:block"
|
||||
src="/logo/dark.png"
|
||||
alt="Hero Dark"
|
||||
/>
|
||||
</div>
|
||||
|
||||
## What is crosspublic?
|
||||
|
||||
crosspublic is a tool to convert private communication into public knowledge.<br />
|
||||
Most of your users are not on your communication channels, and they are not aware of the questions that have already been asked and answered.<br />
|
||||
|
||||
## Architecture
|
||||
crosspublic is an [NX monorepo](https://nx.dev) that contains the backend, control panel, discord bot, marketing website and the docs.<br /><br />
|
||||
Unlike other NX project, this project has one `.env` file that is shared between all the apps.<br />
|
||||
It makes it easier to develop and deploy the project.<br /><br />
|
||||
When deploying to websites like [Railway](https://railway.app) or [Heroku](https://heroku.com), you can use a shared environment variables for all the apps.<br />
|
||||
|
||||
**It has four main components:**
|
||||
- `Panel` - NextJS control panel to manage your FAQ, it also contains the public website of every user FAQ page.
|
||||
- `Tenants` - NextJS website that contains the FAQ of every end-user.
|
||||
- `Backend` - NestJS that operate as the server for both the bots and the website.
|
||||
- `Discord` - Discord bot that listen to messages, and send them to the backend.
|
||||
|
||||
In the future there will also be a bot of Slack, Intercom, Telegram, and more.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card
|
||||
title="Quick start"
|
||||
icon="pen-to-square"
|
||||
href="/quickstart"
|
||||
>
|
||||
Learn how to install the project and start using it
|
||||
</Card>
|
||||
<Card
|
||||
title="How it works"
|
||||
icon="screwdriver-wrench"
|
||||
href="/howitworks"
|
||||
>
|
||||
Learn the architecture of the project
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
|
@ -0,0 +1,85 @@
|
|||
exports.default = {
|
||||
"$schema": "https://mintlify.com/schema.json",
|
||||
"name": "Starter Kit",
|
||||
"logo": {
|
||||
"dark": "/logo/dark.png",
|
||||
"light": "/logo/light.png"
|
||||
},
|
||||
"favicon": "/favicon.png",
|
||||
"colors": {
|
||||
"primary": "#9333EA",
|
||||
"light": "#9333EA",
|
||||
"dark": "#9333EA",
|
||||
"anchors": {
|
||||
"from": "#9333EA",
|
||||
"to": "#9333EA"
|
||||
}
|
||||
},
|
||||
"openapi": "https://api.crosspublic.com/docs-json",
|
||||
"api": {
|
||||
"baseUrl": "https://api.crosspublic.com",
|
||||
},
|
||||
"topbarLinks": [
|
||||
{
|
||||
"name": "Support",
|
||||
"url": "mailto:nevo@crosspublic.com"
|
||||
},
|
||||
{
|
||||
"name": "Cloud",
|
||||
"url": "https://panel.crosspublic.com"
|
||||
}
|
||||
],
|
||||
"modeToggle": {
|
||||
"default": "light"
|
||||
},
|
||||
"topbarCtaButton": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/github-20k/crosspublic"
|
||||
},
|
||||
"tabs": [
|
||||
{
|
||||
"name": "Public API Reference",
|
||||
"url": "public-api-reference"
|
||||
},
|
||||
{
|
||||
"name": "Internal API Reference (Self-Hosted)",
|
||||
"url": "api-reference"
|
||||
}
|
||||
],
|
||||
"anchors": [
|
||||
{
|
||||
"name": "Documentation",
|
||||
"icon": "book-open-cover",
|
||||
"url": "https://docs.crosspublic.com"
|
||||
},
|
||||
{
|
||||
"name": "Community",
|
||||
"icon": "discord",
|
||||
"url": "https://discord.gitroom.com"
|
||||
},
|
||||
{
|
||||
"name": "Blog",
|
||||
"icon": "newspaper",
|
||||
"url": "https://gitroom.com/blog"
|
||||
}
|
||||
],
|
||||
"navigation": [
|
||||
{
|
||||
"group": "Get Started",
|
||||
"pages": ["introduction", "quickstart", "howitworks"]
|
||||
},
|
||||
{
|
||||
"group": "API Documentation",
|
||||
"pages": ["api-reference/introduction"]
|
||||
},
|
||||
{
|
||||
"group": "Public api Documentation",
|
||||
"pages": ["public-api-reference/introduction"]
|
||||
}
|
||||
],
|
||||
"footerSocials": {
|
||||
"twitter": "https://twitter.com/nevodavid",
|
||||
"github": "https://github.com/github-20k/crosspublic",
|
||||
"linkedin": "https://www.linkedin.com/nevodavid"
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
{
|
||||
"$schema": "https://mintlify.com/schema.json",
|
||||
"name": "Starter Kit",
|
||||
"logo": {
|
||||
"dark": "/logo/dark.png",
|
||||
"light": "/logo/light.png"
|
||||
},
|
||||
"favicon": "/favicon.png",
|
||||
"colors": {
|
||||
"primary": "#9333EA",
|
||||
"light": "#9333EA",
|
||||
"dark": "#9333EA",
|
||||
"anchors": {
|
||||
"from": "#9333EA",
|
||||
"to": "#9333EA"
|
||||
}
|
||||
},
|
||||
"openapi": "https://api.crosspublic.com/docs-json",
|
||||
"api": {
|
||||
"baseUrl": "https://api.crosspublic.com"
|
||||
},
|
||||
"topbarLinks": [
|
||||
{
|
||||
"name": "Support",
|
||||
"url": "mailto:nevo@crosspublic.com"
|
||||
}
|
||||
],
|
||||
"modeToggle": {
|
||||
"default": "light"
|
||||
},
|
||||
"topbarCtaButton": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/github-20k/crosspublic"
|
||||
},
|
||||
"tabs": [
|
||||
{
|
||||
"name": "Public API Reference",
|
||||
"url": "public-api-reference"
|
||||
},
|
||||
{
|
||||
"name": "Internal API Reference (Self-Hosted)",
|
||||
"url": "api-reference"
|
||||
}
|
||||
],
|
||||
"anchors": [
|
||||
{
|
||||
"name": "Documentation",
|
||||
"icon": "book-open-cover",
|
||||
"url": "https://docs.crosspublic.com"
|
||||
},
|
||||
{
|
||||
"name": "Community",
|
||||
"icon": "discord",
|
||||
"url": "https://discord.gitroom.com"
|
||||
},
|
||||
{
|
||||
"name": "Blog",
|
||||
"icon": "newspaper",
|
||||
"url": "https://gitroom.com/blog"
|
||||
}
|
||||
],
|
||||
"navigation": [
|
||||
{
|
||||
"group": "Get Started",
|
||||
"pages": [
|
||||
"introduction",
|
||||
"quickstart",
|
||||
"howitworks"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "API Documentation",
|
||||
"pages": [
|
||||
"api-reference/introduction"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Public api Documentation",
|
||||
"pages": [
|
||||
"public-api-reference/introduction"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Authentications",
|
||||
"pages": [
|
||||
"api-reference/custom/authentications/check-org-and-user",
|
||||
"api-reference/custom/authentications/register-to-crosspublic",
|
||||
"api-reference/custom/authentications/login-to-crosspublic"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Stripe",
|
||||
"pages": [
|
||||
"api-reference/custom/stripe/post-stripe"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Public",
|
||||
"pages": [
|
||||
"public-api-reference/custom/public/categories-list",
|
||||
"public-api-reference/custom/public/faq-list",
|
||||
"public-api-reference/custom/public/retrieve-faq",
|
||||
"public-api-reference/custom/public/get-organization-style"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Users",
|
||||
"pages": [
|
||||
"api-reference/custom/users/get-userssign-in",
|
||||
"api-reference/custom/users/get-usersself",
|
||||
"api-reference/custom/users/post-usersrevalidate"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Faq",
|
||||
"pages": [
|
||||
"api-reference/custom/faq/get-faq",
|
||||
"api-reference/custom/faq/put-faq",
|
||||
"api-reference/custom/faq/delete-faq",
|
||||
"api-reference/custom/faq/post-faqorder",
|
||||
"api-reference/custom/faq/put-faq-category",
|
||||
"api-reference/custom/faq/post-faq",
|
||||
"api-reference/custom/faq/post-faqjob",
|
||||
"api-reference/custom/faq/post-faqjobsquestions",
|
||||
"api-reference/custom/faq/post-faqanswers",
|
||||
"api-reference/custom/faq/get-faqjobs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Categories",
|
||||
"pages": [
|
||||
"api-reference/custom/categories/post-categoriesorder",
|
||||
"api-reference/custom/categories/get-categories",
|
||||
"api-reference/custom/categories/post-categories",
|
||||
"api-reference/custom/categories/get-categoriesfaq",
|
||||
"api-reference/custom/categories/get-categories-1",
|
||||
"api-reference/custom/categories/put-categories",
|
||||
"api-reference/custom/categories/delete-categories"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Settings",
|
||||
"pages": [
|
||||
"api-reference/custom/settings/get-settings",
|
||||
"api-reference/custom/settings/post-settingscheck-subdomain",
|
||||
"api-reference/custom/settings/get-settingscheck-domain",
|
||||
"api-reference/custom/settings/delete-settingsdelete-domain",
|
||||
"api-reference/custom/settings/post-settingsdomain",
|
||||
"api-reference/custom/settings/post-settingssubdomain"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Billings",
|
||||
"pages": [
|
||||
"api-reference/custom/billings/get-billingcheck",
|
||||
"api-reference/custom/billings/subscribe-to-a-plan",
|
||||
"api-reference/custom/billings/post-billingmodify",
|
||||
"api-reference/custom/billings/get-billing",
|
||||
"api-reference/custom/billings/post-billingcancel"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Styles",
|
||||
"pages": [
|
||||
"api-reference/custom/styles/get-styles",
|
||||
"api-reference/custom/styles/put-styles"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Integrations",
|
||||
"pages": [
|
||||
"api-reference/custom/integrations/get-integrations",
|
||||
"api-reference/custom/integrations/post-integrations",
|
||||
"api-reference/custom/integrations/get-integrations-add",
|
||||
"api-reference/custom/integrations/delete-integrations"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Invitations",
|
||||
"pages": [
|
||||
"api-reference/custom/invitations/post-invite",
|
||||
"api-reference/custom/invitations/post-inviteadd"
|
||||
]
|
||||
}
|
||||
],
|
||||
"footerSocials": {
|
||||
"twitter": "https://twitter.com/nevodavid",
|
||||
"github": "https://github.com/github-20k/crosspublic",
|
||||
"linkedin": "https://www.linkedin.com/nevodavid"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "docs",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "apps/docs",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
"build": {
|
||||
"command": "node apps/docs/test.js",
|
||||
"options": {
|
||||
"type": "module"
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"command": "cd apps/docs && npx mintlify dev",
|
||||
"options": {
|
||||
"type": "module"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /public/categories
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /public/categories/{slug}/faqs
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /public/styles
|
||||
---
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
openapi: get /public/faq/{slug}
|
||||
---
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
title: 'Introduction'
|
||||
description: 'How to use the public API'
|
||||
---
|
||||
|
||||
<Note>
|
||||
The Public API is only available for the PRO plan and the self-hosted plan.
|
||||
</Note>
|
||||
|
||||
## Why public API
|
||||
if you want to build a custom implementation of the FAQ page, or you want to use it in different service, you can use the public API to get the data.
|
||||
|
||||
## How to use the public API
|
||||
There are two main options to use the Public API:
|
||||
1. For the **PRO plan**, go to [Settings](https://app.crosspublic.com/dashboard/settings) and copy the API key.<br />
|
||||
For every request to the `/public` API URL send a header called `apikey` with the value of the API key.
|
||||
|
||||
2. For the **self-hosted plan**, you can also pass `serverkey` to bypass package check.<br />
|
||||
The `serverkey` is the value of `BACKEND_TOKEN_PROTECTOR` in the `.env` file.
|
||||
|
||||
Check the endpoints on the left for API reference.
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
---
|
||||
title: 'Quickstart'
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
To run the project you need to have multiple things:
|
||||
- Node.js
|
||||
- PostgresSQL
|
||||
- Discord client id and token
|
||||
- Vercel Blob Store (optional)
|
||||
- Vercel Project ID, Team ID and Token (if you want to have multi-tenancy)
|
||||
- Stripe account (optional)
|
||||
- OpenAI API key (optional)
|
||||
- Algolia account (optional)
|
||||
|
||||
### NodeJS
|
||||
A complete guide of how to install NodeJS can be found [here](https://nodejs.org/en/download/).
|
||||
|
||||
### PostgresSQL
|
||||
Make sure you have PostgreSQL installed on your machine.<br />
|
||||
If you don't, you can install [Docker](https://www.docker.com/products/docker-desktop) and run:
|
||||
|
||||
```bash
|
||||
docker run -e POSTGRES_USER=root -e POSTGRES_PASSWORD=your_password --name postgres -p 5432:5432 -d postgres
|
||||
```
|
||||
|
||||
### Discord client id and token
|
||||
Head over to the [Discord Developer Portal](https://discord.com/developers/applications) and create a new application.<br />
|
||||
After that, go to the bot tab and create a new bot.<br />
|
||||
Save the token and client id for later.
|
||||
|
||||
### Vercel Blob Store
|
||||
Head over to the [Vercel Blob Store](https://vercel.com/dashboard/stores) and create a new database.<br />
|
||||
Choose Blob (currently in beta) and save the token for later.
|
||||
|
||||
### Vercel Project ID, Team ID and Token
|
||||
|
||||
1. Create a new Vercel empty project.
|
||||
2. Head over to Vercel teams settings, scroll down to "Team ID" copy the id and save it for later.
|
||||
3. Head over to Vercel project settings, scroll down to "Project ID" copy the id and save it for later.
|
||||
4. Head over to Vercel account settings, scroll down to "Tokens" and create a new token, copy the token and save it for later.
|
||||
|
||||
### Stripe account
|
||||
|
||||
If you don't provide the Stripe `PAYMENT_PUBLIC_KEY`, you will be automatically granted all the features without limitations.
|
||||
|
||||
1. Register a new account on [Stripe](https://stripe.com/).<br />
|
||||
2. Head over to the [Stripe API keys](https://dashboard.stripe.com/test/apikeys) and copy the Publishable and Secret key, save it for later.
|
||||
3. Head over to the [Stripe Webhooks](https://dashboard.stripe.com/test/webhooks) and create a new local webhook.<br />
|
||||
Copy the token and save it for later.
|
||||
|
||||
### OpenAI API key
|
||||
Create a new [OpenAI](https://platform.openai.com) account, head over to the [API keys](https://platform.openai.com/api-keys), copy the key, and save it for later.
|
||||
|
||||
### Algolia account
|
||||
Create a new [Algolia](https://www.algolia.com/) account, head over to the [API keys](https://www.algolia.com/api-keys), copy the APP ID, Search Key, and Admin API Key, and save it for later.
|
||||
|
||||
## Installation
|
||||
|
||||
### Clone the repository
|
||||
|
||||
```bash
|
||||
git clone https://github.com/github-20k/crosspublic
|
||||
```
|
||||
|
||||
### Copy environment variables
|
||||
Copy the `.env.example` file to `.env` and fill in the values
|
||||
|
||||
```bash
|
||||
DISCORD_CLIENT=<copied discord client key>
|
||||
DISCORD_TOKEN=<copied discord token key>
|
||||
DATABASE_URL=postgres://root:your_password@localhost:5432/crosspublic
|
||||
BACKEND_URL=http://localhost:3000
|
||||
NEXT_PUBLIC_BACKEND_URL=http://localhost:3000
|
||||
BACKEND_TOKEN_PROTECTOR=<anything you want, better be long>
|
||||
OPENAI_API_KEY=<open_ai key>
|
||||
JWT_SECRET=<anything you want, better be long>
|
||||
FRONTEND_URL=http://localhost:4200
|
||||
BLOB_READ_WRITE_TOKEN=<copied blob store key>
|
||||
PROJECT_ID_VERCEL=<copied vercel project id>
|
||||
TEAM_ID_VERCEL=<copied vercel team id>
|
||||
PAYMENT_PUBLIC_KEY=<copied stripe publishable key>
|
||||
PAYMENT_SECRET_KEY=<copied stripe secret key>
|
||||
PAYMENT_SIGNING_SECRET=<copied stripe webhook token>
|
||||
MARKETING_WEBSITE_URL=http://localhost:4201
|
||||
DOCS_URL=https://localhost:3000
|
||||
NEXT_PUBLIC_ALGOLIA_APP_ID=<algolia id>
|
||||
NEXT_PUBLIC_ALGOLIA_SEARCH_KEY=<algolia search key>
|
||||
ALGOLIA_ADMIN_API_KEY=<algolia admin api>
|
||||
```
|
||||
|
||||
### Install the dependencies
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
### Generate the prisma client and run the migrations
|
||||
|
||||
```bash
|
||||
npm run update-prisma
|
||||
```
|
||||
|
||||
### Run the project
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
const process = require('process')
|
||||
process.chdir(__dirname);
|
||||
const {writeFileSync, renameSync, rmdirSync, mkdirSync} = require("fs");
|
||||
const { config } = require('dotenv');
|
||||
const prod = require('./mint.js').default;
|
||||
config();
|
||||
(async () => {
|
||||
const {generateOpenApiPages} = await import("@mintlify/scraping");
|
||||
|
||||
try {
|
||||
rmdirSync('./api-reference/custom', { recursive: true });
|
||||
rmdirSync('./public-api-reference/custom', { recursive: true });
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000));
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
await generateOpenApiPages(process.env.BACKEND_URL + '/docs-json', true, 'api-reference/custom');
|
||||
const generate = await generateOpenApiPages(process.env.BACKEND_URL + '/docs-json');
|
||||
await new Promise((resolve) => setTimeout(resolve, 3000));
|
||||
|
||||
mkdirSync('./public-api-reference/custom', { recursive: true });
|
||||
renameSync('./api-reference/custom/public', './public-api-reference/custom/public/');
|
||||
|
||||
prod.navigation.push(...generate.nav.map((item) => ({
|
||||
...item,
|
||||
pages: item.pages.map((page) => (page.indexOf('public') > -1 ? 'public-api-reference/custom/' : 'api-reference/custom/') + page)
|
||||
})));
|
||||
|
||||
writeFileSync('./mint.json', JSON.stringify(prod, null, 2));
|
||||
const text = await (await fetch(process.env.BACKEND_URL + '/docs-json')).text();
|
||||
writeFileSync('./openapi.json', text);
|
||||
})();
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import {DocumentBuilder, SwaggerModule} from "@nestjs/swagger";
|
||||
import {INestApplication} from "@nestjs/common";
|
||||
|
||||
export const loadSwagger = (app: INestApplication) => {
|
||||
const config = new DocumentBuilder()
|
||||
.setTitle('crosspublic Swagger file')
|
||||
.setDescription('API description')
|
||||
.setVersion('1.0')
|
||||
.build();
|
||||
|
||||
const document = SwaggerModule.createDocument(app, config);
|
||||
SwaggerModule.setup('docs', app, document);
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import { Global, Module } from '@nestjs/common';
|
||||
import {MulterModule} from "@nestjs/platform-express";
|
||||
// @ts-ignore
|
||||
import {diskStorage} from "multer";
|
||||
import {mkdirSync} from 'fs';
|
||||
import {extname} from 'path';
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
"@nestjs/platform-express": "^10.0.2",
|
||||
"@nestjs/schedule": "^4.0.0",
|
||||
"@nestjs/serve-static": "^4.0.1",
|
||||
"@nestjs/swagger": "^7.3.0",
|
||||
"@prisma/client": "^5.8.1",
|
||||
"@swc/helpers": "~0.5.2",
|
||||
"@sweetalert2/theme-dark": "^5.0.16",
|
||||
|
|
@ -33,6 +34,7 @@
|
|||
"@types/lodash": "^4.14.202",
|
||||
"@types/md5": "^2.3.5",
|
||||
"@types/mime-types": "^2.1.4",
|
||||
"@types/multer": "^1.4.11",
|
||||
"@types/remove-markdown": "^0.3.4",
|
||||
"@types/stripe": "^8.0.417",
|
||||
"@uidotdev/usehooks": "^2.4.1",
|
||||
|
|
@ -108,7 +110,6 @@
|
|||
"@testing-library/react": "14.0.0",
|
||||
"@types/cookie-parser": "^1.4.6",
|
||||
"@types/jest": "^29.4.0",
|
||||
"@types/multer": "^1.4.11",
|
||||
"@types/node": "18.16.9",
|
||||
"@types/react": "18.2.33",
|
||||
"@types/react-dom": "18.2.14",
|
||||
|
|
@ -4429,6 +4430,11 @@
|
|||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"node_modules/@microsoft/tsdoc": {
|
||||
"version": "0.14.2",
|
||||
"resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz",
|
||||
"integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug=="
|
||||
},
|
||||
"node_modules/@mole-inc/bin-wrapper": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@mole-inc/bin-wrapper/-/bin-wrapper-8.0.1.tgz",
|
||||
|
|
@ -4596,6 +4602,25 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@nestjs/mapped-types": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.0.5.tgz",
|
||||
"integrity": "sha512-bSJv4pd6EY99NX9CjBIyn4TVDoSit82DUZlL4I3bqNfy5Gt+gXTa86i3I/i0iIV9P4hntcGM5GyO+FhZAhxtyg==",
|
||||
"peerDependencies": {
|
||||
"@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0",
|
||||
"class-transformer": "^0.4.0 || ^0.5.0",
|
||||
"class-validator": "^0.13.0 || ^0.14.0",
|
||||
"reflect-metadata": "^0.1.12 || ^0.2.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"class-transformer": {
|
||||
"optional": true
|
||||
},
|
||||
"class-validator": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@nestjs/microservices": {
|
||||
"version": "10.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/microservices/-/microservices-10.3.3.tgz",
|
||||
|
|
@ -4750,6 +4775,38 @@
|
|||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.2.5.tgz",
|
||||
"integrity": "sha512-l6qtdDPIkmAmzEO6egquYDfqQGPMRNGjYtrU13HAXb3YSRrt7HSb1sJY0pKp6o2bAa86tSB6iwaW2JbthPKr7Q=="
|
||||
},
|
||||
"node_modules/@nestjs/swagger": {
|
||||
"version": "7.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.3.0.tgz",
|
||||
"integrity": "sha512-zLkfKZ+ioYsIZ3dfv7Bj8YHnZMNAGWFUmx2ZDuLp/fBE4P8BSjB7hldzDueFXsmwaPL90v7lgyd82P+s7KME1Q==",
|
||||
"dependencies": {
|
||||
"@microsoft/tsdoc": "^0.14.2",
|
||||
"@nestjs/mapped-types": "2.0.5",
|
||||
"js-yaml": "4.1.0",
|
||||
"lodash": "4.17.21",
|
||||
"path-to-regexp": "3.2.0",
|
||||
"swagger-ui-dist": "5.11.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fastify/static": "^6.0.0 || ^7.0.0",
|
||||
"@nestjs/common": "^9.0.0 || ^10.0.0",
|
||||
"@nestjs/core": "^9.0.0 || ^10.0.0",
|
||||
"class-transformer": "*",
|
||||
"class-validator": "*",
|
||||
"reflect-metadata": "^0.1.12 || ^0.2.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@fastify/static": {
|
||||
"optional": true
|
||||
},
|
||||
"class-transformer": {
|
||||
"optional": true
|
||||
},
|
||||
"class-validator": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@nestjs/testing": {
|
||||
"version": "10.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.3.3.tgz",
|
||||
|
|
@ -7987,7 +8044,6 @@
|
|||
"version": "1.19.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
|
||||
"integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/connect": "*",
|
||||
"@types/node": "*"
|
||||
|
|
@ -8018,7 +8074,6 @@
|
|||
"version": "3.4.38",
|
||||
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
|
||||
"integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
|
|
@ -8087,7 +8142,6 @@
|
|||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
|
||||
"integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/body-parser": "*",
|
||||
"@types/express-serve-static-core": "^4.17.33",
|
||||
|
|
@ -8099,7 +8153,6 @@
|
|||
"version": "4.17.43",
|
||||
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz",
|
||||
"integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"@types/qs": "*",
|
||||
|
|
@ -8133,8 +8186,7 @@
|
|||
"node_modules/@types/http-errors": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
|
||||
"integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA=="
|
||||
},
|
||||
"node_modules/@types/http-proxy": {
|
||||
"version": "1.17.14",
|
||||
|
|
@ -8289,8 +8341,7 @@
|
|||
"node_modules/@types/mime": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
|
||||
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="
|
||||
},
|
||||
"node_modules/@types/mime-types": {
|
||||
"version": "2.1.4",
|
||||
|
|
@ -8306,7 +8357,6 @@
|
|||
"version": "1.4.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.11.tgz",
|
||||
"integrity": "sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/express": "*"
|
||||
}
|
||||
|
|
@ -8343,14 +8393,12 @@
|
|||
"node_modules/@types/qs": {
|
||||
"version": "6.9.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.12.tgz",
|
||||
"integrity": "sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg=="
|
||||
},
|
||||
"node_modules/@types/range-parser": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz",
|
||||
"integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "18.2.33",
|
||||
|
|
@ -8406,7 +8454,6 @@
|
|||
"version": "0.17.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz",
|
||||
"integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/mime": "^1",
|
||||
"@types/node": "*"
|
||||
|
|
@ -8425,7 +8472,6 @@
|
|||
"version": "1.15.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz",
|
||||
"integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/http-errors": "*",
|
||||
"@types/mime": "*",
|
||||
|
|
@ -9677,8 +9723,7 @@
|
|||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"node_modules/aria-hidden": {
|
||||
"version": "1.2.3",
|
||||
|
|
@ -11036,9 +11081,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001596",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001596.tgz",
|
||||
"integrity": "sha512-zpkZ+kEr6We7w63ORkoJ2pOfBwBkY/bJrG/UZ90qNb45Isblu8wzDgevEOrRL1r9dWayHjYiiyCMEXPn4DweGQ==",
|
||||
"version": "1.0.30001597",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001597.tgz",
|
||||
"integrity": "sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
|
|
@ -15654,9 +15699,9 @@
|
|||
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz",
|
||||
"integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
|
|
@ -19593,7 +19638,6 @@
|
|||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
},
|
||||
|
|
@ -26478,6 +26522,11 @@
|
|||
"url": "https://opencollective.com/svgo"
|
||||
}
|
||||
},
|
||||
"node_modules/swagger-ui-dist": {
|
||||
"version": "5.11.2",
|
||||
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.11.2.tgz",
|
||||
"integrity": "sha512-jQG0cRgJNMZ7aCoiFofnoojeSaa/+KgWaDlfgs8QN+BXoGMpxeMVY5OEnjq4OlNvF3yjftO8c9GRAgcHlO+u7A=="
|
||||
},
|
||||
"node_modules/sweetalert2": {
|
||||
"version": "11.10.6",
|
||||
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.6.tgz",
|
||||
|
|
@ -28840,16 +28889,16 @@
|
|||
}
|
||||
},
|
||||
"node_modules/which-typed-array": {
|
||||
"version": "1.1.14",
|
||||
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz",
|
||||
"integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==",
|
||||
"version": "1.1.15",
|
||||
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz",
|
||||
"integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"available-typed-arrays": "^1.0.6",
|
||||
"call-bind": "^1.0.5",
|
||||
"available-typed-arrays": "^1.0.7",
|
||||
"call-bind": "^1.0.7",
|
||||
"for-each": "^0.3.3",
|
||||
"gopd": "^1.0.1",
|
||||
"has-tostringtag": "^1.0.1"
|
||||
"has-tostringtag": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
"license": "MIT",
|
||||
"scripts": {
|
||||
"dev": "concurrently \"stripe listen --forward-to localhost:3000/stripe\" \"nx run-many --target=serve --projects=frontend,backend,workers --parallel=4\"",
|
||||
"docs": "nx run-many --target=serve --projects=backend,docs --parallel=2",
|
||||
"workers": "nx run workers:serve:development",
|
||||
"cron": "nx run cron:serve:development",
|
||||
"command": "nx run commands:build && nx run commands:command",
|
||||
|
|
@ -24,6 +25,7 @@
|
|||
"@nestjs/platform-express": "^10.0.2",
|
||||
"@nestjs/schedule": "^4.0.0",
|
||||
"@nestjs/serve-static": "^4.0.1",
|
||||
"@nestjs/swagger": "^7.3.0",
|
||||
"@prisma/client": "^5.8.1",
|
||||
"@swc/helpers": "~0.5.2",
|
||||
"@sweetalert2/theme-dark": "^5.0.16",
|
||||
|
|
@ -33,6 +35,7 @@
|
|||
"@types/lodash": "^4.14.202",
|
||||
"@types/md5": "^2.3.5",
|
||||
"@types/mime-types": "^2.1.4",
|
||||
"@types/multer": "^1.4.11",
|
||||
"@types/remove-markdown": "^0.3.4",
|
||||
"@types/stripe": "^8.0.417",
|
||||
"@uidotdev/usehooks": "^2.4.1",
|
||||
|
|
@ -108,7 +111,6 @@
|
|||
"@testing-library/react": "14.0.0",
|
||||
"@types/cookie-parser": "^1.4.6",
|
||||
"@types/jest": "^29.4.0",
|
||||
"@types/multer": "^1.4.11",
|
||||
"@types/node": "18.16.9",
|
||||
"@types/react": "18.2.33",
|
||||
"@types/react-dom": "18.2.14",
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
"noPropertyAccessFromIndexSignature": false,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"importHelpers": true,
|
||||
"target": "es2015",
|
||||
"module": "esnext",
|
||||
|
|
|
|||