diff --git a/apps/backend/project.json b/apps/backend/project.json index eea59114..c7147dd0 100644 --- a/apps/backend/project.json +++ b/apps/backend/project.json @@ -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": {}, diff --git a/apps/backend/src/main.ts b/apps/backend/src/main.ts index fd6de6fa..be549c06 100644 --- a/apps/backend/src/main.ts +++ b/apps/backend/src/main.ts @@ -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( diff --git a/apps/backend/tsconfig.json b/apps/backend/tsconfig.json index c1e2dd4e..0eec5713 100644 --- a/apps/backend/tsconfig.json +++ b/apps/backend/tsconfig.json @@ -11,6 +11,7 @@ } ], "compilerOptions": { - "esModuleInterop": true + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true } } diff --git a/apps/docs/README.md b/apps/docs/README.md new file mode 100644 index 00000000..c89c478d --- /dev/null +++ b/apps/docs/README.md @@ -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` diff --git a/apps/docs/_snippets/snippet-example.mdx b/apps/docs/_snippets/snippet-example.mdx new file mode 100644 index 00000000..089334c5 --- /dev/null +++ b/apps/docs/_snippets/snippet-example.mdx @@ -0,0 +1,3 @@ +## My Snippet + +This is an example of a reusable snippet diff --git a/apps/docs/api-reference/custom/authentications/check-org-and-user.mdx b/apps/docs/api-reference/custom/authentications/check-org-and-user.mdx new file mode 100644 index 00000000..657fa847 --- /dev/null +++ b/apps/docs/api-reference/custom/authentications/check-org-and-user.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /auth +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/authentications/login-to-meetfaq.mdx b/apps/docs/api-reference/custom/authentications/login-to-meetfaq.mdx new file mode 100644 index 00000000..c20b13e4 --- /dev/null +++ b/apps/docs/api-reference/custom/authentications/login-to-meetfaq.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /auth/login +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/authentications/register-to-meetfaq.mdx b/apps/docs/api-reference/custom/authentications/register-to-meetfaq.mdx new file mode 100644 index 00000000..217f3735 --- /dev/null +++ b/apps/docs/api-reference/custom/authentications/register-to-meetfaq.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /auth/registration +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/billings/get-billing.mdx b/apps/docs/api-reference/custom/billings/get-billing.mdx new file mode 100644 index 00000000..3fc1da21 --- /dev/null +++ b/apps/docs/api-reference/custom/billings/get-billing.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /billing +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/billings/get-billingcheck.mdx b/apps/docs/api-reference/custom/billings/get-billingcheck.mdx new file mode 100644 index 00000000..4bd8e533 --- /dev/null +++ b/apps/docs/api-reference/custom/billings/get-billingcheck.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /billing/check/{id} +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/billings/post-billingcancel.mdx b/apps/docs/api-reference/custom/billings/post-billingcancel.mdx new file mode 100644 index 00000000..aaf94dbd --- /dev/null +++ b/apps/docs/api-reference/custom/billings/post-billingcancel.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /billing/cancel +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/billings/post-billingmodify.mdx b/apps/docs/api-reference/custom/billings/post-billingmodify.mdx new file mode 100644 index 00000000..f6095e4e --- /dev/null +++ b/apps/docs/api-reference/custom/billings/post-billingmodify.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /billing/modify +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/billings/subscribe-to-a-plan.mdx b/apps/docs/api-reference/custom/billings/subscribe-to-a-plan.mdx new file mode 100644 index 00000000..b922bdbd --- /dev/null +++ b/apps/docs/api-reference/custom/billings/subscribe-to-a-plan.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /billing/subscribe +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/categories/delete-categories.mdx b/apps/docs/api-reference/custom/categories/delete-categories.mdx new file mode 100644 index 00000000..1d9db525 --- /dev/null +++ b/apps/docs/api-reference/custom/categories/delete-categories.mdx @@ -0,0 +1,3 @@ +--- +openapi: delete /categories/{id} +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/categories/get-categories-1.mdx b/apps/docs/api-reference/custom/categories/get-categories-1.mdx new file mode 100644 index 00000000..2f68a714 --- /dev/null +++ b/apps/docs/api-reference/custom/categories/get-categories-1.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /categories/{id} +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/categories/get-categories.mdx b/apps/docs/api-reference/custom/categories/get-categories.mdx new file mode 100644 index 00000000..3db7fdb8 --- /dev/null +++ b/apps/docs/api-reference/custom/categories/get-categories.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /categories +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/categories/get-categoriesfaq.mdx b/apps/docs/api-reference/custom/categories/get-categoriesfaq.mdx new file mode 100644 index 00000000..b36b0ac9 --- /dev/null +++ b/apps/docs/api-reference/custom/categories/get-categoriesfaq.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /categories/faq +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/categories/post-categories.mdx b/apps/docs/api-reference/custom/categories/post-categories.mdx new file mode 100644 index 00000000..46b46ba9 --- /dev/null +++ b/apps/docs/api-reference/custom/categories/post-categories.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /categories +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/categories/post-categoriesorder.mdx b/apps/docs/api-reference/custom/categories/post-categoriesorder.mdx new file mode 100644 index 00000000..40efc512 --- /dev/null +++ b/apps/docs/api-reference/custom/categories/post-categoriesorder.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /categories/order +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/categories/put-categories.mdx b/apps/docs/api-reference/custom/categories/put-categories.mdx new file mode 100644 index 00000000..da36ae7b --- /dev/null +++ b/apps/docs/api-reference/custom/categories/put-categories.mdx @@ -0,0 +1,3 @@ +--- +openapi: put /categories/{id} +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/faq/delete-faq.mdx b/apps/docs/api-reference/custom/faq/delete-faq.mdx new file mode 100644 index 00000000..e7c4d910 --- /dev/null +++ b/apps/docs/api-reference/custom/faq/delete-faq.mdx @@ -0,0 +1,3 @@ +--- +openapi: delete /faq/{id} +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/faq/get-faq.mdx b/apps/docs/api-reference/custom/faq/get-faq.mdx new file mode 100644 index 00000000..ce7a166f --- /dev/null +++ b/apps/docs/api-reference/custom/faq/get-faq.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /faq/{id} +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/faq/get-faqjobs.mdx b/apps/docs/api-reference/custom/faq/get-faqjobs.mdx new file mode 100644 index 00000000..e9ab5afb --- /dev/null +++ b/apps/docs/api-reference/custom/faq/get-faqjobs.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /faq/jobs/{id} +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/faq/post-faq.mdx b/apps/docs/api-reference/custom/faq/post-faq.mdx new file mode 100644 index 00000000..44b99764 --- /dev/null +++ b/apps/docs/api-reference/custom/faq/post-faq.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /faq +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/faq/post-faqanswers.mdx b/apps/docs/api-reference/custom/faq/post-faqanswers.mdx new file mode 100644 index 00000000..b8a0f570 --- /dev/null +++ b/apps/docs/api-reference/custom/faq/post-faqanswers.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /faq/answers +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/faq/post-faqjob.mdx b/apps/docs/api-reference/custom/faq/post-faqjob.mdx new file mode 100644 index 00000000..fe68f52e --- /dev/null +++ b/apps/docs/api-reference/custom/faq/post-faqjob.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /faq/job +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/faq/post-faqjobsquestions.mdx b/apps/docs/api-reference/custom/faq/post-faqjobsquestions.mdx new file mode 100644 index 00000000..78d14856 --- /dev/null +++ b/apps/docs/api-reference/custom/faq/post-faqjobsquestions.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /faq/jobs/questions +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/faq/post-faqorder.mdx b/apps/docs/api-reference/custom/faq/post-faqorder.mdx new file mode 100644 index 00000000..303e4c9a --- /dev/null +++ b/apps/docs/api-reference/custom/faq/post-faqorder.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /faq/order +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/faq/put-faq-category.mdx b/apps/docs/api-reference/custom/faq/put-faq-category.mdx new file mode 100644 index 00000000..687a000b --- /dev/null +++ b/apps/docs/api-reference/custom/faq/put-faq-category.mdx @@ -0,0 +1,3 @@ +--- +openapi: put /faq/{id}/category/{category} +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/faq/put-faq.mdx b/apps/docs/api-reference/custom/faq/put-faq.mdx new file mode 100644 index 00000000..dbc2d117 --- /dev/null +++ b/apps/docs/api-reference/custom/faq/put-faq.mdx @@ -0,0 +1,3 @@ +--- +openapi: put /faq/{id} +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/integrations/delete-integrations.mdx b/apps/docs/api-reference/custom/integrations/delete-integrations.mdx new file mode 100644 index 00000000..92bb1b87 --- /dev/null +++ b/apps/docs/api-reference/custom/integrations/delete-integrations.mdx @@ -0,0 +1,3 @@ +--- +openapi: delete /integrations/{id} +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/integrations/get-integrations-add.mdx b/apps/docs/api-reference/custom/integrations/get-integrations-add.mdx new file mode 100644 index 00000000..d2b7c2b9 --- /dev/null +++ b/apps/docs/api-reference/custom/integrations/get-integrations-add.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /integrations/{type}/add +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/integrations/get-integrations.mdx b/apps/docs/api-reference/custom/integrations/get-integrations.mdx new file mode 100644 index 00000000..ea16dc89 --- /dev/null +++ b/apps/docs/api-reference/custom/integrations/get-integrations.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /integrations +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/integrations/post-integrations.mdx b/apps/docs/api-reference/custom/integrations/post-integrations.mdx new file mode 100644 index 00000000..bd5ab22e --- /dev/null +++ b/apps/docs/api-reference/custom/integrations/post-integrations.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /integrations +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/invitations/post-invite.mdx b/apps/docs/api-reference/custom/invitations/post-invite.mdx new file mode 100644 index 00000000..fecc68cd --- /dev/null +++ b/apps/docs/api-reference/custom/invitations/post-invite.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /invite +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/invitations/post-inviteadd.mdx b/apps/docs/api-reference/custom/invitations/post-inviteadd.mdx new file mode 100644 index 00000000..b6019db1 --- /dev/null +++ b/apps/docs/api-reference/custom/invitations/post-inviteadd.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /invite/add +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/settings/delete-settingsdelete-domain.mdx b/apps/docs/api-reference/custom/settings/delete-settingsdelete-domain.mdx new file mode 100644 index 00000000..5abe4347 --- /dev/null +++ b/apps/docs/api-reference/custom/settings/delete-settingsdelete-domain.mdx @@ -0,0 +1,3 @@ +--- +openapi: delete /settings/delete-domain/{id} +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/settings/get-settings.mdx b/apps/docs/api-reference/custom/settings/get-settings.mdx new file mode 100644 index 00000000..f8aeb66a --- /dev/null +++ b/apps/docs/api-reference/custom/settings/get-settings.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /settings +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/settings/get-settingscheck-domain.mdx b/apps/docs/api-reference/custom/settings/get-settingscheck-domain.mdx new file mode 100644 index 00000000..8107e552 --- /dev/null +++ b/apps/docs/api-reference/custom/settings/get-settingscheck-domain.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /settings/check-domain/{id} +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/settings/post-settingscheck-subdomain.mdx b/apps/docs/api-reference/custom/settings/post-settingscheck-subdomain.mdx new file mode 100644 index 00000000..d631ba04 --- /dev/null +++ b/apps/docs/api-reference/custom/settings/post-settingscheck-subdomain.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /settings/check-subdomain +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/settings/post-settingsdomain.mdx b/apps/docs/api-reference/custom/settings/post-settingsdomain.mdx new file mode 100644 index 00000000..4c29ffef --- /dev/null +++ b/apps/docs/api-reference/custom/settings/post-settingsdomain.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /settings/domain +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/settings/post-settingssubdomain.mdx b/apps/docs/api-reference/custom/settings/post-settingssubdomain.mdx new file mode 100644 index 00000000..fb80a11b --- /dev/null +++ b/apps/docs/api-reference/custom/settings/post-settingssubdomain.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /settings/subDomain +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/stripe/post-stripe.mdx b/apps/docs/api-reference/custom/stripe/post-stripe.mdx new file mode 100644 index 00000000..3a80d176 --- /dev/null +++ b/apps/docs/api-reference/custom/stripe/post-stripe.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /stripe +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/styles/get-styles.mdx b/apps/docs/api-reference/custom/styles/get-styles.mdx new file mode 100644 index 00000000..cd7c91e1 --- /dev/null +++ b/apps/docs/api-reference/custom/styles/get-styles.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /styles +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/styles/put-styles.mdx b/apps/docs/api-reference/custom/styles/put-styles.mdx new file mode 100644 index 00000000..d3a6053d --- /dev/null +++ b/apps/docs/api-reference/custom/styles/put-styles.mdx @@ -0,0 +1,3 @@ +--- +openapi: put /styles +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/users/get-usersself.mdx b/apps/docs/api-reference/custom/users/get-usersself.mdx new file mode 100644 index 00000000..1a6792cd --- /dev/null +++ b/apps/docs/api-reference/custom/users/get-usersself.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /users/self +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/users/get-userssign-in.mdx b/apps/docs/api-reference/custom/users/get-userssign-in.mdx new file mode 100644 index 00000000..bec70c6a --- /dev/null +++ b/apps/docs/api-reference/custom/users/get-userssign-in.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /users/sign-in +--- \ No newline at end of file diff --git a/apps/docs/api-reference/custom/users/post-usersrevalidate.mdx b/apps/docs/api-reference/custom/users/post-usersrevalidate.mdx new file mode 100644 index 00000000..412894e6 --- /dev/null +++ b/apps/docs/api-reference/custom/users/post-usersrevalidate.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /users/revalidate +--- \ No newline at end of file diff --git a/apps/docs/api-reference/introduction.mdx b/apps/docs/api-reference/introduction.mdx new file mode 100644 index 00000000..f1f59cb8 --- /dev/null +++ b/apps/docs/api-reference/introduction.mdx @@ -0,0 +1,18 @@ +--- +title: 'Introduction' +--- + + + If you're not looking to build API reference documentation, you can delete + this section by removing the api-reference folder. + + +## 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.
+But if you want to test the API with Swagger or Postman, you can use the `auth` header. diff --git a/apps/docs/essentials/code.mdx b/apps/docs/essentials/code.mdx new file mode 100644 index 00000000..d2a462a7 --- /dev/null +++ b/apps/docs/essentials/code.mdx @@ -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!"); + } +} +``` +```` diff --git a/apps/docs/essentials/images.mdx b/apps/docs/essentials/images.mdx new file mode 100644 index 00000000..4c151777 --- /dev/null +++ b/apps/docs/essentials/images.mdx @@ -0,0 +1,59 @@ +--- +title: 'Images and Embeds' +description: 'Add image, video, and other HTML elements' +icon: 'image' +--- + + + +## Image + +### Using Markdown + +The [markdown syntax](https://www.markdownguide.org/basic-syntax/#images) lets you add images using the following code + +```md +![title](/path/image.jpg) +``` + +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 + +``` + +## Embeds and HTML elements + + + +
+ + + +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. + + + +### iFrames + +Loads another HTML page within the document. Most commonly used for embedding videos. + +```html + +``` diff --git a/apps/docs/essentials/markdown.mdx b/apps/docs/essentials/markdown.mdx new file mode 100644 index 00000000..c8ad9c1f --- /dev/null +++ b/apps/docs/essentials/markdown.mdx @@ -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 +``` + + + +Each **title** and **subtitle** creates an anchor and also shows up on the table of contents on the right. + + + +## 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 `` or `` around your text. + +| Text Size | How to write it | Result | +| ----------- | ------------------------ | ---------------------- | +| Superscript | `superscript` | superscript | +| Subscript | `subscript` | subscript | + +## 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. + +8 x (vk x H1 - H2) = (0,1) + +```md +8 x (vk x H1 - H2) = (0,1) +``` diff --git a/apps/docs/essentials/navigation.mdx b/apps/docs/essentials/navigation.mdx new file mode 100644 index 00000000..ca44bb64 --- /dev/null +++ b/apps/docs/essentials/navigation.mdx @@ -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. + + + +```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"] + } + ] + } +] +``` + + + +## 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`. + + + +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. + + + +```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. diff --git a/apps/docs/essentials/settings.mdx b/apps/docs/essentials/settings.mdx new file mode 100644 index 00000000..ae6e7d6a --- /dev/null +++ b/apps/docs/essentials/settings.mdx @@ -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 + + +Name of your project. Used for the global title. + +Example: `mintlify` + + + + + An array of groups with all the pages within that group + + + The name of the group. + + Example: `Settings` + + + + The relative paths to the markdown files that will serve as pages. + + Example: `["customization", "page"]` + + + + + + + + Path to logo image or object with path to "light" and "dark" mode logo images + + + Path to the logo in light mode + + + Path to the logo in dark mode + + + Where clicking on the logo links you to + + + + + + Path to the favicon image + + + + Hex color codes for your global theme + + + The primary color. Used for most often for highlighted content, section + headers, accents, in light mode + + + The primary color for dark mode. Used for most often for highlighted + content, section headers, accents, in dark mode + + + The primary color for important buttons + + + The color of the background in both light and dark mode + + + The hex color code of the background in light mode + + + The hex color code of the background in dark mode + + + + + + + + Array of `name`s and `url`s of links you want to include in the topbar + + + The name of the button. + + Example: `Contact us` + + + The url once you click on the button. Example: `https://mintlify.com/contact` + + + + + + + + + Link shows a button. GitHub shows the repo information at the url provided including the number of GitHub stars. + + + If `link`: What the button links to. + + If `github`: Link to the repository to load GitHub information from. + + + Text inside the button. Only required if `type` is a `link`. + + + + + + + Array of version names. Only use this if you want to show different versions + of docs with a dropdown in the navigation bar. + + + + An array of the anchors, includes the `icon`, `color`, and `url`. + + + The [Font Awesome](https://fontawesome.com/search?s=brands%2Cduotone) icon used to feature the anchor. + + Example: `comments` + + + The name of the anchor label. + + Example: `Community` + + + 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. + + + 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. + + + Used if you want to hide an anchor until the correct docs version is selected. + + + Pass `true` if you want to hide the anchor until you directly link someone to docs inside it. + + + One of: "brands", "duotone", "light", "sharp-solid", "solid", or "thin" + + + + + + + Override the default configurations for the top-most anchor. + + + The name of the top-most anchor + + + Font Awesome icon. + + + One of: "brands", "duotone", "light", "sharp-solid", "solid", or "thin" + + + + + + An array of navigational tabs. + + + The name of the tab label. + + + 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. + + + + + + Configuration for API settings. Learn more about API pages at [API Components](/api-playground/demo). + + + 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. + + + + + + The authentication strategy used for all API endpoints. + + + The name of the authentication parameter used in the API playground. + + If method is `basic`, the format should be `[usernameName]:[passwordName]` + + + 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`. + + + + + + Configurations for the API playground + + + + 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) + + + + + + Enabling this flag ensures that key ordering in OpenAPI pages matches the key ordering defined in the OpenAPI file. + + This behavior will soon be enabled by default, at which point this field will be deprecated. + + + + + + + A string or an array of strings of URL(s) or relative path(s) pointing to your + OpenAPI file. + + Examples: + + ```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"] + ``` + + + + + + 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" + } + ``` + + + One of the following values `website`, `facebook`, `twitter`, `discord`, `slack`, `github`, `linkedin`, `instagram`, `hacker-news` + + Example: `twitter` + + + The URL to the social platform. + + Example: `https://twitter.com/mintlify` + + + + + + Configurations to enable feedback buttons + + + + Enables a button to allow users to suggest edits via pull requests + + + Enables a button to allow users to raise an issue about the documentation + + + + + + Customize the dark mode toggle. + + + 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. + + + 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: + + + ```json Only Dark Mode + "modeToggle": { + "default": "dark", + "isHidden": true + } + ``` + + ```json Only Light Mode + "modeToggle": { + "default": "light", + "isHidden": true + } + ``` + + + + + + + + + A background image to be displayed behind every page. See example with + [Infisical](https://infisical.com/docs) and [FRPC](https://frpc.io). + diff --git a/apps/docs/favicon.png b/apps/docs/favicon.png new file mode 100644 index 00000000..8f4b9758 Binary files /dev/null and b/apps/docs/favicon.png differ diff --git a/apps/docs/howitworks.mdx b/apps/docs/howitworks.mdx new file mode 100644 index 00000000..446052d5 --- /dev/null +++ b/apps/docs/howitworks.mdx @@ -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.
+The entire project is built under [NX](https://nx.dev/) to have a monorepo with multiple projects.

+Unlike other NX project, this project has one `.env` file that is shared between all the apps.
+It makes it easier to develop and deploy the project.

+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.

+ +**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. + +Architecture of crosspublic + +## Architecture +### Backend +The project has a centralized backend that both the bots and the client interact with.
+The backend is built with [NestJS](https://nestjs.com/) with a basic architecture of controllers, services, repositories and dtos.

+It uses [Prisma](https://www.prisma.io/) as an ORM to interact with the database.
+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.

+The project doesn't have a control panel login, it works with an SSO using the different bots.
+Once somebody uses a command like `/add` or `/signin` the backend will receive the server id and the internal user id from the bot.

+The backend will auto-create an organization and a user if it doesn't exist.
+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/).
+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/).
+It's the website for the end-users to see the FAQ.
+It contains a simple search bar and a list of questions.
+The search bar uses [Algolia](https://www.algolia.com/) to search through the questions.
+It uses the style from the control panel to customize the website.
+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.
+ +### Discord +The Discord bot is built with [Discord.JS](https://discord.js.org/) and [NestJS](https://nestjs.com/).
+It runs in a loop and listens to every message in every server it's in.
+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.
+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/).
+It's a simple static websites with a few pages. + +### Docs +The documentation website is built with [Mintlify](https://www.mintlify.com/).
+The reference in the documentation is being auto-generated by the backend.
+NestJS has a built-in Swagger module that generates a JSON file with all the routes and their documentation.
+It makes it very easy to track API changes and deploy them. diff --git a/apps/docs/images/arch.png b/apps/docs/images/arch.png new file mode 100644 index 00000000..c7b64e4f Binary files /dev/null and b/apps/docs/images/arch.png differ diff --git a/apps/docs/images/checks-passed.png b/apps/docs/images/checks-passed.png new file mode 100644 index 00000000..3303c773 Binary files /dev/null and b/apps/docs/images/checks-passed.png differ diff --git a/apps/docs/images/hero-dark.svg b/apps/docs/images/hero-dark.svg new file mode 100644 index 00000000..c6a30e88 --- /dev/null +++ b/apps/docs/images/hero-dark.svg @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/docs/images/hero-light.svg b/apps/docs/images/hero-light.svg new file mode 100644 index 00000000..297d68fb --- /dev/null +++ b/apps/docs/images/hero-light.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/docs/introduction.mdx b/apps/docs/introduction.mdx new file mode 100644 index 00000000..b2fbd974 --- /dev/null +++ b/apps/docs/introduction.mdx @@ -0,0 +1,53 @@ +--- +title: Introduction +description: 'Welcome to crosspublic documentation' +--- + +
+ Hero Light + Hero Dark +
+ +## What is crosspublic? + +crosspublic is a tool to convert private communication into public knowledge.
+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.
+ +## Architecture +crosspublic is an [NX monorepo](https://nx.dev) that contains the backend, control panel, discord bot, marketing website and the docs.

+Unlike other NX project, this project has one `.env` file that is shared between all the apps.
+It makes it easier to develop and deploy the project.

+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.
+ +**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. + + + + Learn how to install the project and start using it + + + Learn the architecture of the project + + diff --git a/apps/docs/logo/dark.png b/apps/docs/logo/dark.png new file mode 100644 index 00000000..ee9a3d43 Binary files /dev/null and b/apps/docs/logo/dark.png differ diff --git a/apps/docs/logo/light.png b/apps/docs/logo/light.png new file mode 100644 index 00000000..da52061a Binary files /dev/null and b/apps/docs/logo/light.png differ diff --git a/apps/docs/mint.js b/apps/docs/mint.js new file mode 100644 index 00000000..576c9139 --- /dev/null +++ b/apps/docs/mint.js @@ -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" + } +}; diff --git a/apps/docs/mint.json b/apps/docs/mint.json new file mode 100644 index 00000000..9fb90a8c --- /dev/null +++ b/apps/docs/mint.json @@ -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" + } +} diff --git a/apps/docs/openapi.json b/apps/docs/openapi.json new file mode 100644 index 00000000..712c30c6 --- /dev/null +++ b/apps/docs/openapi.json @@ -0,0 +1 @@ +{"openapi":"3.0.0","paths":{"/auth":{"post":{"operationId":"AuthController_checkOrgAndUser","summary":"Check org and user","description":"Checking that the bot that in the server is actually authenticated","parameters":[{"name":"serverkey","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationCreateValidator"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Authentications"]}},"/auth/registration":{"post":{"operationId":"AuthController_register","summary":"Register to crosspublic","description":"This will create an organization and a user","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationValidator"}}}},"responses":{"201":{"description":""}},"tags":["Authentications"]}},"/auth/login":{"post":{"operationId":"AuthController_login","summary":"Login to crosspublic","description":"This will login the user","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginValidator"}}}},"responses":{"201":{"description":""}},"tags":["Authentications"]}},"/stripe":{"post":{"operationId":"StripeController_stripe","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Stripe"]}},"/public/categories":{"get":{"operationId":"PublicCategoriesController_categories","summary":"Categories List","description":"Get all categories from organization \n\n **[WARNING]**: This endpoint requires the PRO package","parameters":[{"name":"apikey","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Public"]}},"/public/categories/{slug}/faqs":{"get":{"operationId":"PublicCategoriesController_allFaqsFromCategories","summary":"FAQ List","description":"Get all faqs from category slug \n\n **[WARNING]**: This endpoint requires the PRO package","parameters":[{"name":"apikey","in":"header","required":true,"schema":{"type":"string"}},{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Public"]}},"/public/faq/{slug}":{"get":{"operationId":"PublicFaqController_getFaqBySlug","summary":"Retrieve FAQ","description":"Get FAQ by slug \n\n **[WARNING]**: This endpoint requires the PRO package","parameters":[{"name":"apikey","in":"header","required":true,"schema":{"type":"string"}},{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Public"]}},"/public/styles":{"get":{"operationId":"PublicStyleController_getOrganizationStyle","summary":"Get organization style","description":"Get organization style \n\n **[WARNING]**: This endpoint requires the PRO package","parameters":[{"name":"apikey","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Public"]}},"/users/sign-in":{"get":{"operationId":"UsersController_signIn","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Users"]}},"/users/self":{"get":{"operationId":"UsersController_getUser","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Users"]}},"/users/revalidate":{"post":{"operationId":"UsersController_revalidate","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Users"]}},"/faq/{id}":{"delete":{"operationId":"FaqController_deleteFaq","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Faq"]},"get":{"operationId":"FaqController_getFaq","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Faq"]},"put":{"operationId":"FaqController_updateFaq","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFaqValidator"}}}},"responses":{"200":{"description":""}},"tags":["Faq"]}},"/faq/order":{"post":{"operationId":"FaqController_orderFaqs","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderValidator"}}}},"responses":{"201":{"description":""}},"tags":["Faq"]}},"/faq/{id}/category/{category}":{"put":{"operationId":"FaqController_changeFaqCategory","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"category","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Faq"]}},"/faq":{"post":{"operationId":"FaqController_createFaq","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFaqValidator"}}}},"responses":{"201":{"description":""}},"tags":["Faq"]}},"/faq/job":{"post":{"operationId":"FaqController_createJob","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessagesListValidator"}}}},"responses":{"201":{"description":""}},"tags":["Faq"]}},"/faq/jobs/questions":{"post":{"operationId":"FaqController_getJobQuestions","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnlyMessagesList"}}}},"responses":{"201":{"description":""}},"tags":["Faq"]}},"/faq/answers":{"post":{"operationId":"FaqController_getJobAnswers","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnsweredQuestion"}}}},"responses":{"201":{"description":""}},"tags":["Faq"]}},"/faq/jobs/{id}":{"get":{"operationId":"FaqController_getJobById","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Faq"]}},"/categories/order":{"post":{"operationId":"CategoriesController_orderCategories","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderValidator"}}}},"responses":{"201":{"description":""}},"tags":["Categories"]}},"/categories":{"get":{"operationId":"CategoriesController_getCategories","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Categories"]},"post":{"operationId":"CategoriesController_createCategory","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCategoryValidator"}}}},"responses":{"201":{"description":""}},"tags":["Categories"]}},"/categories/faq":{"get":{"operationId":"CategoriesController_getFaqs","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Categories"]}},"/categories/{id}":{"put":{"operationId":"CategoriesController_updateCategory","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCategoryValidator"}}}},"responses":{"200":{"description":""}},"tags":["Categories"]},"delete":{"operationId":"CategoriesController_deleteCategory","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteCategoryValidator"}}}},"responses":{"200":{"description":""}},"tags":["Categories"]},"get":{"operationId":"CategoriesController_getCategory","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Categories"]}},"/settings":{"get":{"operationId":"SettingsController_getSettings","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Settings"]}},"/settings/check-subdomain":{"post":{"operationId":"SettingsController_checkSubdomain","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckSubdomainValidator"}}}},"responses":{"201":{"description":""}},"tags":["Settings"]}},"/settings/check-domain/{id}":{"get":{"operationId":"SettingsController_checkDomain","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Settings"]}},"/settings/delete-domain/{id}":{"delete":{"operationId":"SettingsController_deleteDomain","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"boolean"}}}}},"tags":["Settings"]}},"/settings/domain":{"post":{"operationId":"SettingsController_addDomain","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddDomainValidator"}}}},"responses":{"201":{"description":""}},"tags":["Settings"]}},"/settings/subDomain":{"post":{"operationId":"SettingsController_subDomain","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckSubdomainValidator"}}}},"responses":{"201":{"description":""}},"tags":["Settings"]}},"/billing/check/{id}":{"get":{"operationId":"BillingController_checkId","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Billings"]}},"/billing/subscribe":{"post":{"operationId":"BillingController_subscribe","summary":"Subscribe to a plan","description":"Subscribe to a plan","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingSubscribeValidator"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Billings"]}},"/billing/modify":{"post":{"operationId":"BillingController_modifyPayment","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Billings"]}},"/billing":{"get":{"operationId":"BillingController_getCurrentBilling","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Billings"]}},"/billing/cancel":{"post":{"operationId":"BillingController_cancel","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Billings"]}},"/styles":{"get":{"operationId":"StylesController_getStyles","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Styles"]},"put":{"operationId":"StylesController_updateStyles","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateStyleValidator"}}}},"responses":{"200":{"description":""}},"tags":["Styles"]}},"/integrations":{"get":{"operationId":"IntegrationsController_getIntegrations","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Integrations"]},"post":{"operationId":"IntegrationsController_create","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIntegrationValidator"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Integrations"]}},"/integrations/{type}/add":{"get":{"operationId":"IntegrationsController_createIntegration","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}},{"name":"type","required":true,"in":"path","schema":{"enum":["slack","discord"],"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Integrations"]}},"/integrations/{id}":{"delete":{"operationId":"IntegrationsController_delete","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Integrations"]}},"/invite":{"post":{"operationId":"InviteController_create","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitationsValidator"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"tags":["Invitations"]}},"/invite/add":{"post":{"operationId":"InviteController_add","parameters":[{"name":"auth","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Invitations"]}}},"info":{"title":"crosspublic Swagger file","description":"API description","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"schemas":{"OrganizationCreateValidator":{"type":"object","properties":{"serverName":{"type":"string"},"guildId":{"type":"string"},"isOwner":{"type":"boolean"},"internalId":{"type":"string"},"name":{"type":"string"}},"required":["serverName","guildId","isOwner","internalId","name"]},"RegistrationValidator":{"type":"object","properties":{"email":{"type":"string"},"password":{"type":"string","minLength":3},"company":{"type":"string","minLength":3},"token":{"type":"string"}},"required":["email","password","company"]},"LoginValidator":{"type":"object","properties":{"email":{"type":"string"},"password":{"type":"string","minLength":3}},"required":["email","password"]},"OrderListValidator":{"type":"object","properties":{"id":{"type":"string"},"order":{"type":"number"}},"required":["id","order"]},"OrderValidator":{"type":"object","properties":{"order":{"type":"array","items":{"$ref":"#/components/schemas/OrderListValidator"}}},"required":["order"]},"CreateFaqValidator":{"type":"object","properties":{"question":{"type":"string","minLength":3},"answer":{"type":"string","minLength":3},"categoryId":{"type":"string"}},"required":["question","answer","categoryId"]},"MessageList":{"type":"object","properties":{"name":{"type":"string"},"message":{"type":"string"}},"required":["name","message"]},"MessagesListValidator":{"type":"object","properties":{"reference":{"type":"string"},"messagesList":{"type":"array","items":{"$ref":"#/components/schemas/MessageList"}}},"required":["reference","messagesList"]},"OnlyMessagesList":{"type":"object","properties":{"messagesList":{"type":"array","items":{"$ref":"#/components/schemas/MessageList"}}},"required":["messagesList"]},"AnsweredQuestion":{"type":"object","properties":{"messagesList":{"type":"array","items":{"$ref":"#/components/schemas/MessageList"}},"question":{"type":"string"}},"required":["messagesList","question"]},"CreateCategoryValidator":{"type":"object","properties":{"name":{"type":"string","minLength":3},"editor":{"type":"string","minLength":3}},"required":["name","editor"]},"DeleteCategoryValidator":{"type":"object","properties":{"category":{"type":"string"}},"required":["category"]},"CheckSubdomainValidator":{"type":"object","properties":{"subDomain":{"type":"string","minLength":3}},"required":["subDomain"]},"AddDomainValidator":{"type":"object","properties":{"domain":{"type":"string","pattern":"/^(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}$/"}},"required":["domain"]},"BillingSubscribeValidator":{"type":"object","properties":{"period":{"type":"object","enum":["MONTHLY","YEARLY"]},"billing":{"type":"string","enum":["BASIC","PRO"]}},"required":["period","billing"]},"UpdateStyleValidator":{"type":"object","properties":{"name":{"type":"string","minLength":1},"topBarColor":{"type":"string"},"topBarTextColor":{"type":"string"},"backgroundColor":{"type":"string"},"pageTextColor":{"type":"string"},"pageBlockColor":{"type":"string"},"brandingText":{"type":"string"}},"required":["name","topBarColor","topBarTextColor","backgroundColor","pageTextColor","pageBlockColor","brandingText"]},"CreateIntegrationValidator":{"type":"object","properties":{"type":{"type":"string","enum":["discord","slack"]},"information":{"type":"object"}},"required":["type","information"]},"InvitationsValidator":{"type":"object","properties":{"type":{"type":"string","enum":["discord","slack"]},"information":{"type":"object"}},"required":["type","information"]}}}} diff --git a/apps/docs/project.json b/apps/docs/project.json new file mode 100644 index 00000000..b4e731ca --- /dev/null +++ b/apps/docs/project.json @@ -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": [] +} diff --git a/apps/docs/public-api-reference/custom/public/categories-list.mdx b/apps/docs/public-api-reference/custom/public/categories-list.mdx new file mode 100644 index 00000000..9db421b6 --- /dev/null +++ b/apps/docs/public-api-reference/custom/public/categories-list.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /public/categories +--- \ No newline at end of file diff --git a/apps/docs/public-api-reference/custom/public/faq-list.mdx b/apps/docs/public-api-reference/custom/public/faq-list.mdx new file mode 100644 index 00000000..5d58778a --- /dev/null +++ b/apps/docs/public-api-reference/custom/public/faq-list.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /public/categories/{slug}/faqs +--- \ No newline at end of file diff --git a/apps/docs/public-api-reference/custom/public/get-organization-style.mdx b/apps/docs/public-api-reference/custom/public/get-organization-style.mdx new file mode 100644 index 00000000..f5d8fb33 --- /dev/null +++ b/apps/docs/public-api-reference/custom/public/get-organization-style.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /public/styles +--- \ No newline at end of file diff --git a/apps/docs/public-api-reference/custom/public/retrieve-faq.mdx b/apps/docs/public-api-reference/custom/public/retrieve-faq.mdx new file mode 100644 index 00000000..0e9e08dc --- /dev/null +++ b/apps/docs/public-api-reference/custom/public/retrieve-faq.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /public/faq/{slug} +--- \ No newline at end of file diff --git a/apps/docs/public-api-reference/introduction.mdx b/apps/docs/public-api-reference/introduction.mdx new file mode 100644 index 00000000..a7ff3809 --- /dev/null +++ b/apps/docs/public-api-reference/introduction.mdx @@ -0,0 +1,21 @@ +--- +title: 'Introduction' +description: 'How to use the public API' +--- + + + The Public API is only available for the PRO plan and the self-hosted plan. + + +## 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.
+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.
+The `serverkey` is the value of `BACKEND_TOKEN_PROTECTOR` in the `.env` file. + +Check the endpoints on the left for API reference. diff --git a/apps/docs/quickstart.mdx b/apps/docs/quickstart.mdx new file mode 100644 index 00000000..9002eca0 --- /dev/null +++ b/apps/docs/quickstart.mdx @@ -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.
+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.
+After that, go to the bot tab and create a new bot.
+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.
+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/).
+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.
+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= +DISCORD_TOKEN= +DATABASE_URL=postgres://root:your_password@localhost:5432/crosspublic +BACKEND_URL=http://localhost:3000 +NEXT_PUBLIC_BACKEND_URL=http://localhost:3000 +BACKEND_TOKEN_PROTECTOR= +OPENAI_API_KEY= +JWT_SECRET= +FRONTEND_URL=http://localhost:4200 +BLOB_READ_WRITE_TOKEN= +PROJECT_ID_VERCEL= +TEAM_ID_VERCEL= +PAYMENT_PUBLIC_KEY= +PAYMENT_SECRET_KEY= +PAYMENT_SIGNING_SECRET= +MARKETING_WEBSITE_URL=http://localhost:4201 +DOCS_URL=https://localhost:3000 +NEXT_PUBLIC_ALGOLIA_APP_ID= +NEXT_PUBLIC_ALGOLIA_SEARCH_KEY= +ALGOLIA_ADMIN_API_KEY= +``` + +### 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 +``` + diff --git a/apps/docs/test.js b/apps/docs/test.js new file mode 100644 index 00000000..b022398e --- /dev/null +++ b/apps/docs/test.js @@ -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); +})(); diff --git a/libraries/helpers/src/swagger/load.swagger.ts b/libraries/helpers/src/swagger/load.swagger.ts new file mode 100644 index 00000000..b6149a64 --- /dev/null +++ b/libraries/helpers/src/swagger/load.swagger.ts @@ -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); +} \ No newline at end of file diff --git a/libraries/nestjs-libraries/src/upload/upload.module.ts b/libraries/nestjs-libraries/src/upload/upload.module.ts index 4f8e8cb1..d4f14a66 100644 --- a/libraries/nestjs-libraries/src/upload/upload.module.ts +++ b/libraries/nestjs-libraries/src/upload/upload.module.ts @@ -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'; diff --git a/package-lock.json b/package-lock.json index 8857e1be..99808377 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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" diff --git a/package.json b/package.json index b5d9a334..e61f3891 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/tsconfig.base.json b/tsconfig.base.json index fcf40551..daf74911 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -11,6 +11,7 @@ "noPropertyAccessFromIndexSignature": false, "esModuleInterop": true, "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, "importHelpers": true, "target": "es2015", "module": "esnext",