From dbdc6db7bc6136392443bd31145d4d393f93bb61 Mon Sep 17 00:00:00 2001 From: yungblud Date: Tue, 23 Jan 2024 12:18:59 +0900 Subject: [PATCH 1/2] feat: migrated --- package.json | 7 +- .../.vscode/settings.json | 4 + .../.vscode/settings.json | 4 + packages/billets-server/.eslintrc.json | 46 +++++++ packages/billets-server/.gitignore | 6 + packages/billets-server/.prettierrc.json | 6 + packages/billets-server/commitlint.config.cjs | 1 + packages/billets-server/package.json | 51 ++++++++ .../billets-server/src/lib/encryptPassword.ts | 27 ++++ packages/billets-server/src/lib/jwt.ts | 25 ++++ packages/billets-server/src/lib/types.ts | 5 + packages/billets-server/src/prisma/connect.ts | 11 ++ packages/billets-server/src/routes/auth.ts | 27 ++++ .../billets-server/src/routes/authHandlers.ts | 49 +++++++ packages/billets-server/src/routes/concert.ts | 29 +++++ .../src/routes/concertHandlers.ts | 123 ++++++++++++++++++ packages/billets-server/src/routes/user.ts | 25 ++++ .../billets-server/src/routes/userHandler.ts | 30 +++++ packages/billets-server/tsconfig.json | 105 +++++++++++++++ .../billets-server/vercel/api/serverless.ts | 55 ++++++++ packages/billets-server/vercel/vercel.json | 8 ++ yarn.lock | 35 +++-- 22 files changed, 668 insertions(+), 11 deletions(-) create mode 100644 packages/billets-admin-client/.vscode/settings.json create mode 100644 packages/billets-admin-server/.vscode/settings.json create mode 100644 packages/billets-server/.eslintrc.json create mode 100644 packages/billets-server/.gitignore create mode 100644 packages/billets-server/.prettierrc.json create mode 100644 packages/billets-server/commitlint.config.cjs create mode 100644 packages/billets-server/package.json create mode 100644 packages/billets-server/src/lib/encryptPassword.ts create mode 100644 packages/billets-server/src/lib/jwt.ts create mode 100644 packages/billets-server/src/lib/types.ts create mode 100644 packages/billets-server/src/prisma/connect.ts create mode 100644 packages/billets-server/src/routes/auth.ts create mode 100644 packages/billets-server/src/routes/authHandlers.ts create mode 100644 packages/billets-server/src/routes/concert.ts create mode 100644 packages/billets-server/src/routes/concertHandlers.ts create mode 100644 packages/billets-server/src/routes/user.ts create mode 100644 packages/billets-server/src/routes/userHandler.ts create mode 100644 packages/billets-server/tsconfig.json create mode 100644 packages/billets-server/vercel/api/serverless.ts create mode 100644 packages/billets-server/vercel/vercel.json diff --git a/package.json b/package.json index f621c37..c9c1d3e 100644 --- a/package.json +++ b/package.json @@ -7,11 +7,14 @@ ], "nohoist": [ "**/billets-admin-server", - "**/billets-admin-server/**" + "**/billets-admin-server/**", + "**/billets-server", + "**/billets-server/**" ] }, "scripts": { - "super-install": "yarn install --immutable --force || yarn install --immutable --force" + "super-install": "yarn install --immutable --force || yarn install --immutable --force", + "super-remove": "rm -rf ./packages/*/node_modules && rm -rf ./node_modules" }, "devDependencies": { "typescript": "^5.3.3" diff --git a/packages/billets-admin-client/.vscode/settings.json b/packages/billets-admin-client/.vscode/settings.json new file mode 100644 index 0000000..d067910 --- /dev/null +++ b/packages/billets-admin-client/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "typescript.tsdk": "node_modules/typescript/lib", + "typescript.enablePromptUseWorkspaceTsdk": true +} \ No newline at end of file diff --git a/packages/billets-admin-server/.vscode/settings.json b/packages/billets-admin-server/.vscode/settings.json new file mode 100644 index 0000000..d067910 --- /dev/null +++ b/packages/billets-admin-server/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "typescript.tsdk": "node_modules/typescript/lib", + "typescript.enablePromptUseWorkspaceTsdk": true +} \ No newline at end of file diff --git a/packages/billets-server/.eslintrc.json b/packages/billets-server/.eslintrc.json new file mode 100644 index 0000000..0cad458 --- /dev/null +++ b/packages/billets-server/.eslintrc.json @@ -0,0 +1,46 @@ +{ + "env": { + "es2021": true, + "node": true + }, + "extends": [ + "airbnb-base", + "prettier" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint", + "prettier" + ], + "rules": { + "prettier/prettier": "error", + "import/extensions": [ + "error", + "ignorePackages", + { + "js": "never", + "jsx": "never", + "ts": "never", + "tsx": "never" + } + ] + }, + "ignorePatterns": [ + "node_modules", + "build", + "dist", + "public", + "gql/resolvers-types.ts" + ], + "settings": { + "import/resolver": { + "node": { + "extensions": [".js", ".ts", ".jsx", ".tsx"] + } + } + } +} diff --git a/packages/billets-server/.gitignore b/packages/billets-server/.gitignore new file mode 100644 index 0000000..30754cb --- /dev/null +++ b/packages/billets-server/.gitignore @@ -0,0 +1,6 @@ +node_modules +.eslintcache +dist +.vercel +.env +src/prisma/schema.prisma \ No newline at end of file diff --git a/packages/billets-server/.prettierrc.json b/packages/billets-server/.prettierrc.json new file mode 100644 index 0000000..99afff2 --- /dev/null +++ b/packages/billets-server/.prettierrc.json @@ -0,0 +1,6 @@ +{ + "trailingComma": "es5", + "tabWidth": 2, + "semi": false, + "singleQuote": true + } diff --git a/packages/billets-server/commitlint.config.cjs b/packages/billets-server/commitlint.config.cjs new file mode 100644 index 0000000..4fedde6 --- /dev/null +++ b/packages/billets-server/commitlint.config.cjs @@ -0,0 +1 @@ +module.exports = { extends: ['@commitlint/config-conventional'] } diff --git a/packages/billets-server/package.json b/packages/billets-server/package.json new file mode 100644 index 0000000..8273679 --- /dev/null +++ b/packages/billets-server/package.json @@ -0,0 +1,51 @@ +{ + "name": "@coldsurfers/billets-server", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "devDependencies": { + "@commitlint/cli": "^17.4.2", + "@commitlint/config-conventional": "^17.4.2", + "@types/crypto-js": "^4.1.1", + "@types/jsonwebtoken": "^9.0.1", + "@typescript-eslint/eslint-plugin": "^5.50.0", + "@typescript-eslint/parser": "^5.50.0", + "eslint": "^7.32.0 || ^8.2.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-prettier": "^8.6.0", + "eslint-plugin-import": "^2.25.2", + "eslint-plugin-prettier": "^4.2.1", + "husky": "^8.0.3", + "lint-staged": "^13.1.0", + "prettier": "2.8.3", + "prisma": "^5.7.1", + "typescript": "^4.9.5" + }, + "dependencies": { + "@prisma/client": "^5.8.0", + "@vercel/node": "^2.9.0", + "crypto-js": "^4.1.1", + "dotenv": "^16.0.3", + "fastify": "^4.12.0", + "jsonwebtoken": "^9.0.0", + "jwt-decode": "^3.1.2" + }, + "scripts": { + "lint": "eslint --cache \"src/**/*.{js,jsx,ts,tsx}\" \"vercel/**/*.{js,jsx,ts,tsx}\"", + "lint:fix": "yarn lint --fix", + "prisma:copy": "cp -r ../../prisma/schema.prisma ./src/prisma/schema.prisma", + "postinstall": "yarn prisma:copy && yarn prisma:generate", + "debug": "vercel dev --listen 3001", + "deploy": "vercel", + "build": "tsc", + "vercel:sync-env": "vercel env pull", + "prisma:db-push": "yarn prisma db push --schema ./src/prisma/schema.prisma", + "prisma:generate": "yarn prisma generate --schema ./src/prisma/schema.prisma" + }, + "lint-staged": { + "*.{js,jsx,ts,tsx}": [ + "yarn run lint:fix", + "bash -c 'yarn build --noEmit'" + ] + } +} diff --git a/packages/billets-server/src/lib/encryptPassword.ts b/packages/billets-server/src/lib/encryptPassword.ts new file mode 100644 index 0000000..4da01d1 --- /dev/null +++ b/packages/billets-server/src/lib/encryptPassword.ts @@ -0,0 +1,27 @@ +import CryptoJS from 'crypto-js' + +const encryptPassword = ({ + plain, + originalSalt, +}: { + plain: string + originalSalt?: string +}) => { + const salt = + originalSalt || + CryptoJS.lib.WordArray.random(128 / 8).toString(CryptoJS.enc.Hex) + + const iterations = 10000 + + const key = CryptoJS.PBKDF2(plain, CryptoJS.enc.Hex.parse(salt), { + keySize: 512 / 32, + iterations, + }) + + return { + encrypted: key.toString(CryptoJS.enc.Base64), + salt, + } +} + +export default encryptPassword diff --git a/packages/billets-server/src/lib/jwt.ts b/packages/billets-server/src/lib/jwt.ts new file mode 100644 index 0000000..22950b2 --- /dev/null +++ b/packages/billets-server/src/lib/jwt.ts @@ -0,0 +1,25 @@ +import jwt from 'jsonwebtoken' +import dotenv from 'dotenv' +import jwtDecode from 'jwt-decode' +import { FstvlLifeJwtPayload } from './types' + +dotenv.config() + +const { JWT_SECRET: secret } = process.env + +/* eslint-disable import/prefer-default-export */ +export function generateToken(payload: FstvlLifeJwtPayload) { + if (!secret) { + throw new Error('no secret') + } + return jwt.sign(payload, secret) +} + +export function decodeToken(token: string) { + try { + const decoded = jwtDecode(token) + return decoded + } catch (e) { + return null + } +} diff --git a/packages/billets-server/src/lib/types.ts b/packages/billets-server/src/lib/types.ts new file mode 100644 index 0000000..0ab3858 --- /dev/null +++ b/packages/billets-server/src/lib/types.ts @@ -0,0 +1,5 @@ +import { JwtPayload } from 'jwt-decode' + +export interface FstvlLifeJwtPayload extends JwtPayload { + id: number +} diff --git a/packages/billets-server/src/prisma/connect.ts b/packages/billets-server/src/prisma/connect.ts new file mode 100644 index 0000000..7b71924 --- /dev/null +++ b/packages/billets-server/src/prisma/connect.ts @@ -0,0 +1,11 @@ +import { PrismaClient } from '@prisma/client' + +export const prisma = new PrismaClient() + +export async function connect() { + await prisma.$connect() +} + +export async function disconnect() { + await prisma.$disconnect() +} diff --git a/packages/billets-server/src/routes/auth.ts b/packages/billets-server/src/routes/auth.ts new file mode 100644 index 0000000..250df8a --- /dev/null +++ b/packages/billets-server/src/routes/auth.ts @@ -0,0 +1,27 @@ +import { FastifyPluginCallback } from 'fastify' +import { signinHandler, signupHandler } from './authHandlers' + +const authRoute: FastifyPluginCallback = (fastify, opts, done) => { + fastify.post( + '/signin', + { + preHandler: async (req, rep, next) => { + if (!req.body) { + return rep.status(400).send({}) + } + const { email, password } = req.body + if (!email || !password) { + return rep.status(400).send({}) + } + return next() + }, + }, + signinHandler + ) + + fastify.post('/signup', signupHandler) + + done() +} + +export default authRoute diff --git a/packages/billets-server/src/routes/authHandlers.ts b/packages/billets-server/src/routes/authHandlers.ts new file mode 100644 index 0000000..d910cd1 --- /dev/null +++ b/packages/billets-server/src/routes/authHandlers.ts @@ -0,0 +1,49 @@ +import { RouteHandler } from 'fastify' +import encryptPassword from '../lib/encryptPassword' +import { generateToken } from '../lib/jwt' +import { prisma } from '../prisma/connect' + +export const signinHandler: RouteHandler<{ + Body: { + email: string + password: string + } +}> = async (req, rep) => { + const { email, password } = req.body + + try { + const existing = await prisma.user.findUnique({ + where: { + email, + }, + }) + if (!existing) { + return rep.status(404).send({}) + } + const { encrypted } = encryptPassword({ + plain: password, + originalSalt: existing.passwordSalt, + }) + if (encrypted !== existing.password) { + return rep.status(401).send({}) + } + const token = generateToken({ + id: existing.id, + }) + return { + user: { + id: existing.id, + email: existing.email, + createdAt: existing.createdAt.toISOString(), + }, + token, + } + } catch (e) { + console.error(e) + return rep.status(500).send({}) + } +} + +export const signupHandler: RouteHandler<{ + Body: { email: string; password: string; passwordConfirm: string } +}> = async () => {} diff --git a/packages/billets-server/src/routes/concert.ts b/packages/billets-server/src/routes/concert.ts new file mode 100644 index 0000000..465d9d8 --- /dev/null +++ b/packages/billets-server/src/routes/concert.ts @@ -0,0 +1,29 @@ +import { FastifyPluginCallback } from 'fastify' +import { + concertCategoryList, + concertHandler, + concertListHandler, + concertRecentListHandler, + concertSearchHandler, +} from './concertHandlers' + +const concertRoute: FastifyPluginCallback = (fastify, opts, done) => { + // concert list + fastify.get('/', concertListHandler) + + // concert recent list + fastify.get('/recent', concertRecentListHandler) + + // concert + fastify.get('/:id', concertHandler) + + // concert category list + fastify.get('/category', concertCategoryList) + + // concert search + fastify.get('/search', concertSearchHandler) + + done() +} + +export default concertRoute diff --git a/packages/billets-server/src/routes/concertHandlers.ts b/packages/billets-server/src/routes/concertHandlers.ts new file mode 100644 index 0000000..ab0ae27 --- /dev/null +++ b/packages/billets-server/src/routes/concertHandlers.ts @@ -0,0 +1,123 @@ +/* eslint-disable import/prefer-default-export */ +import { RouteHandler } from 'fastify' +import { prisma } from '../prisma/connect' + +export const concertListHandler: RouteHandler<{ + Querystring: { offset: string; categoryId?: string; size: string } +}> = async (req, rep) => { + const { offset, categoryId, size } = req.query + try { + const list = await prisma.concert.findMany({ + where: { + concertCategoryId: categoryId ? +categoryId : undefined, + }, + orderBy: { + createdAt: 'desc', + }, + take: +size, + skip: +offset, + include: { + concertCategory: true, + posters: true, + tickets: { + include: { + ticketPrices: true, + }, + }, + }, + }) + + return list + } catch (e) { + return rep.status(500).send({}) + } +} + +export const concertRecentListHandler: RouteHandler = async (req, rep) => { + try { + const recentList = await prisma.concertCategory.findMany({ + select: { + concerts: { + take: 10, + orderBy: { createdAt: 'desc' }, + include: { + concertCategory: true, + posters: true, + tickets: { + include: { + ticketPrices: true, + }, + }, + }, + }, + id: true, + title: true, + }, + orderBy: { + id: 'asc', + }, + }) + return rep.status(200).send(recentList) + } catch (e) { + return rep.status(500).send({}) + } +} + +export const concertHandler: RouteHandler<{ Params: { id: string } }> = async ( + req, + rep +) => { + const { id } = req.params + + try { + const concert = await prisma.concert.findUnique({ + where: { + id: +id, + }, + include: { + concertCategory: true, + posters: true, + tickets: { + include: { + ticketPrices: true, + }, + }, + }, + }) + return concert + } catch (e) { + return rep.status(500).send({}) + } +} + +export const concertCategoryList: RouteHandler = async (req, rep) => { + try { + const list = await prisma.concertCategory.findMany({}) + return list + } catch (e) { + return rep.status(500).send({}) + } +} + +export const concertSearchHandler: RouteHandler<{ + Querystring: { keyword: string; offset: string; size: string } +}> = async (req, rep) => { + const { keyword, offset, size } = req.query + try { + const list = await prisma.concert.findMany({ + where: { + title: { + contains: keyword, + }, + }, + orderBy: { + createdAt: 'desc', + }, + skip: +offset, + take: +size, + }) + return list + } catch (e) { + return rep.status(500).send({}) + } +} diff --git a/packages/billets-server/src/routes/user.ts b/packages/billets-server/src/routes/user.ts new file mode 100644 index 0000000..1a080ce --- /dev/null +++ b/packages/billets-server/src/routes/user.ts @@ -0,0 +1,25 @@ +import { FastifyPluginCallback } from 'fastify' +import { decodeToken } from '../lib/jwt' +import { userHandler } from './userHandler' + +const userRoute: FastifyPluginCallback = (fastify, opts, done) => { + fastify.get( + '/me', + { + preHandler: async (req, rep, next) => { + if (!req.headers.authorization) { + return rep.status(401).send({}) + } + const decoded = decodeToken(req.headers.authorization) + if (!decoded) { + return rep.status(401).send({}) + } + return next() + }, + }, + userHandler + ) + done() +} + +export default userRoute diff --git a/packages/billets-server/src/routes/userHandler.ts b/packages/billets-server/src/routes/userHandler.ts new file mode 100644 index 0000000..48972fd --- /dev/null +++ b/packages/billets-server/src/routes/userHandler.ts @@ -0,0 +1,30 @@ +import { RouteHandler } from 'fastify' +import { decodeToken } from '../lib/jwt' +import { prisma } from '../prisma/connect' + +// eslint-disable-next-line import/prefer-default-export +export const userHandler: RouteHandler = async (req, rep) => { + try { + const decoded = decodeToken(req.headers.authorization ?? '') + if (!decoded) { + return rep.status(401).send({}) + } + + const user = await prisma.user.findUnique({ + where: { + id: decoded.id, + }, + select: { + email: true, + id: true, + createdAt: true, + }, + }) + if (!user) { + return rep.status(404).send({}) + } + return user + } catch (e) { + return rep.status(500).send({}) + } +} diff --git a/packages/billets-server/tsconfig.json b/packages/billets-server/tsconfig.json new file mode 100644 index 0000000..bc35a61 --- /dev/null +++ b/packages/billets-server/tsconfig.json @@ -0,0 +1,105 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./dist", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "include": ["vercel/**/*.ts", "src/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/packages/billets-server/vercel/api/serverless.ts b/packages/billets-server/vercel/api/serverless.ts new file mode 100644 index 0000000..7b5a08b --- /dev/null +++ b/packages/billets-server/vercel/api/serverless.ts @@ -0,0 +1,55 @@ +import dotenv from 'dotenv' +import Fastify from 'fastify' +import { VercelApiHandler, VercelRequest, VercelResponse } from '@vercel/node' +import authRoute from '../../src/routes/auth' +import concertRoute from '../../src/routes/concert' +import userRoute from '../../src/routes/user' + +dotenv.config() + +const fastify = Fastify({ + logger: process.env.NODE_ENV === 'development', +}) + +fastify.register(authRoute, { prefix: '/api/auth' }) +fastify.register(userRoute, { prefix: 'api/user' }) +fastify.register(concertRoute, { prefix: '/api/concert' }) + +const handler: VercelApiHandler = async ( + req: VercelRequest, + res: VercelResponse +) => { + res.setHeader('Access-Control-Allow-Credentials', 'true') + if (process.env.NODE_ENV === 'development') { + res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000') + } else { + // todo: add white list url of cors + // res.setHeader( + // 'Access-Control-Allow-Origin', + // 'https://fstvllife-admin-web-yungblud.vercel.app' + // ) + // res.setHeader( + // 'Access-Control-Allow-Origin', + // 'https://fstvllife-admin-web.vercel.app' + // ) + } + // another common pattern + // res.setHeader('Access-Control-Allow-Origin', req.headers.origin); + res.setHeader( + 'Access-Control-Allow-Methods', + 'GET,OPTIONS,PATCH,DELETE,POST,PUT' + ) + res.setHeader( + 'Access-Control-Allow-Headers', + 'Authorization, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version' + ) + if (req.method === 'OPTIONS') { + res.status(200).end() + return + } + + await fastify.ready() + fastify.server.emit('request', req, res) +} + +export default handler diff --git a/packages/billets-server/vercel/vercel.json b/packages/billets-server/vercel/vercel.json new file mode 100644 index 0000000..7127715 --- /dev/null +++ b/packages/billets-server/vercel/vercel.json @@ -0,0 +1,8 @@ +{ + "rewrites": [ + { + "source": "/(.*)", + "destination": "/api/serverless.ts" + } + ] +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 03d8004..9bbbed0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2576,7 +2576,7 @@ resolved "https://npm.pkg.github.com/download/@coldsurfers/shared-utils/1.0.0/45a4e1f48ef1ab29c228aee99f266976cc2094ac" integrity sha512-IGcQP3ILFaRBqFxUUlGfPOew6ScnHJjG5yNgfzm5CPcSYR/ggk/KMVJhrI3kUxy6DVnwqlufjD78OrdPyycoaQ== -"@commitlint/cli@^17.3.0": +"@commitlint/cli@^17.3.0", "@commitlint/cli@^17.4.2": version "17.8.1" resolved "https://registry.npmjs.org/@commitlint/cli/-/cli-17.8.1.tgz" integrity sha512-ay+WbzQesE0Rv4EQKfNbSMiJJ12KdKTDzIt0tcK4k11FdsWmtwP0Kp1NWMOUswfIWo6Eb7p7Ln721Nx9FLNBjg== @@ -2592,7 +2592,7 @@ resolve-global "1.0.0" yargs "^17.0.0" -"@commitlint/config-conventional@^17.3.0": +"@commitlint/config-conventional@^17.3.0", "@commitlint/config-conventional@^17.4.2": version "17.8.1" resolved "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-17.8.1.tgz" integrity sha512-NxCOHx1kgneig3VLauWJcDWS40DVjg7nKOpBEEK9E5fjJpQqLCilcnKkIIjdBH98kEO1q3NpE5NSrZ2kl/QGJg== @@ -4361,6 +4361,11 @@ resolved "https://registry.npmjs.org/@prisma/client/-/client-5.8.0.tgz" integrity sha512-QxO6C4MaA/ysTIbC+EcAH1aX/YkpymhXtO6zPdk+FvA7+59tNibIYpd+7koPdViLg2iKES4ojsxWNUGNJaEcbA== +"@prisma/client@^5.8.0": + version "5.8.1" + resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.8.1.tgz#7815ec51c0ca2a6de219c02e7846701ae3baf240" + integrity sha512-xQtMPfbIwLlbm0VVIVQY2yqQVOxPwRQhvIp7Z3m2900g1bu/zRHKhYZJQWELqmjl6d8YwBy0K2NvMqh47v1ubw== + "@prisma/debug@5.8.0": version "5.8.0" resolved "https://registry.npmjs.org/@prisma/debug/-/debug-5.8.0.tgz" @@ -5946,6 +5951,13 @@ resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/jsonwebtoken@^9.0.1": + version "9.0.5" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz#0bd9b841c9e6c5a937c17656e2368f65da025588" + integrity sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA== + dependencies: + "@types/node" "*" + "@types/long@^4.0.0": version "4.0.2" resolved "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz" @@ -6235,7 +6247,7 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^5.21.0", "@typescript-eslint/eslint-plugin@^5.47.0", "@typescript-eslint/eslint-plugin@^5.53.0", "@typescript-eslint/eslint-plugin@^5.62.0": +"@typescript-eslint/eslint-plugin@^5.21.0", "@typescript-eslint/eslint-plugin@^5.47.0", "@typescript-eslint/eslint-plugin@^5.50.0", "@typescript-eslint/eslint-plugin@^5.53.0", "@typescript-eslint/eslint-plugin@^5.62.0": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz" integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== @@ -6261,7 +6273,7 @@ "@typescript-eslint/typescript-estree" "5.10.1" debug "^4.3.2" -"@typescript-eslint/parser@^5.0.0", "@typescript-eslint/parser@^5.21.0", "@typescript-eslint/parser@^5.42.0", "@typescript-eslint/parser@^5.47.0", "@typescript-eslint/parser@^5.53.0", "@typescript-eslint/parser@^5.62.0": +"@typescript-eslint/parser@^5.0.0", "@typescript-eslint/parser@^5.21.0", "@typescript-eslint/parser@^5.42.0", "@typescript-eslint/parser@^5.47.0", "@typescript-eslint/parser@^5.50.0", "@typescript-eslint/parser@^5.53.0", "@typescript-eslint/parser@^5.62.0": version "5.62.0" resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz" integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== @@ -6424,7 +6436,7 @@ resolved "https://registry.npmjs.org/@vercel/error-utils/-/error-utils-1.0.10.tgz" integrity sha512-nsKy2sy+pjUWyKI1V/XXKspVzHMYgSalmj5+EsKWFXZbnNZicqxNtMR94J8Hs7SB4TQxh0s4KhczJtL59AVGMg== -"@vercel/node@^2.8.2": +"@vercel/node@^2.8.2", "@vercel/node@^2.9.0": version "2.15.10" resolved "https://registry.npmjs.org/@vercel/node/-/node-2.15.10.tgz" integrity sha512-IfnqnKAJlL1+0FSDJgxoe9J3kfYAgPGDjz4aO/H5FSjvqP7cKJnns1F9GsQq4pM499+TY8T8mKAdos7/m+WOEw== @@ -8877,7 +8889,7 @@ eslint-config-next@^13.4.16: eslint-plugin-react "^7.33.2" eslint-plugin-react-hooks "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" -eslint-config-prettier@^8.10.0, eslint-config-prettier@^8.5.0: +eslint-config-prettier@^8.10.0, eslint-config-prettier@^8.5.0, eslint-config-prettier@^8.6.0: version "8.10.0" resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz" integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg== @@ -9581,7 +9593,7 @@ fastify-plugin@^4.0.0, fastify-plugin@^4.4.0: resolved "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-4.5.1.tgz" integrity sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ== -fastify@^4.10.2, fastify@^4.24.3, fastify@^4.25.2: +fastify@^4.10.2, fastify@^4.12.0, fastify@^4.24.3, fastify@^4.25.2: version "4.25.2" resolved "https://registry.npmjs.org/fastify/-/fastify-4.25.2.tgz" integrity sha512-SywRouGleDHvRh054onj+lEZnbC1sBCLkR0UY3oyJwjD4BdZJUrxBqfkfCaqn74pVCwBaRHGuL3nEWeHbHzAfw== @@ -10496,7 +10508,7 @@ human-signals@^5.0.0: resolved "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz" integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== -husky@^8.0.2: +husky@^8.0.2, husky@^8.0.3: version "8.0.3" resolved "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz" integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg== @@ -13587,6 +13599,11 @@ prettier@2.8.1, prettier@^2.8.1: resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz" integrity sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg== +prettier@2.8.3: + version "2.8.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.3.tgz#ab697b1d3dd46fb4626fbe2f543afe0cc98d8632" + integrity sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw== + pretty-bytes@5.6.0: version "5.6.0" resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz" @@ -15650,7 +15667,7 @@ typescript@4.6.3: resolved "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz" integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== -typescript@4.9.5, typescript@^4.8.3, typescript@^4.9.4: +typescript@4.9.5, typescript@^4.8.3, typescript@^4.9.4, typescript@^4.9.5: version "4.9.5" resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== From 682d18ec609bb8ff3bf94e101df6a409c9c27a5d Mon Sep 17 00:00:00 2001 From: yungblud Date: Tue, 23 Jan 2024 13:35:34 +0900 Subject: [PATCH 2/2] feat: modified schema.prisma for bilnaryTargets --- prisma/schema.prisma | 1 + 1 file changed, 1 insertion(+) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index d41b93a..63b989a 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -3,6 +3,7 @@ generator client { provider = "prisma-client-js" + binaryTargets = ["native", "darwin-arm64", "rhel-openssl-1.0.x"] } datasource db {