diff --git a/Dockerfile b/Dockerfile index d1f6e11..b8db87a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,23 @@ -FROM node:14 +FROM node:16 WORKDIR . -COPY package*.json . -RUN npm i --production +ARG NODE_ENV +ARG DATABASE_URL +ARG GOOGLE_CLIENT_ID +ARG GOOGLE_CLIENT_SECRET +ARG AUTH_SECRET +ARG AUTH_URL +ARG NEXT_PUBLIC_BASE_URL +ARG NEXT_PUBLIC_MAPTILER_ACCESS_TOKEN +ARG SENDGRID_API_KEY +ARG SENDGRID_SENDER +COPY package*.json . +RUN npm ci --production +RUN npm i --save-dev typescript postcss ts-node sharp COPY . . +RUN npm run db:generate RUN npm run build EXPOSE 3000 diff --git a/README.md b/README.md index 7967ffd..5c980b1 100644 --- a/README.md +++ b/README.md @@ -34,9 +34,23 @@ npx prisma studio ``` ## Start production server +Create a file named `.env.production`: +``` +NODE_ENV=production + +DATABASE_URL=postgresql://computational_puzzles:computational_puzzles@db:5432/mydb?schema=public&connect_timeout=300 +GOOGLE_CLIENT_ID=10889722286-8uek1esq4uicv31an6tehi60c7ev5lvp.apps.googleusercontent.com +GOOGLE_CLIENT_SECRET=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 +SECRET=secret +AUTH_SECRET=secret +AUTH_URL=http://localhost:3000 + +NEXT_PUBLIC_BASE_URL=http://localhost:3000 +NEXT_PUBLIC_MAPTILER_ACCESS_TOKEN=uTyRuREEmko5kblSVwhb +``` +Then, run the following command ```bash -docker-compose build -docker-compose up +docker-compose up -- build ``` ## For testing diff --git a/docker-compose.yml b/docker-compose.yml index 8645ab1..58381be 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,22 +2,39 @@ version: "3.6" services: app: - build: . - env_file: .env + build: + context: . + dockerfile: Dockerfile + args: + NODE_ENV: ${NODE_ENV} + DATABASE_URL: ${DATABASE_URL} + GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID} + GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET} + AUTH_SECRET: ${AUTH_SECRET} + AUTH_URL: ${AUTH_URL} + NEXT_PUBLIC_BASE_URL: ${NEXT_PUBLIC_BASE_URL} + NEXT_PUBLIC_MAPTILER_ACCESS_TOKEN: ${NEXT_PUBLIC_MAPTILER_ACCESS_TOKEN} + SENDGRID_API_KEY: ${SENDGRID_API_KEY} + SENDGRID_SENDER: ${SENDGRID_SENDER} + env_file: .env.production + image: computational_puzzles + volumes: + - ./:/app ports: - "3000:3000" - volumes: - - app:/app depends_on: - db networks: - app_network - + links: + - db:db + db: image: postgres:9.6 + container_name: computational_puzzle_db volumes: - db_data:/var/lib/postgresql/data - env_file: .env + env_file: .env.production environment: POSTGRES_USER: computational_puzzles POSTGRES_PASSWORD: computational_puzzles # This is used to create development database, please change when migrate to production @@ -28,7 +45,6 @@ services: - app_network volumes: - app: db_data: networks: diff --git a/package-lock.json b/package-lock.json index 4022fdc..b236cf7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@next-auth/prisma-adapter": "^0.5.2-next.19", "@prisma/client": "^3.6.0", "@types/react": "^17.0.27", - "argon2": "^0.28.3", + "argon2": "^0.28.5", "axios": "^0.24.0", "babel-plugin-superjson-next": "^0.4.2", "next": "^12.0.7", @@ -39,7 +39,7 @@ "@types/supertest": "^2.0.11", "@typescript-eslint/eslint-plugin": "^4.33.0", "@typescript-eslint/parser": "^4.33.0", - "babel-jest": "^27.2.3", + "babel-jest": "^27.5.1", "dotenv": "^14.3.2", "eslint": "^7.32.0", "eslint-config-next": "11.1.2", @@ -1129,23 +1129,23 @@ } }, "node_modules/@jest/transform": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.5.tgz", - "integrity": "sha512-PuMet2UlZtlGzwc6L+aZmR3I7CEBpqadO03pU40l2RNY2fFJ191b9/ITB44LNOhVtsyykx0OZvj0PCyuLm7Eew==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", "dev": true, "dependencies": { "@babel/core": "^7.1.0", - "@jest/types": "^27.4.2", - "babel-plugin-istanbul": "^6.0.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", - "jest-regex-util": "^27.4.0", - "jest-util": "^27.4.2", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", "micromatch": "^4.0.4", - "pirates": "^4.0.1", + "pirates": "^4.0.4", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" @@ -1234,9 +1234,9 @@ } }, "node_modules/@jest/types": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz", - "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -2108,9 +2108,9 @@ "dev": true }, "node_modules/@types/babel__core": { - "version": "7.1.17", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.17.tgz", - "integrity": "sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A==", + "version": "7.1.19", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", + "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -2121,9 +2121,9 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", - "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, "dependencies": { "@babel/types": "^7.0.0" @@ -2923,18 +2923,18 @@ "dev": true }, "node_modules/babel-jest": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.5.tgz", - "integrity": "sha512-3uuUTjXbgtODmSv/DXO9nZfD52IyC2OYTFaXGRzL0kpykzroaquCrD5+lZNafTvZlnNqZHt5pb0M08qVBZnsnA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", "dev": true, "dependencies": { - "@jest/transform": "^27.4.5", - "@jest/types": "^27.4.2", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.4.0", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "slash": "^3.0.0" }, "engines": { @@ -3031,9 +3031,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", - "integrity": "sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", "dev": true, "dependencies": { "@babel/template": "^7.3.3", @@ -3086,12 +3086,12 @@ } }, "node_modules/babel-preset-jest": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz", - "integrity": "sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^27.4.0", + "babel-plugin-jest-hoist": "^27.5.1", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { @@ -5528,9 +5528,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "node_modules/harmony-reflect": { "version": "1.6.2", @@ -6903,21 +6903,21 @@ } }, "node_modules/jest-haste-map": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.5.tgz", - "integrity": "sha512-oJm1b5qhhPs78K24EDGifWS0dELYxnoBiDhatT/FThgB9yxqUm5F6li3Pv+Q+apMBmmPNzOBnZ7ZxWMB1Leq1Q==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", "dev": true, "dependencies": { - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "@types/graceful-fs": "^4.1.2", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.4.0", - "jest-serializer": "^27.4.0", - "jest-util": "^27.4.2", - "jest-worker": "^27.4.5", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", "micromatch": "^4.0.4", "walker": "^1.0.7" }, @@ -7246,9 +7246,9 @@ } }, "node_modules/jest-regex-util": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.4.0.tgz", - "integrity": "sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", "dev": true, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -7570,13 +7570,13 @@ } }, "node_modules/jest-serializer": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.4.0.tgz", - "integrity": "sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", "dev": true, "dependencies": { "@types/node": "*", - "graceful-fs": "^4.2.4" + "graceful-fs": "^4.2.9" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" @@ -7703,16 +7703,16 @@ } }, "node_modules/jest-util": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz", - "integrity": "sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", "dev": true, "dependencies": { - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "picomatch": "^2.2.3" }, "engines": { @@ -7977,9 +7977,9 @@ } }, "node_modules/jest-worker": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.5.tgz", - "integrity": "sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, "dependencies": { "@types/node": "*", @@ -12368,23 +12368,23 @@ } }, "@jest/transform": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.4.5.tgz", - "integrity": "sha512-PuMet2UlZtlGzwc6L+aZmR3I7CEBpqadO03pU40l2RNY2fFJ191b9/ITB44LNOhVtsyykx0OZvj0PCyuLm7Eew==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^27.4.2", - "babel-plugin-istanbul": "^6.0.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.4.5", - "jest-regex-util": "^27.4.0", - "jest-util": "^27.4.2", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", "micromatch": "^4.0.4", - "pirates": "^4.0.1", + "pirates": "^4.0.4", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" @@ -12448,9 +12448,9 @@ } }, "@jest/types": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz", - "integrity": "sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -13050,9 +13050,9 @@ "dev": true }, "@types/babel__core": { - "version": "7.1.17", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.17.tgz", - "integrity": "sha512-6zzkezS9QEIL8yCBvXWxPTJPNuMeECJVxSOhxNY/jfq9LxOTHivaYTqr37n9LknWWRTIkzqH2UilS5QFvfa90A==", + "version": "7.1.19", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", + "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -13063,9 +13063,9 @@ } }, "@types/babel__generator": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", - "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, "requires": { "@babel/types": "^7.0.0" @@ -13690,18 +13690,18 @@ "dev": true }, "babel-jest": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.5.tgz", - "integrity": "sha512-3uuUTjXbgtODmSv/DXO9nZfD52IyC2OYTFaXGRzL0kpykzroaquCrD5+lZNafTvZlnNqZHt5pb0M08qVBZnsnA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", "dev": true, "requires": { - "@jest/transform": "^27.4.5", - "@jest/types": "^27.4.2", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.4.0", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "slash": "^3.0.0" }, "dependencies": { @@ -13770,9 +13770,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz", - "integrity": "sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -13812,12 +13812,12 @@ } }, "babel-preset-jest": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz", - "integrity": "sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^27.4.0", + "babel-plugin-jest-hoist": "^27.5.1", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -15698,9 +15698,9 @@ } }, "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "harmony-reflect": { "version": "1.6.2", @@ -16675,22 +16675,22 @@ "dev": true }, "jest-haste-map": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.5.tgz", - "integrity": "sha512-oJm1b5qhhPs78K24EDGifWS0dELYxnoBiDhatT/FThgB9yxqUm5F6li3Pv+Q+apMBmmPNzOBnZ7ZxWMB1Leq1Q==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", "dev": true, "requires": { - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "@types/graceful-fs": "^4.1.2", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.3.2", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.4.0", - "jest-serializer": "^27.4.0", - "jest-util": "^27.4.2", - "jest-worker": "^27.4.5", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", "micromatch": "^4.0.4", "walker": "^1.0.7" } @@ -16931,9 +16931,9 @@ "requires": {} }, "jest-regex-util": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.4.0.tgz", - "integrity": "sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", "dev": true }, "jest-resolve": { @@ -17183,13 +17183,13 @@ } }, "jest-serializer": { - "version": "27.4.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.4.0.tgz", - "integrity": "sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", "dev": true, "requires": { "@types/node": "*", - "graceful-fs": "^4.2.4" + "graceful-fs": "^4.2.9" } }, "jest-snapshot": { @@ -17285,16 +17285,16 @@ } }, "jest-util": { - "version": "27.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz", - "integrity": "sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", "dev": true, "requires": { - "@jest/types": "^27.4.2", + "@jest/types": "^27.5.1", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "picomatch": "^2.2.3" }, "dependencies": { @@ -17487,9 +17487,9 @@ } }, "jest-worker": { - "version": "27.4.5", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.5.tgz", - "integrity": "sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, "requires": { "@types/node": "*", diff --git a/package.json b/package.json index e07f01c..6c22b7b 100644 --- a/package.json +++ b/package.json @@ -10,14 +10,17 @@ "lint": "next lint", "test": "jest --runInBand", "prettify": "npx prettier --write src/", - "db:push": "prisma db push" + "db:push": "prisma db push", + "db:generate": "prisma generate", + "migrate:prod": "prisma migrate deploy", + "db:seed": "ts-node prisma/seed/index.ts" }, "dependencies": { "@maptiler/geocoder": "^1.1.0", "@next-auth/prisma-adapter": "^0.5.2-next.19", "@prisma/client": "^3.6.0", "@types/react": "^17.0.27", - "argon2": "^0.28.3", + "argon2": "^0.28.5", "axios": "^0.24.0", "babel-plugin-superjson-next": "^0.4.2", "next": "^12.0.7", @@ -44,7 +47,7 @@ "@types/supertest": "^2.0.11", "@typescript-eslint/eslint-plugin": "^4.33.0", "@typescript-eslint/parser": "^4.33.0", - "babel-jest": "^27.2.3", + "babel-jest": "^27.5.1", "dotenv": "^14.3.2", "eslint": "^7.32.0", "eslint-config-next": "11.1.2", diff --git a/prisma/seed/index.ts b/prisma/seed/index.ts index 4c9bf63..260a5e1 100644 --- a/prisma/seed/index.ts +++ b/prisma/seed/index.ts @@ -1,9 +1,9 @@ -import { PrismaClient, Puzzle, PuzzleType } from '@prisma/client'; +import { PrismaClient, Difficulty } from '@prisma/client'; +import type { Puzzle, PuzzleType } from '@prisma/client'; const prisma = new PrismaClient(); import seedData from './seed.json'; -import type { DIFFICULTY } from '../../src/types/global'; const createPuzzleType = () => { const puzzleTypes = seedData.puzzleType; @@ -18,7 +18,7 @@ const createPuzzleType = () => { ); }; -const difficulties: DIFFICULTY[] = ['EASY', 'MEDIUM', 'HARD']; +const difficulties: Difficulty[] = Object.values(Difficulty); const createPuzzle = (createdPuzzleTypes: PuzzleType[]) => { const puzzles = seedData.puzzle; @@ -41,7 +41,7 @@ const createPuzzle = (createdPuzzleTypes: PuzzleType[]) => { id: puzzleType.id } }, - difficulty: puzzle.difficulty as DIFFICULTY, + difficulty: puzzle.difficulty as Difficulty, content: puzzle.content, variables: puzzle.variables, question: puzzle.question, @@ -68,7 +68,7 @@ const createPuzzleInstance = (createdPuzzles: Puzzle[]) => { hint: puzzleInstance.hint, longitude: parseFloat(puzzleInstance.longtitude), latitude: parseFloat(puzzleInstance.latitude), - address: puzzleInstance.address, + address: puzzleInstance.address } }); }); diff --git a/src/__mocks__/pages/api/auth/index.ts b/src/__mocks__/pages/api/auth/index.ts index cee877a..dfb828f 100644 --- a/src/__mocks__/pages/api/auth/index.ts +++ b/src/__mocks__/pages/api/auth/index.ts @@ -1,4 +1,4 @@ -import { User } from '@prisma/client'; +import type { User } from '@prisma/client'; import * as faker from 'faker'; import { prisma } from '../../..'; diff --git a/src/__mocks__/pages/api/puzzles/index.ts b/src/__mocks__/pages/api/puzzles/index.ts index 923e091..237ec38 100644 --- a/src/__mocks__/pages/api/puzzles/index.ts +++ b/src/__mocks__/pages/api/puzzles/index.ts @@ -1,4 +1,4 @@ -import { Puzzle, PuzzleInstance, PuzzleType } from '@prisma/client'; +import type { Puzzle, PuzzleInstance, PuzzleType } from '@prisma/client'; import { prisma } from '../../..'; import { diff --git a/src/__mocks__/pages/api/puzzles/instances/create.ts b/src/__mocks__/pages/api/puzzles/instances/create.ts index 083948d..c72771b 100644 --- a/src/__mocks__/pages/api/puzzles/instances/create.ts +++ b/src/__mocks__/pages/api/puzzles/instances/create.ts @@ -1,9 +1,8 @@ import * as faker from 'faker'; -import { DIFFICULTY } from '../../../../../types/global'; +import { Difficulty } from '@prisma/client'; import { getRandomNumberRange, getRandomString } from '../../../../getRandom'; -// TODO: Ensure this list matches DB's configuration -const DIFFICULTY_LIST = ['EASY', 'MEDIUM', 'HARD']; +const DIFFICULTY_LIST = Object.values(Difficulty); export const mockName = (): string => { return faker.random.word() + faker.random.word() + faker.random.word(); @@ -13,10 +12,10 @@ export const mockContent = (): string => { return faker.lorem.paragraph(); }; -export const mockDifficulty = (): DIFFICULTY => { +export const mockDifficulty = (): Difficulty => { return DIFFICULTY_LIST[ Math.floor(Math.random() * DIFFICULTY_LIST.length) - ] as DIFFICULTY; + ] as Difficulty; }; export const mockOfficialAnswer = (): string => { diff --git a/src/__tests__/pages/api/user/update-username.test.ts b/src/__tests__/pages/api/user/update-username.test.ts index 04fd81d..7c5ed44 100644 --- a/src/__tests__/pages/api/user/update-username.test.ts +++ b/src/__tests__/pages/api/user/update-username.test.ts @@ -1,5 +1,5 @@ import { NextApiRequest, NextApiResponse } from 'next'; -import { User } from '@prisma/client'; +import type { User } from '@prisma/client'; import { mockEmail, mockPassword, diff --git a/src/__tests__/utils/error.test.ts b/src/__tests__/utils/error.test.ts index 271f7eb..b6fb2f1 100644 --- a/src/__tests__/utils/error.test.ts +++ b/src/__tests__/utils/error.test.ts @@ -1,5 +1,5 @@ import { handleServiceError } from '../../utils/error'; -import { HandledError } from '../../types/error'; +import type { HandledError } from '../../types/error'; describe('HTTP response status', () => { it('is 400', () => { diff --git a/src/components/App/CardGrid/index.tsx b/src/components/App/CardGrid/index.tsx index b9da8fb..960774e 100644 --- a/src/components/App/CardGrid/index.tsx +++ b/src/components/App/CardGrid/index.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import { PuzzleCard } from '../../Global'; import styles from './CardGrid.module.scss'; -import { CardProps } from '../../../types/cards'; +import type { CardProps } from '../../../types/cards'; const CardGrid = ({ cardList }: { cardList: CardProps[] }) => { return ( diff --git a/src/components/App/DisplayPuzzleInstances/index.tsx b/src/components/App/DisplayPuzzleInstances/index.tsx index bbae03d..630cc32 100644 --- a/src/components/App/DisplayPuzzleInstances/index.tsx +++ b/src/components/App/DisplayPuzzleInstances/index.tsx @@ -1,13 +1,14 @@ import * as React from 'react'; import { useState, useEffect } from 'react'; import styles from './DisplayPuzzleInstances.module.scss'; -import { PuzzleCustom } from '../../../types/api/puzzles/puzzle'; +import type { PuzzleCustom } from '../../../types/api/puzzles/puzzle'; import { getAllPuzzleInstances } from '../../../services'; -import { PuzzleInstance } from '@prisma/client'; +import type { PuzzleInstance } from '@prisma/client'; import { Button } from '../../Global'; import { QRGenerator } from '../../App'; import toast from 'react-hot-toast'; import { getLinkToPuzzleInstance } from '../../../utils/getLinkToPuzzleInstance'; +import Router from 'next/router'; type DisplayPuzzleInstancesProps = { puzzlesList: PuzzleCustom[]; @@ -26,6 +27,11 @@ const DisplayPuzzleInstances = ({ setAllPuzzleInstances(await getAllPuzzleInstances()); }; + const handleRedirectToPuzzlePage = (puzzleInstanceId) => { + const linkToPuzzlePage = getLinkToPuzzleInstance(puzzleInstanceId); + Router.push(linkToPuzzlePage); + } + useEffect(() => { getPuzzleInstances(); }, [puzzlesList]); @@ -99,7 +105,7 @@ const DisplayPuzzleInstances = ({ />
-