2
0

build: 🏗️ Add docker image and deployment features

This commit is contained in:
Baptiste Arnaud
2022-03-12 07:53:37 +01:00
parent 1dbbc9a251
commit e886d1b079
30 changed files with 2020 additions and 2136 deletions

View File

@ -50,6 +50,9 @@ NEXT_PUBLIC_VIEWER_HOST=http://localhost:3001
# (Optional) Error tracking with Sentry
NEXT_PUBLIC_SENTRY_DSN=
SENTRY_AUTH_TOKEN=
SENTRY_PROJECT=
SENTRY_ORG=
# Vercel
VERCEL_TOKEN=

View File

@ -8,7 +8,6 @@ module.exports = {
'plugin:@typescript-eslint/recommended',
'plugin:react/recommended',
'next/core-web-vitals',
'prettier',
],
parser: '@typescript-eslint/parser',
parserOptions: {
@ -23,10 +22,9 @@ module.exports = {
version: 'detect', // Tells eslint-plugin-react to automatically detect the version of React to use
},
},
plugins: ['prettier', 'react', '@typescript-eslint'],
plugins: ['react', '@typescript-eslint'],
rules: {
'react/no-unescaped-entities': [0],
'prettier/prettier': 'error',
'react/display-name': [0],
},
}

View File

@ -2,7 +2,9 @@
const { withSentryConfig } = require('@sentry/nextjs')
const moduleExports = {
// Your existing module.exports
experimental: {
outputStandalone: true,
},
}
const sentryWebpackPluginOptions = {
@ -11,4 +13,6 @@ const sentryWebpackPluginOptions = {
// https://github.com/getsentry/sentry-webpack-plugin#options.
}
module.exports = withSentryConfig(moduleExports, sentryWebpackPluginOptions)
module.exports = process.env.SENTRY_AUTH_TOKEN
? withSentryConfig(moduleExports, sentryWebpackPluginOptions)
: moduleExports

View File

@ -3,6 +3,7 @@
"version": "0.1.0",
"license": "AGPL-3.0-or-later",
"scripts": {
"dx": "yarn dev",
"dev": "next dev -p 3000",
"build": "next build",
"start": "next start",
@ -14,29 +15,29 @@
"workerDirectory": "public"
},
"dependencies": {
"@chakra-ui/css-reset": "^1.1.2",
"@chakra-ui/react": "^1.8.3",
"@chakra-ui/css-reset": "^1.1.3",
"@chakra-ui/react": "^1.8.6",
"@codemirror/basic-setup": "^0.19.1",
"@codemirror/lang-css": "^0.19.3",
"@codemirror/lang-html": "^0.19.4",
"@codemirror/lang-javascript": "^0.19.7",
"@codemirror/lang-json": "^0.19.1",
"@codemirror/lang-json": "^0.19.2",
"@codemirror/text": "^0.19.6",
"@emotion/react": "^11.7.1",
"@emotion/styled": "^11.6.0",
"@emotion/react": "^11.8.2",
"@emotion/styled": "^11.8.1",
"@giphy/js-fetch-api": "^4.1.2",
"@giphy/js-types": "^4.1.0",
"@giphy/react-components": "^5.4.0",
"@googleapis/drive": "^2.2.0",
"@giphy/react-components": "^5.6.1",
"@googleapis/drive": "^2.3.0",
"@next-auth/prisma-adapter": "1.0.1",
"@sentry/nextjs": "^6.17.7",
"@stripe/stripe-js": "^1.22.0",
"@udecode/plate-basic-marks": "^10.0.0",
"@sentry/nextjs": "^6.18.2",
"@stripe/stripe-js": "^1.24.0",
"@udecode/plate-basic-marks": "^10.2.2",
"@udecode/plate-common": "^7.0.2",
"@udecode/plate-core": "^10.0.0",
"@udecode/plate-link": "^10.0.0",
"@udecode/plate-ui-link": "^10.0.0",
"@udecode/plate-ui-toolbar": "^10.0.0",
"@udecode/plate-core": "^10.2.2",
"@udecode/plate-link": "^10.2.2",
"@udecode/plate-ui-link": "^10.2.2",
"@udecode/plate-ui-toolbar": "^10.2.2",
"bot-engine": "*",
"browser-image-compression": "^1.0.17",
"cuid": "^2.1.8",
@ -45,20 +46,20 @@
"dequal": "^2.0.2",
"focus-visible": "^5.2.0",
"framer-motion": "^4",
"google-auth-library": "^7.12.0",
"google-auth-library": "^7.14.0",
"google-spreadsheet": "^3.2.0",
"got": "^12.0.1",
"htmlparser2": "^7.2.0",
"immer": "^9.0.12",
"js-video-url-parser": "^0.5.1",
"jsonwebtoken": "^8.5.1",
"kbar": "^0.1.0-beta.27",
"kbar": "^0.1.0-beta.30",
"micro": "^9.3.4",
"micro-cors": "^0.1.1",
"minio": "^7.0.26",
"models": "*",
"msw": "^0.36.8",
"next": "^12.0.10",
"next": "^12.1.0",
"next-auth": "4.2.1",
"nodemailer": "^6.7.2",
"nprogress": "^0.2.0",
@ -69,40 +70,39 @@
"react-draggable": "^4.4.4",
"react-table": "^7.7.0",
"short-uuid": "^4.2.0",
"slate": "^0.72.8",
"slate": "^0.73.1",
"slate-history": "^0.66.0",
"slate-hyperscript": "^0.67.0",
"slate-react": "^0.72.9",
"stripe": "^8.202.0",
"slate-react": "^0.74.2",
"stripe": "^8.209.0",
"styled-components": "^5.3.3",
"svg-round-corners": "^0.3.0",
"swr": "^1.2.1",
"typebot-js": "^2.1.0",
"swr": "^1.2.2",
"typebot-js": "*",
"use-debounce": "^7.0.1",
"use-immer": "^0.6.0",
"utils": "*"
"utils": "*",
"prettier": "^2.5.1"
},
"devDependencies": {
"@playwright/test": "^1.19.0",
"@types/prettier": "^2.4.4",
"@playwright/test": "^1.19.2",
"@types/google-spreadsheet": "^3.1.5",
"@types/jsonwebtoken": "8.5.1",
"@types/jsonwebtoken": "8.5.8",
"@types/micro-cors": "^0.1.2",
"@types/minio": "^7.0.12",
"@types/node": "^17.0.17",
"@types/node": "^17.0.21",
"@types/nodemailer": "^6.4.4",
"@types/nprogress": "^0.2.0",
"@types/papaparse": "^5.3.2",
"@types/prettier": "^2.4.4",
"@types/qs": "^6.9.7",
"@types/react": "^17.0.39",
"@types/react": "^17.0.40",
"@types/react-table": "^7.7.9",
"@typescript-eslint/eslint-plugin": "^5.11.0",
"@typescript-eslint/eslint-plugin": "^5.14.0",
"dotenv": "^16.0.0",
"eslint": "<8.0.0",
"eslint-config-next": "12.0.10",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-config-next": "12.1.0",
"next-transpile-modules": "^9.0.0",
"prettier": "^2.5.1",
"typescript": "^4.5.5"
"typescript": "^4.6.2"
}
}

View File

@ -1,5 +1,5 @@
// Forked from https://github.com/nextauthjs/adapters/blob/main/packages/prisma/src/index.ts
import type { PrismaClient, Prisma, Invitation } from 'db'
import { PrismaClient, Prisma, Invitation, Plan } from 'db'
import { randomUUID } from 'crypto'
import type { Adapter, AdapterUser } from 'next-auth/adapters'
import cuid from 'cuid'
@ -12,7 +12,12 @@ export function CustomAdapter(p: PrismaClient): Adapter {
where: { email: user.email },
})
const createdUser = await p.user.create({
data: { ...data, id: user.id, apiToken: randomUUID() },
data: {
...data,
id: user.id,
apiToken: randomUUID(),
plan: process.env.ADMIN_EMAIL === data.email ? Plan.PRO : Plan.FREE,
},
})
if (invitations.length > 0)
await convertInvitationsToCollaborations(p, user, invitations)

View File

@ -5,8 +5,6 @@ import { NextApiRequest, NextApiResponse } from 'next'
import { getAuthenticatedUser } from 'services/api/utils'
import { methodNotAllowed, notAuthenticated } from 'utils'
const adminEmail = 'contact@baptiste-arnaud.fr'
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const user = await getAuthenticatedUser(req)
if (!user) return notAuthenticated(res)
@ -81,7 +79,7 @@ const parseWhereFilter = (
{
id: typebotId,
ownerId:
(type === 'read' && user.email === adminEmail) ||
(type === 'read' && user.email === process.env.ADMIN_EMAIL) ||
process.env.NEXT_PUBLIC_E2E_TEST
? undefined
: user.id,

View File

@ -5,8 +5,6 @@ import { getAuthenticatedUser } from 'services/api/utils'
import { isFreePlan } from 'services/user/user'
import { methodNotAllowed, notAuthenticated } from 'utils'
const adminEmail = 'contact@baptiste-arnaud.fr'
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const user = await getAuthenticatedUser(req)
if (!user) return notAuthenticated(res)
@ -24,7 +22,9 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
: undefined,
where: {
typebotId,
typebot: { ownerId: user.email === adminEmail ? undefined : user.id },
typebot: {
ownerId: user.email === process.env.ADMIN_EMAIL ? undefined : user.id,
},
answers: { some: {} },
isCompleted: isFreePlan(user) ? true : undefined,
},