diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz index 103a2bb..46246eb 100644 Binary files a/.yarn/install-state.gz and b/.yarn/install-state.gz differ diff --git a/README.md b/README.md index d8e6087..d1f864d 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ comes with a LSP for Vim users. Run `npx nx serve be` to start the development server. Happy coding! -## Build for production +## Build for **production** Run `npx nx build be` to build the application. The build artifacts are stored in the output directory (e.g. `dist/` or `build/`), ready to be deployed. diff --git a/apps/be/.env.example b/apps/be/.env.example index 117c8ee..08a4d0d 100644 --- a/apps/be/.env.example +++ b/apps/be/.env.example @@ -1,11 +1,33 @@ +# REQUIRED to can get task an excecute it + +NODE_ENV= #production, dev +DEPLOY_ENV= #serverless - when deploy to serverless platform, otherwise let it empty + MONGODB_URI= +REDIS_HOST='localhost' +REDIS_PORT='6379' +REDIS_PASSWORD= +REDIS_CONNECT_TIMEOUT=5000 +# END REQUIRED + +# OPTIONAL + +BULL_TASK_CONCURRENCY=20 +BULL_BACKGROUND_CONCURRENCY=10 +BULL_SAVE_LOG_CONCURRENCY=10 +MAX_LOGS_PER_TASK=10 + +# END OPTIONAL + FALLBACK_LANGUAGE='en' API_STATS_PATH='/stats' API_STATS_USERNAME='stats' API_STATS_PASSWORD='stats' +# Set below to your server can be used auth service + AUTH_JWT_TOKEN_EXPIRES_IN=5m AUTH_JWT_SECRET='supersecretkeyyoushouldnotcommittogithub' @@ -18,11 +40,6 @@ AUTH_PASSWORDLESS_SECRET='supersecretkeyyoushouldnotcommittogithub_pwless' AUTH_CONFIRM_EMAIL_TOKEN_EXPIRES_IN=15m AUTH_CONFIRM_EMAIL_SECRET='supersecretkeyyoushouldnotcommittogithub_confirmEmail' -BULL_TASK_CONCURRENCY=20 -BULL_BACKGROUND_CONCURRENCY=10 -BULL_SAVE_LOG_CONCURRENCY=10 -MAX_LOG_PER_TASK=10 - ### EMAIL ### MAIL_SENDER='TaskTr noreply ' # your mail sender, All services below will use this mail sender @@ -40,9 +57,4 @@ GMAIL_PASSWORD='' RESEND_HOST='smtp.resend.com' RESEND_USER='resend' RESEND_API_KEY= -### EMAIL ### - -REDIS_HOST='localhost' -REDIS_PORT='6379' -REDIS_PASSWORD= -REDIS_CONNECT_TIMEOUT=5000 \ No newline at end of file +### EMAIL ### \ No newline at end of file diff --git a/apps/be/common/src/i18n/i18n.module.ts b/apps/be/common/src/i18n/i18n.module.ts index e237be6..f7ed214 100644 --- a/apps/be/common/src/i18n/i18n.module.ts +++ b/apps/be/common/src/i18n/i18n.module.ts @@ -12,12 +12,20 @@ import { ConfigService } from '@nestjs/config'; imports: [ I18nModuleCore.forRootAsync({ useFactory: (configService: ConfigService) => ({ - fallbackLanguage: configService.getOrThrow('FALLBACK_LANGUAGE'), + fallbackLanguage: configService.get('FALLBACK_LANGUAGE') || 'en', loaderOptions: { - path: join(__dirname, './assets/i18n/lang/'), + path: join( + __dirname, + configService.get('DEPLOY_ENV')?.toLowerCase() === 'serverless' + ? './lang/' + : './assets/i18n/lang/', + ), watch: true, }, - typesOutputPath: join(process.cwd(), `./apps/be/common/src/i18n/i18n.generated.ts`), + typesOutputPath: + configService.get('DEPLOY_ENV')?.toLowerCase() === 'serverless' + ? undefined + : join(process.cwd(), `./apps/be/common/src/i18n/i18n.generated.ts`), }), resolvers: [ new HeaderResolver(['x-lang', 'x-language', 'language']), diff --git a/apps/be/common/src/index.ts b/apps/be/common/src/index.ts index 1135413..2c769ae 100644 --- a/apps/be/common/src/index.ts +++ b/apps/be/common/src/index.ts @@ -1,3 +1,5 @@ +export * from './axios'; +export * from './bullmq'; export * from './i18n'; export * from './mail'; export * from './mongodb'; diff --git a/apps/be/src/app/auth/index.ts b/apps/be/src/app/auth/index.ts new file mode 100644 index 0000000..2c9172b --- /dev/null +++ b/apps/be/src/app/auth/index.ts @@ -0,0 +1,5 @@ +export * from './dtos'; +export * from './guards'; +export * from './strategies'; +export * from './auth.module'; +export * from './auth.service'; diff --git a/apps/be/src/app/index.ts b/apps/be/src/app/index.ts new file mode 100644 index 0000000..4e44087 --- /dev/null +++ b/apps/be/src/app/index.ts @@ -0,0 +1,5 @@ +export * from './auth'; +export * from './task-logs'; +export * from './tasks'; +export * from './users'; +export * from './app.module'; diff --git a/apps/be/src/app/tasks/index.ts b/apps/be/src/app/tasks/index.ts index 5356662..fa0cfc6 100644 --- a/apps/be/src/app/tasks/index.ts +++ b/apps/be/src/app/tasks/index.ts @@ -1,2 +1,3 @@ export * from './tasks.module'; export * from './schemas'; +export * from './tasks.module'; diff --git a/package.json b/package.json index bb0211f..4e99816 100644 --- a/package.json +++ b/package.json @@ -130,12 +130,14 @@ "jest": "^29.4.1", "jest-environment-jsdom": "^29.4.1", "jest-environment-node": "^29.4.1", + "module-alias": "^2.2.3", "nx": "19.1.1", "postcss": "8.4.21", "prettier": "^3.2.5", "tailwindcss": "3.4.3", "ts-jest": "^29.1.0", "ts-node": "10.9.1", + "tsconfig-paths": "^4.2.0", "typescript": "~5.4.2", "webpack": "^5.91.0", "webpack-cli": "^5.1.4" diff --git a/serverless/api/index.ts b/serverless/api/index.ts new file mode 100644 index 0000000..1fb3978 --- /dev/null +++ b/serverless/api/index.ts @@ -0,0 +1,42 @@ +/** + * Config for using path-aliases + */ + +const path = require('path'); +const moduleAlias = require('module-alias'); +const tsConfigPaths = require('tsconfig-paths'); +const tsConfig = require('./tsconfig.json'); + +const baseUrl = tsConfig?.compilerOptions?.baseUrl ?? '../'; + +// Register tsconfig-paths, use for TS +tsConfigPaths.register({ + baseUrl: baseUrl, + paths: tsConfig.compilerOptions.paths, + cwd: __dirname, +}); + +// Config for serverless can understand alias +if (tsConfig?.compilerOptions?.paths) { + for (const alias in tsConfig.compilerOptions.paths) { + const paths = tsConfig.compilerOptions.paths[alias]; + if (paths) { + let targetPath = paths[0]; + targetPath = targetPath.replace(/(\/\*|\*|\\*)$/g, ''); + const formattedAlias = alias.replace(/(\/\*|\*|\\*)$/g, ''); + moduleAlias.addAlias(formattedAlias, path.resolve(__dirname, baseUrl, targetPath)); + } + } +} + +/** + * Require the needed modules, that serverless can compile it to JS + * Then the server can be import and run it + */ +require('../../apps/be/common/src/index'); +require('../../apps/be/src/app/index'); + +/** + * Main file to run the server + */ +require('../../apps/be/src/main'); diff --git a/serverless/api/tsconfig.json b/serverless/api/tsconfig.json new file mode 100644 index 0000000..e20fbe0 --- /dev/null +++ b/serverless/api/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "target": "ES2021", + "module": "CommonJS", + "moduleResolution": "Node", + "skipLibCheck": true, + "types": ["node"], + "strictPropertyInitialization": false, + "esModuleInterop": true, + "resolveJsonModule": true, + "baseUrl": "../../", + "paths": { + "~be/app/*": ["apps/be/src/app/*"], + "~be/common/*": ["apps/be/common/src/*"] + } + } +} diff --git a/serverless/vercel.json b/serverless/vercel.json new file mode 100644 index 0000000..5f99498 --- /dev/null +++ b/serverless/vercel.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://openapi.vercel.sh/vercel.json", + "regions": ["sin1"], + "installCommand": "cd ../ && yarn install --immutable", + "buildCommand": "", + "functions": { + "api/**/*.ts": { + "maxDuration": 60 + } + }, + "rewrites": [{ "source": "/(.*)", "destination": "/api" }] +} diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..37f94f3 --- /dev/null +++ b/vercel.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://openapi.vercel.sh/vercel.json", + "framework": "nextjs", + "regions": ["sin1"], + "installCommand": "yarn install --immutable", + "buildCommand": "yarn nx build fe", + "outputDirectory": "dist/apps/fe/.next", + "cleanUrls": true +} diff --git a/yarn.lock b/yarn.lock index 4dcee99..6c9c5d1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4782,6 +4782,7 @@ __metadata: jest-environment-jsdom: "npm:^29.4.1" jest-environment-node: "npm:^29.4.1" js-cookie: "npm:^3.0.5" + module-alias: "npm:^2.2.3" mongoose: "npm:^8.4.1" ms: "npm:^2.1.3" nestjs-i18n: "npm:^10.4.5" @@ -4814,6 +4815,7 @@ __metadata: tailwindcss: "npm:3.4.3" ts-jest: "npm:^29.1.0" ts-node: "npm:10.9.1" + tsconfig-paths: "npm:^4.2.0" tslib: "npm:^2.3.0" typescript: "npm:~5.4.2" uuid: "npm:^9.0.1" @@ -15423,6 +15425,13 @@ __metadata: languageName: node linkType: hard +"module-alias@npm:^2.2.3": + version: 2.2.3 + resolution: "module-alias@npm:2.2.3" + checksum: 10c0/47dc5b6d04f6e7df0ff330ca9b2a37c688a682ed661e9432b0b327e1e6c43eedad052151b8d50d6beea8b924828d2a92fa4625c18d651bf2d93d8f03aa0172fa + languageName: node + linkType: hard + "moment@npm:^2.18.1, moment@npm:^2.29.4": version: 2.30.1 resolution: "moment@npm:2.30.1" @@ -21254,7 +21263,7 @@ __metadata: languageName: node linkType: hard -"tsconfig-paths@npm:^4.0.0, tsconfig-paths@npm:^4.1.2": +"tsconfig-paths@npm:^4.0.0, tsconfig-paths@npm:^4.1.2, tsconfig-paths@npm:^4.2.0": version: 4.2.0 resolution: "tsconfig-paths@npm:4.2.0" dependencies: