diff --git a/.env.example b/.env.example index 535209c..2ac6f1a 100644 --- a/.env.example +++ b/.env.example @@ -2,7 +2,6 @@ HOST=https://example.com PORT=3000 LOCAL=true DRIVE_ROOT_DIR=Health-test -GOOGLE_API_KEY=xxxxxxxxxxxxxxxxxxx SLACK_API_URL=https://slack.com/api SLACK_CLIENT_ID=1234567890123.1234567890123 SLACK_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxx diff --git a/nest-cli.json b/nest-cli.json index f9aa683..febb1ca 100644 --- a/nest-cli.json +++ b/nest-cli.json @@ -3,6 +3,7 @@ "collection": "@nestjs/schematics", "sourceRoot": "src", "compilerOptions": { - "deleteOutDir": true + "deleteOutDir": true, + "assets": ["**/*.njk"] } } diff --git a/package.json b/package.json index ce7385f..82ce0ae 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,12 @@ "@nestjs/common": "^9.0.0", "@nestjs/core": "^9.0.0", "@nestjs/platform-express": "^9.0.0", + "@types/express-fileupload": "^1.4.1", + "@types/moment": "^2.13.0", "axios": "^1.3.6", "dotenv": "^16.0.3", "express-fileupload": "^1.4.0", + "express-serve-static-core": "^0.1.1", "googleapis": "^118.0.0", "googleapis-common": "^6.0.4", "moment": "^2.29.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c6a0cce..52ade23 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,6 +10,12 @@ dependencies: '@nestjs/platform-express': specifier: ^9.0.0 version: 9.0.0(@nestjs/common@9.0.0)(@nestjs/core@9.0.0) + '@types/express-fileupload': + specifier: ^1.4.1 + version: 1.4.1 + '@types/moment': + specifier: ^2.13.0 + version: 2.13.0 axios: specifier: ^1.3.6 version: 1.3.6 @@ -19,6 +25,9 @@ dependencies: express-fileupload: specifier: ^1.4.0 version: 1.4.0 + express-serve-static-core: + specifier: ^0.1.1 + version: 0.1.1 googleapis: specifier: ^118.0.0 version: 118.0.0 @@ -1043,13 +1052,17 @@ packages: dependencies: '@types/connect': 3.4.35 '@types/node': 18.15.11 - dev: true + + /@types/busboy@1.5.0: + resolution: {integrity: sha512-ncOOhwmyFDW76c/Tuvv9MA9VGYUCn8blzyWmzYELcNGDb0WXWLSmFi7hJq25YdRBYJrmMBB5jZZwUjlJe9HCjQ==} + dependencies: + '@types/node': 18.15.11 + dev: false /@types/connect@3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: '@types/node': 18.15.11 - dev: true /@types/cookiejar@2.1.2: resolution: {integrity: sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==} @@ -1077,13 +1090,19 @@ packages: resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} dev: true + /@types/express-fileupload@1.4.1: + resolution: {integrity: sha512-sbl865h1Sser6SF+efpw2F/+roGISj+PRIbMcGXbtzgJQCBAeeBmoSo7sPge/mBa22ymCHfFPtHFsag/wUxwfg==} + dependencies: + '@types/busboy': 1.5.0 + '@types/express': 4.17.13 + dev: false + /@types/express-serve-static-core@4.17.33: resolution: {integrity: sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==} dependencies: '@types/node': 18.15.11 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 - dev: true /@types/express@4.17.13: resolution: {integrity: sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==} @@ -1092,7 +1111,6 @@ packages: '@types/express-serve-static-core': 4.17.33 '@types/qs': 6.9.7 '@types/serve-static': 1.15.1 - dev: true /@types/graceful-fs@4.1.6: resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} @@ -1133,11 +1151,16 @@ packages: /@types/mime@3.0.1: resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==} - dev: true + + /@types/moment@2.13.0: + resolution: {integrity: sha512-DyuyYGpV6r+4Z1bUznLi/Y7HpGn4iQ4IVcGn8zrr1P4KotKLdH0sbK1TFR6RGyX6B+G8u83wCzL+bpawKU/hdQ==} + deprecated: This is a stub types definition for Moment (https://github.com/moment/moment). Moment provides its own type definitions, so you don't need @types/moment installed! + dependencies: + moment: 2.29.4 + dev: false /@types/node@18.15.11: resolution: {integrity: sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==} - dev: true /@types/parse-json@4.0.0: resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} @@ -1149,18 +1172,15 @@ packages: /@types/qs@6.9.7: resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} - dev: true /@types/range-parser@1.2.4: resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} - dev: true /@types/serve-static@1.15.1: resolution: {integrity: sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==} dependencies: '@types/mime': 3.0.1 '@types/node': 18.15.11 - dev: true /@types/stack-utils@2.0.1: resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} @@ -2564,6 +2584,10 @@ packages: busboy: 1.6.0 dev: false + /express-serve-static-core@0.1.1: + resolution: {integrity: sha512-phQFPo1vVwBLOjDq+EspUY6PpWZIs/s62Lvu6QuReViQ9j9ANBnMqPBRwdxs3zxNmpMJ9KBKrmMqCjMwHnGRyQ==} + dev: false + /express@4.18.1: resolution: {integrity: sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==} engines: {node: '>= 0.10.0'} diff --git a/src/app.controller.ts b/src/app.controller.ts index cfd9369..29560e0 100644 --- a/src/app.controller.ts +++ b/src/app.controller.ts @@ -1,5 +1,5 @@ import { Controller, Get, Req, Res } from '@nestjs/common'; -import { Request, Response } from 'express'; +import type { Request, Response } from 'express-serve-static-core'; import { GoogleAuthService } from './modules/authentication/services/googleAuth.service'; @Controller() @@ -14,7 +14,7 @@ export class AppController { } catch (ex) { requiredAuth = true; } - res.render('views/pages/index.njk', { + res.render('pages/index.njk', { authUrl: this.googleAuthService.generateAuthUrl( await this.googleAuthService.getAuthClient(), ), diff --git a/src/common/constants.ts b/src/common/constants.ts index e696c49..f1aae31 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -1,5 +1,4 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -import * as path from 'path'; +import path from 'path'; // @NOTE: If modifying these scopes, delete token.json. export const SCOPES = [ diff --git a/src/main.ts b/src/main.ts index bd69036..1d2db8f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,28 +1,31 @@ /* eslint-disable @typescript-eslint/no-var-requires */ import { NestFactory } from '@nestjs/core'; import { NestExpressApplication } from '@nestjs/platform-express'; -import { join } from 'path'; +import path, { join } from 'path'; import { AppModule } from './app.module'; -import * as dotenv from 'dotenv'; -import * as fs from 'fs'; -import * as os from 'os'; -import * as fileUpload from 'express-fileupload'; -import * as nunjucks from 'nunjucks'; +import dotenv from 'dotenv'; +import fs from 'fs'; +import os from 'os'; +import fileUpload from 'express-fileupload'; +import nunjucks from 'nunjucks'; dotenv.config(); const ROOT_DIR: string = join(__dirname, '..'); +// @TODO: pass proper production flag here const IS_PRODUCTION: boolean = process.env.LOCAL !== 'true'; +const IS_LOCAL: boolean = process.env.LOCAL === 'true'; async function bootstrap() { - const options = { - key: fs.readFileSync(ROOT_DIR + '/localhost-key.pem'), - cert: fs.readFileSync(ROOT_DIR + '/localhost.pem'), - }; - const app: NestExpressApplication = await NestFactory.create(AppModule, { - httpsOptions: options, - }); + const app: NestExpressApplication = IS_LOCAL + ? await NestFactory.create(AppModule, { + httpsOptions: { + key: fs.readFileSync(ROOT_DIR + '/localhost-key.pem'), + cert: fs.readFileSync(ROOT_DIR + '/localhost.pem'), + }, + }) + : await NestFactory.create(AppModule); app.use( fileUpload({ @@ -41,7 +44,7 @@ async function bootstrap() { noCache: !IS_PRODUCTION, }; - nunjucks.configure(join(ROOT_DIR, IS_PRODUCTION ? 'dist' : 'src'), opts); + nunjucks.configure(path.resolve(__dirname, 'views'), opts); app.enableCors(); app.set('trust proxy', 1); @@ -51,4 +54,5 @@ async function bootstrap() { console.log(`server running on ${port}`); }); } + bootstrap(); diff --git a/src/modules/authentication/controllers/auth.controller.ts b/src/modules/authentication/controllers/auth.controller.ts index 196b64b..3bf9a70 100644 --- a/src/modules/authentication/controllers/auth.controller.ts +++ b/src/modules/authentication/controllers/auth.controller.ts @@ -1,5 +1,5 @@ import { Controller, Get, Req, Res } from '@nestjs/common'; -import { Request, Response } from 'express'; +import { Request, Response } from 'express-serve-static-core'; import { GoogleAuthService } from '../services/googleAuth.service'; import { deleteFile } from '../../../services/utils/files.service'; @@ -26,7 +26,7 @@ export class AuthController { @Get('/auth') async goToAuth(@Res() res: Response) { - res.render('views/pages/authenticate/index.njk', { + res.render('pages/authenticate/index.njk', { authUrl: this.googleAuthService.generateAuthUrl( await this.googleAuthService.getAuthClient(), ), diff --git a/src/modules/authentication/services/googleAuth.service.ts b/src/modules/authentication/services/googleAuth.service.ts index 041e2a2..f6b9099 100644 --- a/src/modules/authentication/services/googleAuth.service.ts +++ b/src/modules/authentication/services/googleAuth.service.ts @@ -3,13 +3,13 @@ import { Inject, Injectable } from '@nestjs/common'; import { google } from 'googleapis'; import { OAuth2Client } from 'googleapis-common'; import { deleteFile } from '../../../services/utils/files.service'; -import { Request, Response } from 'express'; +import { Request, Response } from 'express-serve-static-core'; import { CREDENTIALS_PATH, SCOPES } from '../../../common/constants'; -import * as fs from 'fs'; -import * as url from 'url'; -import * as os from 'os'; -import * as path from 'path'; +import fs from 'fs'; +import url from 'url'; +import os from 'os'; +import path from 'path'; @Injectable() export class GoogleAuthService { diff --git a/src/modules/calendar/controllers/calendar.controller.ts b/src/modules/calendar/controllers/calendar.controller.ts index 1d25657..3e3f025 100644 --- a/src/modules/calendar/controllers/calendar.controller.ts +++ b/src/modules/calendar/controllers/calendar.controller.ts @@ -3,7 +3,7 @@ import { TriggersService } from '../services/triggers.service'; import { GoogleAuthService } from '../../authentication/services/googleAuth.service'; import { EventsService } from '../services/events.service'; import { WatchService } from '../services/watch.service'; -import { Request, Response } from 'express'; +import { Request, Response } from 'express-serve-static-core'; @Controller() export class CalendarController { @@ -35,7 +35,7 @@ export class CalendarController { this.watchService.watchCalendarEvents(authClient); - res.render('views/pages/slack/integrate.njk'); + res.render('pages/slack/integrate.njk'); }); } } diff --git a/src/modules/calendar/services/events.service.ts b/src/modules/calendar/services/events.service.ts index 8e84c90..8d450fd 100644 --- a/src/modules/calendar/services/events.service.ts +++ b/src/modules/calendar/services/events.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common'; import { calendar_v3, google } from 'googleapis'; -import * as moment from 'moment'; +import moment from 'moment'; @Injectable() export class EventsService { @@ -14,9 +14,6 @@ export class EventsService { const calendar = google.calendar({ version: 'v3', auth, - params: { - key: process.env.GOOGLE_API_KEY, - }, }); const res = await calendar.events.list({ calendarId: 'primary', diff --git a/src/modules/calendar/services/watch.service.ts b/src/modules/calendar/services/watch.service.ts index 43fd0b8..558c7c7 100644 --- a/src/modules/calendar/services/watch.service.ts +++ b/src/modules/calendar/services/watch.service.ts @@ -12,9 +12,6 @@ export class WatchService { async watchCalendarEvents(auth) { const calendar = google.calendar({ version: 'v3', - params: { - key: process.env.GOOGLE_API_KEY, - }, auth, }); const channel = { @@ -41,9 +38,6 @@ export class WatchService { stopWatchingCalendarEvents(auth) { const calendar = google.calendar({ version: 'v3', - params: { - key: process.env.GOOGLE_API_KEY, - }, auth, }); diff --git a/src/modules/drive/controllers/drive.controller.ts b/src/modules/drive/controllers/drive.controller.ts index 87b6ab2..e71c98d 100644 --- a/src/modules/drive/controllers/drive.controller.ts +++ b/src/modules/drive/controllers/drive.controller.ts @@ -1,6 +1,6 @@ import { Controller, Get, Post, Req, Res } from '@nestjs/common'; import { UploadService } from '../services/upload.service'; -import { Request, Response } from 'express'; +import { Request, Response } from 'express-serve-static-core'; import { GoogleAuthService } from '../../authentication/services/googleAuth.service'; @Controller() @@ -19,7 +19,7 @@ export class DriveController { requiredAuth = true; } - res.render('views/pages/drive/upload.njk', { + res.render('pages/drive/upload.njk', { authUrl: this.googleAuthService.generateAuthUrl( await this.googleAuthService.getAuthClient(), ), diff --git a/src/modules/drive/services/upload.service.ts b/src/modules/drive/services/upload.service.ts index 9c0d32f..9469c80 100644 --- a/src/modules/drive/services/upload.service.ts +++ b/src/modules/drive/services/upload.service.ts @@ -3,8 +3,8 @@ import { Injectable } from '@nestjs/common'; import { google } from 'googleapis'; import { commaSeparatedValues } from '../../../services/utils/strings.service'; -import * as fs from 'fs'; -import * as moment from 'moment'; +import fs from 'fs'; +import moment from 'moment'; @Injectable() export class UploadService { @@ -18,9 +18,6 @@ export class UploadService { const service = google.drive({ version: 'v3', - params: { - key: process.env.GOOGLE_API_KEY, - }, auth: oauth2Client, }); diff --git a/test/app.e2e-spec.ts b/test/app.e2e-spec.ts index 2954f68..8b920c4 100644 --- a/test/app.e2e-spec.ts +++ b/test/app.e2e-spec.ts @@ -3,7 +3,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; import { AppModule } from './../src/app.module'; -import * as request from 'supertest'; +import request from 'supertest'; describe('AppController (e2e)', () => { let app: INestApplication; diff --git a/tsconfig.json b/tsconfig.json index adb614c..ec5d98d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,6 +4,7 @@ "declaration": true, "removeComments": true, "emitDecoratorMetadata": true, + "esModuleInterop": true, "experimentalDecorators": true, "allowSyntheticDefaultImports": true, "target": "es2017", diff --git a/vercel.json b/vercel.json index e8febde..4520498 100644 --- a/vercel.json +++ b/vercel.json @@ -4,6 +4,10 @@ { "src": "src/main.ts", "use": "@vercel/node" + }, + { + "src": "**/*.njk", + "use": "@vercel/static" } ], "routes": [ @@ -12,5 +16,7 @@ "dest": "src/main.ts", "methods": ["GET", "POST", "PUT", "DELETE"] } - ] + ], + "buildCommand": "pnpm run build", + "outputDirectory": "dist" }