diff --git a/.dockerignore b/.dockerignore
deleted file mode 100644
index 72cd8e1..0000000
--- a/.dockerignore
+++ /dev/null
@@ -1,24 +0,0 @@
-**/.classpath
-**/.coverage
-**/.dockerignore
-**/.env
-**/.git
-**/.gitignore
-**/.project
-**/.settings
-**/.toolstarget
-**/.vs
-**/.vscode
-**/*.*proj.user
-**/*.dbmdl
-**/*.jfm
-**/charts
-**/docker-compose*
-**/Dockerfile*
-**/node_modules
-**/npm-debug.log
-**/obj
-**/secrets.dev.yml
-**/values.dev.yml
-LICENSE
-README.md
diff --git a/.eslintrc.json b/.eslintrc.json
index 16b6531..d1597f3 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -2,7 +2,9 @@
"root": true,
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"parser": "@typescript-eslint/parser",
- "parserOptions": { "project": ["./tsconfig.json"] },
+ "parserOptions": {
+ "project": ["./tsconfig.json"]
+ },
"plugins": ["@typescript-eslint"],
"rules": {
"@typescript-eslint/strict-boolean-expressions": [
@@ -27,9 +29,11 @@
"@typescript-eslint/no-explicit-any": "off"
},
"ignorePatterns": [
- "src/**/*.test.ts",
- "public/js/**/*.js",
"coverage/**/*.js",
- "jest.config.ts"
+ "dist/**/*.js",
+ "public/js/**/*.js",
+ "jest.config.ts",
+ // Ignore test files
+ "test/*"
]
}
diff --git a/.gitignore b/.gitignore
index fa3bbac..bfd4297 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
.idea/
coverage/
node_modules/
-out/
+dist/
secrets/
\ No newline at end of file
diff --git a/.prettierrc.json b/.prettierrc.json
index 3923e53..f5b3d30 100644
--- a/.prettierrc.json
+++ b/.prettierrc.json
@@ -6,7 +6,7 @@
"useTabs": false,
"overrides": [
{
- "files": ["*.json", "*.yml"],
+ "files": ["*.json", "*.{yml,yaml}"],
"options": {
"tabWidth": 2
}
diff --git a/Dockerfile b/Dockerfile
index 3b6f17f..a3c7a26 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,15 +6,6 @@ WORKDIR /app
COPY package*.json ./
-RUN npm install && npm cache clean --force
+RUN npm install
-COPY tsconfig.json ./
-COPY nodemon.json ./
-
-COPY ./src ./src
-COPY ./db ./db
-COPY ./public ./public
-COPY ./views ./views
-COPY ./secrets ./secrets
-
-RUN npm run build
+CMD [ "npm", "start" ]
diff --git a/db/data-model.drawio b/db/data-model.drawio
deleted file mode 100644
index ea6798d..0000000
--- a/db/data-model.drawio
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docker-compose.yml b/docker-compose.yml
index 57bf950..53279ab 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,21 +1,20 @@
-version: '3.8'
-
services:
server:
image: daily-dash
restart: always
- build:
- context: .
- dockerfile: Dockerfile
- pull_policy: never
- command: sh -c "npm run migrate && npm start"
ports:
- ${PORT}:443
- ${DEBUG_PORT}:${DEBUG_PORT}
volumes:
- - ./src:/app/src
+ - ./dist:/app/dist
+ - ./nodemon.json:/app/nodemon.json
- ./public:/app/public
- ./views:/app/views
+ - ./secrets:/app/secrets
+ build:
+ context: .
+ dockerfile: Dockerfile
+ pull_policy: never
env_file: ./secrets/.env
depends_on:
db:
@@ -26,35 +25,35 @@ services:
db:
image: postgres:latest
restart: always
+ ports:
+ - ${DB_PORT}:5432
volumes:
- db-data:/var/lib/postgresql/data
+ env_file: ./secrets/.env
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_PASSWORD: ${DB_PASSWORD}
- ports:
- - ${DB_PORT}:5432
healthcheck:
- test: [ 'CMD', 'pg_isready', '-U', '$DB_USERNAME' ]
+ test: ['CMD', 'pg_isready', '-U', '$DB_USERNAME']
interval: 10s
timeout: 5s
retries: 5
- env_file: ./secrets/.env
cache:
image: redis:latest
restart: always
ports:
- ${REDIS_PORT}:6379
- command: redis-server --save 20 1 --loglevel warning --requirepass ${REDIS_PASSWORD}
volumes:
- cache-data:/data
+ env_file: ./secrets/.env
+ command: redis-server --save 20 1 --loglevel warning --requirepass ${REDIS_PASSWORD}
healthcheck:
- test: [ 'CMD', 'redis-cli', '--raw', 'incr', 'ping' ]
+ test: ['CMD', 'redis-cli', '--raw', 'incr', 'ping']
interval: 10s
timeout: 5s
retries: 5
- env_file: ./secrets/.env
volumes:
db-data:
diff --git a/nodemon.json b/nodemon.json
index c0d6539..651bbb0 100644
--- a/nodemon.json
+++ b/nodemon.json
@@ -1,6 +1,7 @@
{
- "watch": ["src"],
- "ext": ".ts,.js",
+ "watch": ["dist"],
+ "ext": ".js",
"ignore": [],
- "exec": "node -r ts-node/register --inspect=0.0.0.0:9229"
+ "exec": "node --inspect=0.0.0.0:9229 ./dist/server.js",
+ "legacyWatch": true
}
diff --git a/package-lock.json b/package-lock.json
index 4c84ea9..98f5eb1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7,7 +7,7 @@
"": {
"name": "daily-dash",
"version": "1.0.0",
- "license": "ISC",
+ "license": "GPLv3",
"dependencies": {
"@google-cloud/local-auth": "^3.0.1",
"@googleapis/calendar": "^9.7.0",
@@ -62,6 +62,7 @@
"@types/serve-favicon": "^2.5.7",
"@types/supertest": "^2.0.16",
"@types/xml-js": "^1.0.0",
+ "@types/xml2js": "^0.4.14",
"@typescript-eslint/eslint-plugin": "^7.0.2",
"jest": "^29.7.0",
"nodemon": "^3.0.1",
@@ -418,6 +419,36 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-syntax-class-static-block": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
+ "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-attributes": {
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz",
+ "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
"node_modules/@babel/plugin-syntax-import-meta": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
@@ -529,6 +560,21 @@
"@babel/core": "^7.0.0-0"
}
},
+ "node_modules/@babel/plugin-syntax-private-property-in-object": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
+ "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
"node_modules/@babel/plugin-syntax-top-level-await": {
"version": "7.14.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
@@ -768,9 +814,9 @@
}
},
"node_modules/@googleapis/calendar": {
- "version": "9.7.6",
- "resolved": "https://registry.npmjs.org/@googleapis/calendar/-/calendar-9.7.6.tgz",
- "integrity": "sha512-8Mt+Vgm7ybDmU+ezAiLzeO6hxZZkt2hMY+bS/1OZeYM6moHUQAF5cFTOWiVk63U+HJji8dKt9XvscOxEWAwnrQ==",
+ "version": "9.7.7",
+ "resolved": "https://registry.npmjs.org/@googleapis/calendar/-/calendar-9.7.7.tgz",
+ "integrity": "sha512-PPXjXlnZqyZv1+1SstLLTOBvro5HuXAsNGwjdB+2VXmJH3DjPvdCiq3i7DJkCi19tcpddzW6Oq9FM1bpUZHq3A==",
"dependencies": {
"googleapis-common": "^7.0.0"
},
@@ -779,9 +825,9 @@
}
},
"node_modules/@googleapis/docs": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/@googleapis/docs/-/docs-3.0.2.tgz",
- "integrity": "sha512-7AjDSKcZlmt+3cE+t2+kRmDyySl1sCyDYxfnWCY9rpSUhuEFRT7foqdGscI/H2f1blw3LSnF7SVvaYYHlfVHNg==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@googleapis/docs/-/docs-3.1.0.tgz",
+ "integrity": "sha512-8tw3nT0ppvElnIEOByijz/kpOoLDUazQVNxP2ZmaXStPfP1VVPaAqz7KQfiZM3e3fFhe+0eYoTv3a93XUf9auA==",
"dependencies": {
"googleapis-common": "^7.0.0"
},
@@ -1835,11 +1881,11 @@
"dev": true
},
"node_modules/@types/node": {
- "version": "20.14.14",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.14.tgz",
- "integrity": "sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==",
+ "version": "20.16.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.0.tgz",
+ "integrity": "sha512-vDxceJcoZhIVh67S568bm1UGZO0DX0hpplJZxzeXMKwIPLn190ec5RRxQ69BKhX44SUGIxxgMdDY557lGLKprQ==",
"dependencies": {
- "undici-types": "~5.26.4"
+ "undici-types": "~6.19.2"
}
},
"node_modules/@types/nodemailer": {
@@ -1979,6 +2025,15 @@
"xml-js": "*"
}
},
+ "node_modules/@types/xml2js": {
+ "version": "0.4.14",
+ "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.14.tgz",
+ "integrity": "sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/yargs": {
"version": "17.0.33",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
@@ -2504,9 +2559,9 @@
"integrity": "sha512-u5w79Rd7SU4JaIlA/zFqG+gOiuq25q5VLyZ8E+ijJeILuTxVzZgp2CaGw/UTw6pXYN9XMO9yiqj/nEHmhTG5CA=="
},
"node_modules/axios": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.3.tgz",
- "integrity": "sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==",
+ "version": "1.7.4",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz",
+ "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
@@ -2728,23 +2783,26 @@
}
},
"node_modules/babel-preset-current-node-syntax": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz",
- "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz",
+ "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==",
"dev": true,
"dependencies": {
"@babel/plugin-syntax-async-generators": "^7.8.4",
"@babel/plugin-syntax-bigint": "^7.8.3",
- "@babel/plugin-syntax-class-properties": "^7.8.3",
- "@babel/plugin-syntax-import-meta": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.12.13",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5",
+ "@babel/plugin-syntax-import-attributes": "^7.24.7",
+ "@babel/plugin-syntax-import-meta": "^7.10.4",
"@babel/plugin-syntax-json-strings": "^7.8.3",
- "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
- "@babel/plugin-syntax-numeric-separator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4",
"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
"@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
"@babel/plugin-syntax-optional-chaining": "^7.8.3",
- "@babel/plugin-syntax-top-level-await": "^7.8.3"
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
+ "@babel/plugin-syntax-top-level-await": "^7.14.5"
},
"peerDependencies": {
"@babel/core": "^7.0.0"
@@ -3115,9 +3173,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001649",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001649.tgz",
- "integrity": "sha512-fJegqZZ0ZX8HOWr6rcafGr72+xcgJKI9oWfDW5DrD7ExUtgZC7a7R7ZYmZqplh7XDocFdGeIFn7roAxhOeYrPQ==",
+ "version": "1.0.30001651",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz",
+ "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==",
"dev": true,
"funding": [
{
@@ -3924,9 +3982,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.5.tgz",
- "integrity": "sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA==",
+ "version": "1.5.11",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.11.tgz",
+ "integrity": "sha512-R1CccCDYqndR25CaXFd6hp/u9RaaMcftMkphmvuepXr5b1vfLkRml6aWVeBhXJ7rbevHkKEMJtz8XqPf7ffmew==",
"dev": true
},
"node_modules/emittery": {
@@ -4832,9 +4890,9 @@
}
},
"node_modules/foreground-child": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz",
- "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz",
+ "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
"dev": true,
"dependencies": {
"cross-spawn": "^7.0.0",
@@ -5002,15 +5060,15 @@
}
},
"node_modules/gaxios": {
- "version": "6.7.0",
- "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.0.tgz",
- "integrity": "sha512-DSrkyMTfAnAm4ks9Go20QGOcXEyW/NmZhvTYBU2rb4afBB393WIMQPWPEDMl/k8xqiNN9HYq2zao3oWXsdl2Tg==",
+ "version": "6.7.1",
+ "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz",
+ "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==",
"dependencies": {
"extend": "^3.0.2",
"https-proxy-agent": "^7.0.1",
"is-stream": "^2.0.0",
"node-fetch": "^2.6.9",
- "uuid": "^10.0.0"
+ "uuid": "^9.0.1"
},
"engines": {
"node": ">=14"
@@ -5039,18 +5097,6 @@
"node": ">= 14"
}
},
- "node_modules/gaxios/node_modules/uuid": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
- "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
- "funding": [
- "https://github.com/sponsors/broofa",
- "https://github.com/sponsors/ctavan"
- ],
- "bin": {
- "uuid": "dist/bin/uuid"
- }
- },
"node_modules/gcp-metadata": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz",
@@ -5821,9 +5867,9 @@
}
},
"node_modules/ignore": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
- "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true,
"engines": {
"node": ">= 4"
@@ -9926,9 +9972,9 @@
}
},
"node_modules/type-fest": {
- "version": "4.23.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.23.0.tgz",
- "integrity": "sha512-ZiBujro2ohr5+Z/hZWHESLz3g08BBdrdLMieYFULJO+tWc437sn8kQsWLJoZErY8alNhxre9K4p3GURAG11n+w==",
+ "version": "4.25.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.25.0.tgz",
+ "integrity": "sha512-bRkIGlXsnGBRBQRAY56UXBm//9qH4bmJfFvq83gSz41N282df+fjy8ofcEgc1sM8geNt5cl6mC2g9Fht1cs8Aw==",
"dev": true,
"peer": true,
"engines": {
@@ -9981,9 +10027,9 @@
"dev": true
},
"node_modules/undici-types": {
- "version": "5.26.5",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
- "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
+ "version": "6.19.6",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.6.tgz",
+ "integrity": "sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org=="
},
"node_modules/universalify": {
"version": "0.1.2",
diff --git a/package.json b/package.json
index 93a84e1..da0ff3d 100644
--- a/package.json
+++ b/package.json
@@ -5,9 +5,9 @@
"description": "Your all-in-one dashboard for news, weather, todos, events, and commuting.",
"main": "./src/server.ts",
"scripts": {
- "clean": "rimraf ./out",
- "build": "tsc",
- "start": "nodemon -L ./src/server.ts",
+ "clean": "rimraf ./dist",
+ "build": "tsc --watch",
+ "start": "nodemon",
"test": "jest",
"lint": "eslint .",
"format:check": "prettier . --check",
@@ -15,8 +15,7 @@
"docker:up": "docker compose --env-file ./secrets/.env up",
"docker:down": "docker-compose --env-file ./secrets/.env down",
"docker:rmi": "docker rmi daily-dash postgres redis",
- "migrate": "knex --knexfile ./out/db/knexfile.js migrate:latest",
- "seed": "knex --knexfile ./out/db/knexfile.js seed:run"
+ "seed": "knex --knexfile ./dist/db/knexfile.js seed:run"
},
"repository": {
"type": "git",
@@ -31,8 +30,8 @@
"calendar",
"commuting"
],
- "author": "CryptoSpaceDev",
- "license": "ISC",
+ "author": "Hannes Gorges",
+ "license": "GPLv3",
"bugs": {
"url": "https://github.com/hgorges/DailyDash.git/issues"
},
@@ -55,6 +54,7 @@
"@types/serve-favicon": "^2.5.7",
"@types/supertest": "^2.0.16",
"@types/xml-js": "^1.0.0",
+ "@types/xml2js": "^0.4.14",
"@typescript-eslint/eslint-plugin": "^7.0.2",
"jest": "^29.7.0",
"nodemon": "^3.0.1",
diff --git a/public/css/content/admin.css b/public/css/content/admin.css
index ff5971b..201b105 100644
--- a/public/css/content/admin.css
+++ b/public/css/content/admin.css
@@ -1,10 +1,10 @@
-
.content-container {
display: flex;
justify-content: space-between;
}
-#dashboard-summary, #user-list {
+#dashboard-summary,
+#user-list {
flex: 1;
margin: 10px;
}
@@ -70,7 +70,7 @@
}
.stat:after {
- content: "";
+ content: '';
display: table;
clear: both;
-}
\ No newline at end of file
+}
diff --git a/public/css/content/dashboard/calendar-widget.css b/public/css/content/dashboard/calendar-widget.css
index e405f01..185026d 100644
--- a/public/css/content/dashboard/calendar-widget.css
+++ b/public/css/content/dashboard/calendar-widget.css
@@ -45,7 +45,7 @@
justify-content: space-between;
background: var(--secondary-color);
color: var(--primary-color);
- box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15);
transition: transform 0.2s ease,
box-shadow 0.2s ease;
margin-bottom: 10px;
@@ -53,7 +53,7 @@
.event:hover {
transform: translateY(-3px);
- box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15);
}
.event h3 {
diff --git a/public/css/content/dashboard/traffic-widget.css b/public/css/content/dashboard/traffic-widget.css
index 1b09dd6..5b79501 100644
--- a/public/css/content/dashboard/traffic-widget.css
+++ b/public/css/content/dashboard/traffic-widget.css
@@ -3,7 +3,7 @@
border-left: 4px solid var(--primary-color);
padding: 10px 20px;
border-radius: 8px;
- box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15);
}
.route-info {
@@ -34,7 +34,7 @@
border-radius: 20px;
padding: 5px 10px;
margin: 5px;
- box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15);
display: inline-flex;
align-items: center;
font-size: 1em;
diff --git a/public/css/content/dashboard/weather-widget.css b/public/css/content/dashboard/weather-widget.css
index e78da19..03793f5 100644
--- a/public/css/content/dashboard/weather-widget.css
+++ b/public/css/content/dashboard/weather-widget.css
@@ -19,7 +19,7 @@
background-color: var(--secondary-color);
color: var(--primary-color);
border-radius: 5px;
- box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15);
}
.weather-description:not(:last-child) {
@@ -44,7 +44,7 @@
background-color: var(--secondary-color);
color: var(--primary-color);
border-radius: 5px;
- box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15);
}
.temperature-label {
@@ -72,7 +72,7 @@
padding: 10px;
background: var(--secondary-color);
border-radius: 10px;
- box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@@ -121,7 +121,7 @@
padding: 10px;
background: var(--secondary-color);
border-radius: 10px;
- box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15);
width: 25px;
height: 25px;
display: flex;
diff --git a/public/css/content/signup.css b/public/css/content/signup.css
index 89fb24f..9d8629b 100644
--- a/public/css/content/signup.css
+++ b/public/css/content/signup.css
@@ -87,7 +87,7 @@
color: var(--error-color);
border-radius: 8px;
margin: 10px 10px 20px;
- box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15);
font-weight: bold;
position: relative;
border-left: 4px solid var(--error-color);
diff --git a/public/css/main.css b/public/css/main.css
index 5b93047..f72686f 100644
--- a/public/css/main.css
+++ b/public/css/main.css
@@ -79,7 +79,7 @@ p {
color: var(--info-color);
border-radius: 8px;
margin: 10px 10px 20px;
- box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15);
font-weight: bold;
position: relative;
border-left: 4px solid var(--info-color);
@@ -91,7 +91,7 @@ p {
color: var(--error-color);
border-radius: 8px;
margin: 10px 10px 20px;
- box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15);
font-weight: bold;
position: relative;
border-left: 4px solid var(--error-color);
diff --git a/qodana.yaml b/qodana.yaml
index 51c2bcb..6013899 100644
--- a/qodana.yaml
+++ b/qodana.yaml
@@ -1,4 +1,4 @@
-version: "1.0"
+version: '1.0'
profile:
name: qodana.starter
diff --git a/db/knexfile.ts b/src/db/knexfile.ts
similarity index 85%
rename from db/knexfile.ts
rename to src/db/knexfile.ts
index 4aa55bc..c865274 100644
--- a/db/knexfile.ts
+++ b/src/db/knexfile.ts
@@ -12,10 +12,10 @@ const knexConfig: Knex.Config = {
timezone: process.env.DB_TIMEZONE!,
},
migrations: {
- directory: './migrations',
+ directory: './dist/db/migrations',
},
seeds: {
- directory: './seeds',
+ directory: './dist/db/seeds',
},
};
diff --git a/db/migrations/001_settings_migration.ts b/src/db/migrations/001_settings_migration.ts
similarity index 100%
rename from db/migrations/001_settings_migration.ts
rename to src/db/migrations/001_settings_migration.ts
diff --git a/db/migrations/002_users_migration.ts b/src/db/migrations/002_users_migration.ts
similarity index 100%
rename from db/migrations/002_users_migration.ts
rename to src/db/migrations/002_users_migration.ts
diff --git a/db/migrations/003_api_keys_migration.ts b/src/db/migrations/003_api_keys_migration.ts
similarity index 100%
rename from db/migrations/003_api_keys_migration.ts
rename to src/db/migrations/003_api_keys_migration.ts
diff --git a/db/seeds/001_users_seed.ts b/src/db/seeds/001_users_seed.ts
similarity index 88%
rename from db/seeds/001_users_seed.ts
rename to src/db/seeds/001_users_seed.ts
index 4494dc7..48c8ea0 100644
--- a/db/seeds/001_users_seed.ts
+++ b/src/db/seeds/001_users_seed.ts
@@ -1,6 +1,11 @@
import { Knex } from 'knex';
import bcrypt from 'bcrypt';
+/*
+ This file is used to test the knex seed functionality.
+ In a production environment, this seed file should not be used.
+ */
+
export async function seed(knex: Knex): Promise {
await knex('users').insert([
{
diff --git a/src/middleware/authMiddleware.ts b/src/middleware/authMiddleware.ts
index 97fd690..cf1598a 100644
--- a/src/middleware/authMiddleware.ts
+++ b/src/middleware/authMiddleware.ts
@@ -1,9 +1,9 @@
import { NextFunction, Request, Response } from 'express';
import userModel from '../models/userModel';
import { AuthRequest } from '../utils/utils';
-import { mailer } from '../server';
import path from 'path';
import { renderFile } from 'ejs';
+import mailer from '../utils/mailer';
export async function loginUser(
req: AuthRequest,
diff --git a/src/server.ts b/src/server.ts
index e39b41b..de0178a 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -4,44 +4,38 @@ import express from 'express';
import fs from 'fs';
import Knex from 'knex';
import path from 'path';
-import knexConfig from '../db/knexfile';
+import knexConfig from './db/knexfile';
import configRouter from './routes/configRoutes';
import sessionRouter from './routes/sessionRoutes';
import userRouter from './routes/userRoutes';
-import nodemailer from 'nodemailer';
-import nodemailerSendGrid from 'nodemailer-sendgrid';
+// Loading environment variables
dotenv.config({ path: '../secrets/.env' });
export const db = Knex(knexConfig);
+db.migrate.latest().finally(() => {
+ const app = express();
+ const port = parseInt(process.env.PORT as string);
-const app = express();
-const port = parseInt(process.env.PORT as string);
+ app.set('view engine', 'ejs');
-export const mailer = nodemailer.createTransport(
- nodemailerSendGrid({
- apiKey: process.env.SENDGRID_API_KEY!,
- }),
-);
+ app.use(configRouter);
+ app.use(sessionRouter);
+ app.use(userRouter);
-app.set('view engine', 'ejs');
+ const privateKey = fs.readFileSync(
+ path.join(__dirname, '..', 'secrets', 'cryptospace.key'),
+ 'utf8',
+ );
+ const certificate = fs.readFileSync(
+ path.join(__dirname, '..', 'secrets', 'cryptospace.crt'),
+ 'utf8',
+ );
-app.use(configRouter);
-app.use(sessionRouter);
-app.use(userRouter);
+ const credentials = { key: privateKey, cert: certificate };
+ const httpsServer = https.createServer(credentials, app);
-const privateKey = fs.readFileSync(
- path.join(__dirname, '..', 'secrets', 'cryptospace.key'),
- 'utf8',
-);
-const certificate = fs.readFileSync(
- path.join(__dirname, '..', 'secrets', 'cryptospace.crt'),
- 'utf8',
-);
+ httpsServer.listen(port);
-const credentials = { key: privateKey, cert: certificate };
-const httpsServer = https.createServer(credentials, app);
-
-httpsServer.listen(port);
-
-console.log(`Server is running on port ${port}`);
+ console.log(`Server is running on port ${port}`);
+});
diff --git a/src/utils/mailer.ts b/src/utils/mailer.ts
new file mode 100644
index 0000000..fafb486
--- /dev/null
+++ b/src/utils/mailer.ts
@@ -0,0 +1,8 @@
+import nodemailer from 'nodemailer';
+import nodemailerSendGrid from 'nodemailer-sendgrid';
+
+export default nodemailer.createTransport(
+ nodemailerSendGrid({
+ apiKey: process.env.SENDGRID_API_KEY!,
+ }),
+);
diff --git a/tsconfig.json b/tsconfig.json
index c1754e1..03d5291 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,17 +1,16 @@
{
"compilerOptions": {
- "target": "es6",
- "module": "commonjs",
- "rootDir": "./",
- "lib": ["es6"],
+ "target": "ESNext",
+ "module": "NodeNext",
+ "lib": ["ESNext"],
+ "rootDir": "./src",
+ "outDir": "./dist",
"sourceMap": true,
- "outDir": "out",
"noEmitOnError": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
- "strict": true,
- "skipLibCheck": true
+ "strict": true
},
- "include": ["src/**/*.ts", "test/**/*.ts", "db/**/*.ts"],
+ "include": ["src/**/*"],
"exclude": ["node_modules"]
}
diff --git a/views/includes/end.ejs b/views/includes/end.ejs
index 3f747f4..43a2dbd 100644
--- a/views/includes/end.ejs
+++ b/views/includes/end.ejs
@@ -2,7 +2,7 @@