Parse postgres connection information out of the environment
Some checks failed
Build and Publish Docker Container / build (push) Failing after 3m12s

This commit is contained in:
Joshua Coles 2024-02-11 18:59:32 +00:00
parent 28b01769e5
commit e967244158
5 changed files with 83 additions and 103 deletions

View File

@ -25,7 +25,7 @@
"react-dom": "^18",
"react-tooltip": "^5.25.0",
"reaviz": "^15.2.1",
"swr": "^2.2.4"
"zod": "^3.22.4"
},
"devDependencies": {
"@testing-library/jest-dom": "^6.1.5",
@ -41,7 +41,7 @@
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"kysely-codegen": "^0.11.0",
"postcss": "^8",
"postcss": "^8.4.35",
"tailwindcss": "^3.3.0",
"ts-node": "^10.9.2",
"typescript": "^5"

105
pnpm-lock.yaml generated
View File

@ -50,9 +50,9 @@ dependencies:
reaviz:
specifier: ^15.2.1
version: 15.2.1(@types/react@18.0.0)(prop-types@15.8.1)(react-dom@18.0.0)(react@18.0.0)
swr:
specifier: ^2.2.4
version: 2.2.4(react@18.0.0)
zod:
specifier: ^3.22.4
version: 3.22.4
devDependencies:
'@testing-library/jest-dom':
@ -78,7 +78,7 @@ devDependencies:
version: 18.0.0
autoprefixer:
specifier: ^10.0.1
version: 10.0.1(postcss@8.0.0)
version: 10.0.1(postcss@8.4.35)
eslint:
specifier: ^8
version: 8.0.0
@ -95,11 +95,11 @@ devDependencies:
specifier: ^0.11.0
version: 0.11.0(kysely@0.27.2)(pg@8.11.3)
postcss:
specifier: ^8
version: 8.0.0
specifier: ^8.4.35
version: 8.4.35
tailwindcss:
specifier: ^3.3.0
version: 3.3.0(postcss@8.0.0)(ts-node@10.9.2)
version: 3.3.0(postcss@8.4.35)(ts-node@10.9.2)
ts-node:
specifier: ^10.9.2
version: 10.9.2(@types/node@20.0.0)(typescript@5.0.2)
@ -543,7 +543,7 @@ packages:
peerDependencies:
tailwindcss: ^3.0
dependencies:
tailwindcss: 3.3.0(postcss@8.0.0)(ts-node@10.9.2)
tailwindcss: 3.3.0(postcss@8.4.35)(ts-node@10.9.2)
dev: false
/@heroicons/react@1.0.6(react@18.0.0):
@ -1810,7 +1810,7 @@ packages:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
dev: true
/autoprefixer@10.0.1(postcss@8.0.0):
/autoprefixer@10.0.1(postcss@8.4.35):
resolution: {integrity: sha512-aQo2BDIsoOdemXUAOBpFv4ZQa2DrOtEufarYhtFsK1088Ca0TUwu/aQWf0M3mrILXZ3mTIVn1lR3hPW8acacsw==}
engines: {node: ^10 || ^12 || >=14}
hasBin: true
@ -1822,7 +1822,7 @@ packages:
colorette: 1.4.0
normalize-range: 0.1.2
num2fraction: 1.2.2
postcss: 8.0.0
postcss: 8.4.35
postcss-value-parser: 4.2.0
dev: true
@ -2146,6 +2146,7 @@ packages:
/colorette@1.4.0:
resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==}
dev: true
/combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
@ -3788,21 +3789,12 @@ packages:
get-intrinsic: 1.2.4
dev: true
/isarray@1.0.0:
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
/isarray@2.0.5:
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
/isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
/isobject@2.1.0:
resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==}
engines: {node: '>=0.10.0'}
dependencies:
isarray: 1.0.0
/istanbul-lib-coverage@3.2.2:
resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
engines: {node: '>=8'}
@ -4518,12 +4510,6 @@ packages:
resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
engines: {node: '>=10'}
/line-column@1.0.2:
resolution: {integrity: sha512-Ktrjk5noGYlHsVnYWh62FLVs4hTb8A3e+vucNZMgPeAOITdshMSgv4cCZQeRDjm7+goqmo6+liZwTXo+U3sVww==}
dependencies:
isarray: 1.0.0
isobject: 2.1.0
/lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
@ -5087,27 +5073,27 @@ packages:
deprecated: You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1
dev: false
/postcss-import@14.1.0(postcss@8.0.0):
/postcss-import@14.1.0(postcss@8.4.35):
resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==}
engines: {node: '>=10.0.0'}
peerDependencies:
postcss: ^8.0.0
dependencies:
postcss: 8.0.0
postcss: 8.4.35
postcss-value-parser: 4.2.0
read-cache: 1.0.0
resolve: 1.22.8
/postcss-js@4.0.1(postcss@8.0.0):
/postcss-js@4.0.1(postcss@8.4.35):
resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
engines: {node: ^12 || ^14 || >= 16}
peerDependencies:
postcss: ^8.4.21
dependencies:
camelcase-css: 2.0.1
postcss: 8.0.0
postcss: 8.4.35
/postcss-load-config@3.1.4(postcss@8.0.0)(ts-node@10.9.2):
/postcss-load-config@3.1.4(postcss@8.4.35)(ts-node@10.9.2):
resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
engines: {node: '>= 10'}
peerDependencies:
@ -5120,17 +5106,17 @@ packages:
optional: true
dependencies:
lilconfig: 2.1.0
postcss: 8.0.0
postcss: 8.4.35
ts-node: 10.9.2(@types/node@20.0.0)(typescript@5.0.2)
yaml: 1.10.2
/postcss-nested@6.0.0(postcss@8.0.0):
/postcss-nested@6.0.0(postcss@8.4.35):
resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==}
engines: {node: '>=12.0'}
peerDependencies:
postcss: ^8.2.14
dependencies:
postcss: 8.0.0
postcss: 8.4.35
postcss-selector-parser: 6.0.15
/postcss-selector-parser@6.0.15:
@ -5143,15 +5129,6 @@ packages:
/postcss-value-parser@4.2.0:
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
/postcss@8.0.0:
resolution: {integrity: sha512-BriaW5AeZHfyuuKhK3Z6yRDKI6NR2TdRWyZcj3+Pk2nczQsMBqavggAzTledsbyexPthW3nFA6XfgCWjZqmVPA==}
engines: {node: ^10 || ^12 || >=14}
dependencies:
colorette: 1.4.0
line-column: 1.0.2
nanoid: 3.3.7
source-map: 0.6.1
/postcss@8.4.31:
resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
engines: {node: ^10 || ^12 || >=14}
@ -5161,6 +5138,14 @@ packages:
source-map-js: 1.0.2
dev: false
/postcss@8.4.35:
resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==}
engines: {node: ^10 || ^12 || >=14}
dependencies:
nanoid: 3.3.7
picocolors: 1.0.0
source-map-js: 1.0.2
/postgres-array@2.0.0:
resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
engines: {node: '>=4'}
@ -5815,7 +5800,6 @@ packages:
/source-map-js@1.0.2:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'}
dev: false
/source-map-support@0.3.3:
resolution: {integrity: sha512-9O4+y9n64RewmFoKUZ/5Tx9IHIcXM6Q+RTSw6ehnqybUz4a7iwR3Eaw80uLtqqQ5D0C+5H03D4KKGo9PdP33Gg==}
@ -5845,6 +5829,7 @@ packages:
/source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
dev: true
/split2@4.2.0:
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
@ -6063,16 +6048,6 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
/swr@2.2.4(react@18.0.0):
resolution: {integrity: sha512-njiZ/4RiIhoOlAaLYDqwz5qH/KZXVilRLvomrx83HjzCWTfa+InyfAjv05PSFxnmLzZkNO9ZfvgoqzAaEI4sGQ==}
peerDependencies:
react: ^16.11.0 || ^17.0.0 || ^18.0.0
dependencies:
client-only: 0.0.1
react: 18.0.0
use-sync-external-store: 1.2.0(react@18.0.0)
dev: false
/symbol-tree@3.2.4:
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
dev: true
@ -6093,7 +6068,7 @@ packages:
resolution: {integrity: sha512-3mFKyCo/MBcgyOTlrY8T7odzZFx+w+qKSMAmdFzRvqBfLlSigU6TZnlFHK0lkMwj9Bj8OYU+9yW9lmGuS0QEnQ==}
dev: false
/tailwindcss@3.3.0(postcss@8.0.0)(ts-node@10.9.2):
/tailwindcss@3.3.0(postcss@8.4.35)(ts-node@10.9.2):
resolution: {integrity: sha512-hOXlFx+YcklJ8kXiCAfk/FMyr4Pm9ck477G0m/us2344Vuj355IpoEDB5UmGAsSpTBmr+4ZhjzW04JuFXkb/fw==}
engines: {node: '>=12.13.0'}
hasBin: true
@ -6114,11 +6089,11 @@ packages:
normalize-path: 3.0.0
object-hash: 3.0.0
picocolors: 1.0.0
postcss: 8.0.0
postcss-import: 14.1.0(postcss@8.0.0)
postcss-js: 4.0.1(postcss@8.0.0)
postcss-load-config: 3.1.4(postcss@8.0.0)(ts-node@10.9.2)
postcss-nested: 6.0.0(postcss@8.0.0)
postcss: 8.4.35
postcss-import: 14.1.0(postcss@8.4.35)
postcss-js: 4.0.1(postcss@8.4.35)
postcss-load-config: 3.1.4(postcss@8.4.35)(ts-node@10.9.2)
postcss-nested: 6.0.0(postcss@8.4.35)
postcss-selector-parser: 6.0.15
postcss-value-parser: 4.2.0
quick-lru: 5.1.1
@ -6452,14 +6427,6 @@ packages:
use-isomorphic-layout-effect: 1.1.2(@types/react@18.0.0)(react@18.0.0)
dev: false
/use-sync-external-store@1.2.0(react@18.0.0):
resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies:
react: 18.0.0
dev: false
/util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
@ -6703,3 +6670,7 @@ packages:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
dev: true
/zod@3.22.4:
resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==}
dev: false

View File

@ -1,7 +1,6 @@
import {SubjectComparisonCard} from "@/components/cards/subjectComparisonCard";
import {CalendarOverviewCard} from "@/components/cards/calendarOverviewCard";
import {SubjectOverviewCard} from "@/components/cards/subjectOverviewCard";
import {getData} from "@/data/fetchData";
import {getDataSQL} from "@/data/fetchWithSQL";
export interface OverviewConfig {

View File

@ -2,15 +2,52 @@ import {DB as Database} from './db' // this is the Database interface we defined
import {Pool} from 'pg'
import {Kysely, PostgresDialect} from 'kysely'
import * as fs from "node:fs";
import {z} from 'zod';
function fileOrEnv(fileKey: string, valueKey: string): string | undefined {
const file = process.env[fileKey];
const envSchema = z.object({
POSTGRES_DB: z.string(),
POSTGRES_HOST: z.string(),
POSTGRES_PORT: z.string().transform((val, ctx) => {
const parsed = parseInt(val);
if (isNaN(parsed)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Not a number",
});
return z.NEVER;
}
return parsed;
}),
POSTGRES_USER: z.string().optional(),
POSTGRES_USER_FILE: z.string().optional(),
POSTGRES_PASSWORD: z.string().optional(),
POSTGRES_PASSWORD_FILE: z.string().optional(),
}).refine(
env => env.POSTGRES_USER || env.POSTGRES_USER_FILE,
{
message: "Either POSTGRES_USER or POSTGRES_USER_FILE must be set",
path: ["POSTGRES_USER", "POSTGRES_USER_FILE"],
}
).refine(
env => env.POSTGRES_PASSWORD || env.POSTGRES_PASSWORD_FILE,
{
message: "Either POSTGRES_PASSWORD or POSTGRES_PASSWORD_FILE must be set",
path: ["POSTGRES_PASSWORD", "POSTGRES_PASSWORD_FILE"],
}
);
const env = envSchema.parse(process.env);
function fileOrEnv(fileKey: keyof typeof env, valueKey: keyof typeof env): string | undefined {
const file: string = env[fileKey] as string;
if (file && fs.existsSync(file)) {
return fs.readFileSync(file, 'utf8');
}
return process.env[valueKey];
return env[valueKey] as string;
}
function getCredentials() {
@ -22,9 +59,9 @@ function getCredentials() {
const dialect = new PostgresDialect({
pool: new Pool({
database: process.env.POSTGRES_DB!,
host: process.env.POSTGRES_HOST!,
port: parseInt(process.env.POSTGRES_PORT!),
database: env.POSTGRES_DB,
host: env.POSTGRES_HOST,
port: env.POSTGRES_PORT,
...getCredentials(),
max: 10,
})

View File

@ -1,5 +1,4 @@
"use server";
import {OverviewConfig} from "@/components/OverviewPage";
export interface Data {
projects: {
@ -16,29 +15,3 @@ export interface Data {
// description: string,
}[],
}
export async function getData(config: OverviewConfig): Promise<Data> {
const projectIds = config.subjects.map((subject) => subject.projectId);
const projectResponse = await fetch(`https://cosmos.tail307fc.ts.net/api/project?select=raw_json&toggl_id=in.(${projectIds.join(',')})`);
const projects = await projectResponse.json();
const projectLensed = projects.map((project: any) => ({
projectId: project.raw_json.id,
name: project.raw_json.name,
color: project.raw_json.color,
}));
const timeEntriesResponse = await fetch(`https://cosmos.tail307fc.ts.net/api/time_entry?select=project_id,raw_json&project_id=in.(${projectIds.join(',')})&start=gt.${config.timePeriod.start}&start=lt.${config.timePeriod.end}`);
const timeEntries = await timeEntriesResponse.json();
const timeEntriesLensed = timeEntries.map((timeEntry: any) => ({
projectId: timeEntry.project_id,
start: timeEntry.raw_json.start,
end: timeEntry.raw_json.end,
duration: timeEntry.raw_json.seconds,
// description: timeEntry.raw_json.description,
}));
return {
projects: projectLensed,
timeEntries: timeEntriesLensed,
};
}