From a56454110af23498612959b1578bb6f36ffe3edf Mon Sep 17 00:00:00 2001 From: Vargha Csongor Date: Thu, 27 Mar 2025 22:08:01 +0100 Subject: [PATCH] fix lint issues with prettier --- apps/app/.github/workflows/playwright.yml | 36 +- apps/app/.storybook/main.ts | 27 +- apps/app/.storybook/preview.ts | 20 +- apps/app/.vscode/settings.json | 2 +- apps/app/e2e/example.spec.ts | 16 +- apps/app/messages/en.json | 2 +- apps/app/messages/hu.json | 274 +- apps/app/package.json | 140 +- apps/app/playwright.config.ts | 114 +- apps/app/postcss.config.js | 2 +- apps/app/src/app.css | 26 +- apps/app/src/app.d.ts | 24 +- apps/app/src/hooks.server.ts | 54 +- apps/app/src/lib/api/api.gen.ts | 2710 +++++++++-------- apps/app/src/lib/cookiesAlert.svelte | 28 +- apps/app/src/lib/model.ts | 162 +- apps/app/src/lib/server/oauth.ts | 10 +- apps/app/src/lib/server/session.ts | 33 +- apps/app/src/lib/switchToLanguage.test.ts | 44 +- apps/app/src/lib/switchToLanguage.ts | 8 +- apps/app/src/lib/theme-select.svelte | 8 +- apps/app/src/lib/themes.ts | 2 +- apps/app/src/routes/+page.server.ts | 16 +- apps/app/src/routes/+page.svelte | 18 +- apps/app/src/routes/login/+page.server.ts | 10 +- apps/app/src/routes/login/+page.svelte | 2 +- apps/app/src/routes/login/google/+server.ts | 22 +- .../login/google/callback/+page.server.ts | 117 +- .../routes/login/google/callback/+page.svelte | 73 +- apps/app/src/routes/page.stories.svelte | 6 +- apps/app/src/stories/Button.stories.svelte | 38 +- apps/app/src/stories/Button.svelte | 44 +- apps/app/src/stories/Configure.mdx | 67 +- apps/app/src/stories/Header.stories.svelte | 38 +- apps/app/src/stories/Header.svelte | 76 +- apps/app/src/stories/Page.stories.svelte | 46 +- apps/app/src/stories/Page.svelte | 122 +- apps/app/src/stories/button.css | 36 +- apps/app/src/stories/header.css | 36 +- apps/app/src/stories/page.css | 78 +- apps/app/svelte.config.js | 4 +- apps/app/tests-examples/demo-todo-app.spec.ts | 647 ++-- apps/app/tsconfig.json | 4 +- apps/app/vite.config.ts | 12 +- apps/app/wrangler.jsonc | 184 +- 45 files changed, 2766 insertions(+), 2672 deletions(-) diff --git a/apps/app/.github/workflows/playwright.yml b/apps/app/.github/workflows/playwright.yml index 3eb1314..2812391 100644 --- a/apps/app/.github/workflows/playwright.yml +++ b/apps/app/.github/workflows/playwright.yml @@ -1,27 +1,27 @@ name: Playwright Tests on: push: - branches: [ main, master ] + branches: [main, master] pull_request: - branches: [ main, master ] + branches: [main, master] jobs: test: timeout-minutes: 60 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: lts/* - - name: Install dependencies - run: npm ci - - name: Install Playwright Browsers - run: npx playwright install --with-deps - - name: Run Playwright tests - run: npx playwright test - - uses: actions/upload-artifact@v4 - if: ${{ !cancelled() }} - with: - name: playwright-report - path: playwright-report/ - retention-days: 30 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: lts/* + - name: Install dependencies + run: npm ci + - name: Install Playwright Browsers + run: npx playwright install --with-deps + - name: Run Playwright tests + run: npx playwright test + - uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/apps/app/.storybook/main.ts b/apps/app/.storybook/main.ts index c3c286d..b55c2e9 100644 --- a/apps/app/.storybook/main.ts +++ b/apps/app/.storybook/main.ts @@ -1,19 +1,16 @@ import type { StorybookConfig } from '@storybook/sveltekit'; const config: StorybookConfig = { - "stories": [ - "../src/**/*.mdx", - "../src/**/*.stories.@(js|ts|svelte)" - ], - "addons": [ - "@storybook/addon-svelte-csf", - "@storybook/addon-essentials", - "@chromatic-com/storybook", - "@storybook/addon-interactions" - ], - "framework": { - "name": "@storybook/sveltekit", - "options": {} - } + stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|ts|svelte)'], + addons: [ + '@storybook/addon-svelte-csf', + '@storybook/addon-essentials', + '@chromatic-com/storybook', + '@storybook/addon-interactions' + ], + framework: { + name: '@storybook/sveltekit', + options: {} + } }; -export default config; \ No newline at end of file +export default config; diff --git a/apps/app/.storybook/preview.ts b/apps/app/.storybook/preview.ts index c4d1be9..dbd1c7a 100644 --- a/apps/app/.storybook/preview.ts +++ b/apps/app/.storybook/preview.ts @@ -1,14 +1,14 @@ -import type { Preview } from '@storybook/svelte' +import type { Preview } from '@storybook/svelte'; const preview: Preview = { - parameters: { - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/i, - }, - }, - }, + parameters: { + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i + } + } + } }; -export default preview; \ No newline at end of file +export default preview; diff --git a/apps/app/.vscode/settings.json b/apps/app/.vscode/settings.json index 0126e59..4110aab 100644 --- a/apps/app/.vscode/settings.json +++ b/apps/app/.vscode/settings.json @@ -2,4 +2,4 @@ "files.associations": { "wrangler.json": "jsonc" } -} \ No newline at end of file +} diff --git a/apps/app/e2e/example.spec.ts b/apps/app/e2e/example.spec.ts index 54a906a..787dd49 100644 --- a/apps/app/e2e/example.spec.ts +++ b/apps/app/e2e/example.spec.ts @@ -1,18 +1,18 @@ import { test, expect } from '@playwright/test'; test('has title', async ({ page }) => { - await page.goto('https://playwright.dev/'); + await page.goto('https://playwright.dev/'); - // Expect a title "to contain" a substring. - await expect(page).toHaveTitle(/Playwright/); + // Expect a title "to contain" a substring. + await expect(page).toHaveTitle(/Playwright/); }); test('get started link', async ({ page }) => { - await page.goto('https://playwright.dev/'); + await page.goto('https://playwright.dev/'); - // Click the get started link. - await page.getByRole('link', { name: 'Get started' }).click(); + // Click the get started link. + await page.getByRole('link', { name: 'Get started' }).click(); - // Expects page to have a heading with the name of Installation. - await expect(page.getByRole('heading', { name: 'Installation' })).toBeVisible(); + // Expects page to have a heading with the name of Installation. + await expect(page.getByRole('heading', { name: 'Installation' })).toBeVisible(); }); diff --git a/apps/app/messages/en.json b/apps/app/messages/en.json index a136fa4..3cd9a2c 100644 --- a/apps/app/messages/en.json +++ b/apps/app/messages/en.json @@ -93,7 +93,7 @@ "plant": "Plant", "politics": "Politics", "profile_id": "Profile ID", - "profiel_id_registration":"If someone already created a profile for you, ask them for your profiles ID and enter it here.", + "profiel_id_registration": "If someone already created a profile for you, ask them for your profiles ID and enter it here.", "profile_picture": "Profile Picture", "privacy_policy": "Privacy Policy", "recipe": "Recipe", diff --git a/apps/app/messages/hu.json b/apps/app/messages/hu.json index 66f800c..6b3426b 100644 --- a/apps/app/messages/hu.json +++ b/apps/app/messages/hu.json @@ -1,141 +1,141 @@ { - "$schema": "https://inlang.com/schema/inlang-message-format", - "about": "Rólunk", - "accept": "Elfogadás", - "add": "Hozzáadás", - "address": "Cím", - "alive": "Élő", - "allergies": "Allergiák", - "allow_family_tree_admin_access": "Családfa adminisztrátor hozzáférésének engedélyezése", - "animal": "Állat", - "audio": "Hang", - "back": "Vissza", - "baptized": "Megkeresztelve", - "belief": "Hit", - "birth_name": "Születési név", - "blood_pressure": "Vérnyomás", - "blood_type": "Vércsoport", - "born": "Született", - "cancel": "Mégse", - "city": "Város", - "child": "Gyermek", - "citizenship": "Állampolgárság", - "close": "Bezár", - "coffee": "Kávé", - "colour": "Szín", - "connection": "Kapcsolat", - "connection_type": "Kapcsolat típusa", - "contact": "Kapcsolat", - "cookie_disclaimer": "Ez a weboldal sütiket használ annak érdekében, hogy a lehető legjobb élményt nyújtsa, beleértve a téma tárolását és a felhasználói munkamenetek kezelését.", - "cookie_policy": "Süti szabályzat", - "country": "Ország", - "dark": "Sötét", - "death": "Halál", - "deceased": "Elhunyt", - "deny": "Elutasítás", - "description": "Leírás", - "details": "Részletek", - "directions": "Útvonalak", - "document": "Dokumentum", - "download": "Letöltés", - "edit": "Szerkesztés", - "email": "Email", + "$schema": "https://inlang.com/schema/inlang-message-format", + "about": "Rólunk", + "accept": "Elfogadás", + "add": "Hozzáadás", + "address": "Cím", + "alive": "Élő", + "allergies": "Allergiák", + "allow_family_tree_admin_access": "Családfa adminisztrátor hozzáférésének engedélyezése", + "animal": "Állat", + "audio": "Hang", + "back": "Vissza", + "baptized": "Megkeresztelve", + "belief": "Hit", + "birth_name": "Születési név", + "blood_pressure": "Vérnyomás", + "blood_type": "Vércsoport", + "born": "Született", + "cancel": "Mégse", + "city": "Város", + "child": "Gyermek", + "citizenship": "Állampolgárság", + "close": "Bezár", + "coffee": "Kávé", + "colour": "Szín", + "connection": "Kapcsolat", + "connection_type": "Kapcsolat típusa", + "contact": "Kapcsolat", + "cookie_disclaimer": "Ez a weboldal sütiket használ annak érdekében, hogy a lehető legjobb élményt nyújtsa, beleértve a téma tárolását és a felhasználói munkamenetek kezelését.", + "cookie_policy": "Süti szabályzat", + "country": "Ország", + "dark": "Sötét", + "death": "Halál", + "deceased": "Elhunyt", + "deny": "Elutasítás", + "description": "Leírás", + "details": "Részletek", + "directions": "Útvonalak", + "document": "Dokumentum", + "download": "Letöltés", + "edit": "Szerkesztés", + "email": "Email", "export_something": "{thing}Exportálás", - "extra_names": "Extra nevek", - "faith": "Vallás", - "failed_to_create_user": "Felhasználó létrehozása sikertelen", + "extra_names": "Extra nevek", + "faith": "Vallás", + "failed_to_create_user": "Felhasználó létrehozása sikertelen", "family_tree": "Családfa", - "favourite": "Kedvenc", - "favourite_recipes": "Kedvenc receptek", - "file": "Fájl", - "first_name": "Keresztnév", - "flower": "Virág", - "fruit": "Gyümölcs", - "hair_colour": "Hajszín", - "hello_world": "Helló, {name} innen: hu!", - "height": "Magasság", - "hobby": "Hobbi", - "home": "Otthon", - "id": "Azonosító", - "ideology": "Ideológia", - "illness": "Betegség", - "image": "Kép", - "ingridients": "Hozzávalók", - "interest": "Érdeklődés", - "language": "Nyelv", - "last_name": "Vezetéknév", - "life_events": "Életesemények", - "light": "Világos", - "loading": "Betöltés", - "login": "Bejelentkezés", - "logout": "Kijelentkezés", - "medication": "Gyógyszer", - "message_for_future_generations": "Üzenet a jövő generációinak", - "middle_name": "Második név", - "missing_field": "{field} mező hiányzik", - "mothers_first_name": "Anyja keresztneve", - "mothers_last_name": "Anyja vezetékneve", - "nation": "Nemzet", - "no": "Nem", - "no_data": "Nincs adat", - "notes": "Jegyzetek", - "occupation": "Foglalkozás", - "occupation_to_display": "Megjelenítendő foglalkozás", - "others_said": "Mások mondták", - "parent": "Szülő", - "people": "Emberek", - "person": "Személy", - "pet": "Háziállat", - "philosophy": "Filozófia", - "photos": "Fotók", - "place_of_birth": "Születési hely", - "place_of_death": "Halálozási hely", - "plant": "Növény", - "politics": "Politika", - "profile_picture": "Profilkép", - "privacy_policy": "Adatvédelmi irányelvek", - "recipe": "Recept", - "recipes": "Receptek", - "register": "Regisztráció", - "relation": "Kapcsolat", - "relation_type": "Kapcsolat típusa", - "relationship": "Kapcsolat", - "relationship_type": "Kapcsolat típusa", - "religion": "Vallás", - "remove": "Eltávolítás", - "residence": "Lakóhely", - "save": "Mentés", - "search": "Keresés", - "select": "Kiválasztás", - "select_all": "Összes kiválasztása", - "settings": "Beállítások", - "sibling": "Testvér", - "sign_in": "Bejelentkezés", - "sign_out": "Kijelentkezés", - "site_intro": "Üdvözöljük a Generációk Öröksége oldalán, ahol rögzítheti családfáját és megoszthatja családtörténetét szereteivel. Hozon létre digitális szellemi hagyatékot leszármazottai számára.", - "skill": "Képesség", - "skin_colour": "Bőrszín", - "source": "Forrás", - "source_url": "Forrás URL", - "spouse": "Házastárs", - "street": "Utca", - "suffixes": "Utótagok", - "system": "Rendszer", - "talent": "Tehetség", - "terms_and_conditions": "Felhasználási feltételek", - "theme": "Téma", - "title": "Generációk Öröksége {page}", - "titles": "Címek", - "tree": "Fa", - "unselect_all": "Összes kiválasztásának megszüntetése", - "unknown": "Ismeretlen", - "upload": "Feltöltés", - "vaccination": "Oltás", - "vegetable": "Zöldség", - "video": "Videó", - "website": "Weboldal", - "weight": "Súly", - "welcome": "Üdvözöljük a Generációk Öröksége oldalán", - "yes": "Igen", - "zip_code": "Irányítószám" + "favourite": "Kedvenc", + "favourite_recipes": "Kedvenc receptek", + "file": "Fájl", + "first_name": "Keresztnév", + "flower": "Virág", + "fruit": "Gyümölcs", + "hair_colour": "Hajszín", + "hello_world": "Helló, {name} innen: hu!", + "height": "Magasság", + "hobby": "Hobbi", + "home": "Otthon", + "id": "Azonosító", + "ideology": "Ideológia", + "illness": "Betegség", + "image": "Kép", + "ingridients": "Hozzávalók", + "interest": "Érdeklődés", + "language": "Nyelv", + "last_name": "Vezetéknév", + "life_events": "Életesemények", + "light": "Világos", + "loading": "Betöltés", + "login": "Bejelentkezés", + "logout": "Kijelentkezés", + "medication": "Gyógyszer", + "message_for_future_generations": "Üzenet a jövő generációinak", + "middle_name": "Második név", + "missing_field": "{field} mező hiányzik", + "mothers_first_name": "Anyja keresztneve", + "mothers_last_name": "Anyja vezetékneve", + "nation": "Nemzet", + "no": "Nem", + "no_data": "Nincs adat", + "notes": "Jegyzetek", + "occupation": "Foglalkozás", + "occupation_to_display": "Megjelenítendő foglalkozás", + "others_said": "Mások mondták", + "parent": "Szülő", + "people": "Emberek", + "person": "Személy", + "pet": "Háziállat", + "philosophy": "Filozófia", + "photos": "Fotók", + "place_of_birth": "Születési hely", + "place_of_death": "Halálozási hely", + "plant": "Növény", + "politics": "Politika", + "profile_picture": "Profilkép", + "privacy_policy": "Adatvédelmi irányelvek", + "recipe": "Recept", + "recipes": "Receptek", + "register": "Regisztráció", + "relation": "Kapcsolat", + "relation_type": "Kapcsolat típusa", + "relationship": "Kapcsolat", + "relationship_type": "Kapcsolat típusa", + "religion": "Vallás", + "remove": "Eltávolítás", + "residence": "Lakóhely", + "save": "Mentés", + "search": "Keresés", + "select": "Kiválasztás", + "select_all": "Összes kiválasztása", + "settings": "Beállítások", + "sibling": "Testvér", + "sign_in": "Bejelentkezés", + "sign_out": "Kijelentkezés", + "site_intro": "Üdvözöljük a Generációk Öröksége oldalán, ahol rögzítheti családfáját és megoszthatja családtörténetét szereteivel. Hozon létre digitális szellemi hagyatékot leszármazottai számára.", + "skill": "Képesség", + "skin_colour": "Bőrszín", + "source": "Forrás", + "source_url": "Forrás URL", + "spouse": "Házastárs", + "street": "Utca", + "suffixes": "Utótagok", + "system": "Rendszer", + "talent": "Tehetség", + "terms_and_conditions": "Felhasználási feltételek", + "theme": "Téma", + "title": "Generációk Öröksége {page}", + "titles": "Címek", + "tree": "Fa", + "unselect_all": "Összes kiválasztásának megszüntetése", + "unknown": "Ismeretlen", + "upload": "Feltöltés", + "vaccination": "Oltás", + "vegetable": "Zöldség", + "video": "Videó", + "website": "Weboldal", + "weight": "Súly", + "welcome": "Üdvözöljük a Generációk Öröksége oldalán", + "yes": "Igen", + "zip_code": "Irányítószám" } diff --git a/apps/app/package.json b/apps/app/package.json index d901aea..6f143f1 100644 --- a/apps/app/package.json +++ b/apps/app/package.json @@ -1,72 +1,72 @@ { - "name": "generations-heritage", - "private": true, - "version": "0.0.1", - "type": "module", - "scripts": { - "dev": "vite dev", - "build": "vite build", - "preview": "npm run build && wrangler pages dev", - "prepare": "svelte-kit sync || echo ''", - "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", - "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", - "format": "prettier --write .", - "lint": "prettier --check . && eslint .", - "test:unit": "vitest", - "test": "npm run test:unit -- --run", - "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build", - "deploy-stage": "npm run build && wrangler pages deploy --env staging", - "deploy-prod": "npm run build && wrangler pages deploy --env production", - "cf-typegen": "wrangler types && move worker-configuration.d.ts src/" - }, - "devDependencies": { - "@chromatic-com/storybook": "^3.2.4", - "@cloudflare/workers-types": "^4.20250214.0", - "@eslint/compat": "^1.2.5", - "@eslint/js": "^9.18.0", - "@playwright/test": "^1.50.1", - "@storybook/addon-essentials": "^8.5.6", - "@storybook/addon-interactions": "^8.5.6", - "@storybook/addon-svelte-csf": "^5.0.0-next.23", - "@storybook/blocks": "^8.5.6", - "@storybook/svelte": "^8.5.6", - "@storybook/sveltekit": "^8.5.6", - "@storybook/test": "^8.5.6", - "@sveltejs/adapter-auto": "^4.0.0", - "@sveltejs/adapter-cloudflare": "^5.0.3", - "@sveltejs/kit": "^2.16.0", - "@sveltejs/vite-plugin-svelte": "^5.0.0", - "@tailwindcss/postcss": "^4.0.12", - "@types/node": "^22.13.9", - "@vitest/coverage-v8": "^3.0.5", - "daisyui": "^5.0.0", - "eslint": "^9.18.0", - "eslint-config-prettier": "^10.0.1", - "eslint-plugin-svelte": "^2.46.1", - "globals": "^15.14.0", - "openapi-typescript": "^7.6.1", - "prettier": "^3.4.2", - "prettier-plugin-svelte": "^3.3.3", - "prettier-plugin-tailwindcss": "^0.6.11", - "storybook": "^8.5.6", - "svelte": "^5.0.0", - "svelte-check": "^4.0.0", - "tailwindcss": "^4.0.12", - "typescript": "^5.0.0", - "typescript-eslint": "^8.20.0", - "vite": "^6.0.0", - "vitest": "^3.0.0", - "wrangler": "^3.109.1" - }, - "dependencies": { - "@inlang/paraglide-sveltekit": "^0.15.5", - "@pilcrowjs/object-parser": "^0.0.4", - "@types/pikaday": "^1.7.9", - "@xyflow/svelte": "^1.0.0-next.3", - "arctic": "^3.3.0", - "neo4j-driver": "^5.28.1", - "openapi-fetch": "^0.13.5", - "pikaday": "^1.8.2" - } + "name": "generations-heritage", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "npm run build && wrangler pages dev", + "prepare": "svelte-kit sync || echo ''", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", + "format": "prettier --write .", + "lint": "prettier --check . && eslint .", + "test:unit": "vitest", + "test": "npm run test:unit -- --run", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build", + "deploy-stage": "npm run build && wrangler pages deploy --env staging", + "deploy-prod": "npm run build && wrangler pages deploy --env production", + "cf-typegen": "wrangler types && move worker-configuration.d.ts src/" + }, + "devDependencies": { + "@chromatic-com/storybook": "^3.2.4", + "@cloudflare/workers-types": "^4.20250214.0", + "@eslint/compat": "^1.2.5", + "@eslint/js": "^9.18.0", + "@playwright/test": "^1.50.1", + "@storybook/addon-essentials": "^8.5.6", + "@storybook/addon-interactions": "^8.5.6", + "@storybook/addon-svelte-csf": "^5.0.0-next.23", + "@storybook/blocks": "^8.5.6", + "@storybook/svelte": "^8.5.6", + "@storybook/sveltekit": "^8.5.6", + "@storybook/test": "^8.5.6", + "@sveltejs/adapter-auto": "^4.0.0", + "@sveltejs/adapter-cloudflare": "^5.0.3", + "@sveltejs/kit": "^2.16.0", + "@sveltejs/vite-plugin-svelte": "^5.0.0", + "@tailwindcss/postcss": "^4.0.12", + "@types/node": "^22.13.9", + "@vitest/coverage-v8": "^3.0.5", + "daisyui": "^5.0.0", + "eslint": "^9.18.0", + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-svelte": "^2.46.1", + "globals": "^15.14.0", + "openapi-typescript": "^7.6.1", + "prettier": "^3.4.2", + "prettier-plugin-svelte": "^3.3.3", + "prettier-plugin-tailwindcss": "^0.6.11", + "storybook": "^8.5.6", + "svelte": "^5.0.0", + "svelte-check": "^4.0.0", + "tailwindcss": "^4.0.12", + "typescript": "^5.0.0", + "typescript-eslint": "^8.20.0", + "vite": "^6.0.0", + "vitest": "^3.0.0", + "wrangler": "^3.109.1" + }, + "dependencies": { + "@inlang/paraglide-sveltekit": "^0.15.5", + "@pilcrowjs/object-parser": "^0.0.4", + "@types/pikaday": "^1.7.9", + "@xyflow/svelte": "^1.0.0-next.3", + "arctic": "^3.3.0", + "neo4j-driver": "^5.28.1", + "openapi-fetch": "^0.13.5", + "pikaday": "^1.8.2" + } } diff --git a/apps/app/playwright.config.ts b/apps/app/playwright.config.ts index efd9b88..9dbe87e 100644 --- a/apps/app/playwright.config.ts +++ b/apps/app/playwright.config.ts @@ -12,68 +12,68 @@ import { defineConfig, devices } from '@playwright/test'; * See https://playwright.dev/docs/test-configuration. */ export default defineConfig({ - testDir: './e2e', - /* Run tests in files in parallel */ - fullyParallel: true, - /* Fail the build on CI if you accidentally left test.only in the source code. */ - forbidOnly: !!process.env.CI, - /* Retry on CI only */ - retries: process.env.CI ? 2 : 0, - /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : undefined, - /* Reporter to use. See https://playwright.dev/docs/test-reporters */ - reporter: 'html', - /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ - use: { - /* Base URL to use in actions like `await page.goto('/')`. */ - // baseURL: 'http://127.0.0.1:3000', + testDir: './e2e', + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: 'html', + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + // baseURL: 'http://127.0.0.1:3000', - /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ - trace: 'on-first-retry', - }, + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry' + }, - /* Configure projects for major browsers */ - projects: [ - { - name: 'chromium', - use: { ...devices['Desktop Chrome'] }, - }, + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] } + }, - { - name: 'firefox', - use: { ...devices['Desktop Firefox'] }, - }, + { + name: 'firefox', + use: { ...devices['Desktop Firefox'] } + }, - { - name: 'webkit', - use: { ...devices['Desktop Safari'] }, - }, + { + name: 'webkit', + use: { ...devices['Desktop Safari'] } + } - /* Test against mobile viewports. */ - // { - // name: 'Mobile Chrome', - // use: { ...devices['Pixel 5'] }, - // }, - // { - // name: 'Mobile Safari', - // use: { ...devices['iPhone 12'] }, - // }, + /* Test against mobile viewports. */ + // { + // name: 'Mobile Chrome', + // use: { ...devices['Pixel 5'] }, + // }, + // { + // name: 'Mobile Safari', + // use: { ...devices['iPhone 12'] }, + // }, - /* Test against branded browsers. */ - // { - // name: 'Microsoft Edge', - // use: { ...devices['Desktop Edge'], channel: 'msedge' }, - // }, - // { - // name: 'Google Chrome', - // use: { ...devices['Desktop Chrome'], channel: 'chrome' }, - // }, - ], + /* Test against branded browsers. */ + // { + // name: 'Microsoft Edge', + // use: { ...devices['Desktop Edge'], channel: 'msedge' }, + // }, + // { + // name: 'Google Chrome', + // use: { ...devices['Desktop Chrome'], channel: 'chrome' }, + // }, + ] - /* Run your local dev server before starting the tests */ - // webServer: { - // command: 'npm run start', - // url: 'http://127.0.0.1:3000', - // reuseExistingServer: !process.env.CI, - // }, + /* Run your local dev server before starting the tests */ + // webServer: { + // command: 'npm run start', + // url: 'http://127.0.0.1:3000', + // reuseExistingServer: !process.env.CI, + // }, }); diff --git a/apps/app/postcss.config.js b/apps/app/postcss.config.js index c5c819c..85b958c 100644 --- a/apps/app/postcss.config.js +++ b/apps/app/postcss.config.js @@ -1,5 +1,5 @@ export default { plugins: { - '@tailwindcss/postcss': {}, + '@tailwindcss/postcss': {} } }; diff --git a/apps/app/src/app.css b/apps/app/src/app.css index dfaad23..c42017b 100644 --- a/apps/app/src/app.css +++ b/apps/app/src/app.css @@ -9,16 +9,24 @@ color utility to any element that depends on these defaults. */ @layer base { - *, - ::after, - ::before, - ::backdrop, - ::file-selector-button { - border-color: var(--color-gray-200, currentColor); - } - + *, + ::after, + ::before, + ::backdrop, + ::file-selector-button { + border-color: var(--color-gray-200, currentColor); + } } @plugin "daisyui" { - themes: light --default, dark --prefersdark, light, dark, cyberpunk, synthwave, retro, coffee, dracula; + themes: + light --default, + dark --prefersdark, + light, + dark, + cyberpunk, + synthwave, + retro, + coffee, + dracula; } diff --git a/apps/app/src/app.d.ts b/apps/app/src/app.d.ts index 6cf4fd3..9d3771a 100644 --- a/apps/app/src/app.d.ts +++ b/apps/app/src/app.d.ts @@ -3,18 +3,18 @@ import { KVNamespace } from '@cloudflare/workers-types'; // for information about these interfaces declare global { namespace App { - interface Locals { - session: Session | null; - } - interface Platform { - env: { - GH_MEDIA: R2Bucket; + interface Locals { + session: Session | null; + } + interface Platform { + env: { + GH_MEDIA: R2Bucket; GH_SESSIONS: KVNamespace; - }; - cf: CfProperties - ctx: ExecutionContext - } - } + }; + cf: CfProperties; + ctx: ExecutionContext; + } + } } -export {}; \ No newline at end of file +export {}; diff --git a/apps/app/src/hooks.server.ts b/apps/app/src/hooks.server.ts index 70ab421..05d3bfb 100644 --- a/apps/app/src/hooks.server.ts +++ b/apps/app/src/hooks.server.ts @@ -1,47 +1,51 @@ import type { Handle } from '@sveltejs/kit'; -import { themes } from '$lib/themes' +import { themes } from '$lib/themes'; import { i18n } from '$lib/i18n'; -import { validateSessionToken, setSessionTokenCookie, deleteSessionTokenCookie } from "$lib/server/session"; -import { sequence } from "@sveltejs/kit/hooks"; +import { + validateSessionToken, + setSessionTokenCookie, + deleteSessionTokenCookie +} from '$lib/server/session'; +import { sequence } from '@sveltejs/kit/hooks'; const handleParaglide: Handle = i18n.handle(); const authHandle: Handle = async ({ event, resolve }) => { - const token = event.cookies.get("session") ?? null; - if (token === null) { - event.locals.session = null; - return resolve(event); - } + const token = event.cookies.get('session') ?? null; + if (token === null) { + event.locals.session = null; + return resolve(event); + } - if(!event.platform || !event.platform.env || !event.platform.env.GH_SESSIONS){ - return new Response("Server configuration error. GH_SESSIONS KeyValue store missing", { + if (!event.platform || !event.platform.env || !event.platform.env.GH_SESSIONS) { + return new Response('Server configuration error. GH_SESSIONS KeyValue store missing', { status: 500 }); } - const session = await validateSessionToken(token, event.platform.env.GH_SESSIONS); - if (session !== null) { - setSessionTokenCookie(event, token, session.expiresAt); - } else { - deleteSessionTokenCookie(event); - } + const session = await validateSessionToken(token, event.platform.env.GH_SESSIONS); + if (session !== null) { + setSessionTokenCookie(event, token, session.expiresAt); + } else { + deleteSessionTokenCookie(event); + } - event.locals.session = session; - return resolve(event); + event.locals.session = session; + return resolve(event); }; const themeHandler: Handle = async ({ event, resolve }) => { - const theme = event.cookies.get('theme') + const theme = event.cookies.get('theme'); if (!theme || !themes.includes(theme)) { - return await resolve(event) + return await resolve(event); } return await resolve(event, { transformPageChunk: ({ html }) => { - return html.replace('data-theme=""', `data-theme="${theme}"`) - }, - }) -} + return html.replace('data-theme=""', `data-theme="${theme}"`); + } + }); +}; -export const handle: Handle = sequence(handleParaglide, authHandle,themeHandler); \ No newline at end of file +export const handle: Handle = sequence(handleParaglide, authHandle, themeHandler); diff --git a/apps/app/src/lib/api/api.gen.ts b/apps/app/src/lib/api/api.gen.ts index eda060b..eccde19 100644 --- a/apps/app/src/lib/api/api.gen.ts +++ b/apps/app/src/lib/api/api.gen.ts @@ -4,1355 +4,1375 @@ */ export interface paths { - "/health": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Check the health of the server */ - get: operations["healthCheck"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/person_and_relationship/{id}": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** Create a person and relationship */ - post: operations["createPersonAndRelationship"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/person": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** Create a new person */ - post: operations["createPerson"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/person/{id}": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - post?: never; - /** Soft delete a person by ID */ - delete: operations["softDeletePerson"]; - options?: never; - head?: never; - /** Update a person by ID */ - patch: operations["updatePerson"]; - trace?: never; - }; - "/person/{id}/hard-delete": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - post?: never; - /** Hard delete a person by ID */ - delete: operations["hardDeletePerson"]; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/person/google/{google_id}": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Get a person by Google ID */ - get: operations["getPersonByGoogleId"]; - put?: never; - /** Create a new person by Google ID */ - post: operations["createPersonByGoogleId"]; - delete?: never; - options?: never; - head?: never; - /** Create a new person by Google ID with invite code */ - patch: operations["createPersonByGoogleIdAndInviteCode"]; - trace?: never; - }; - "/person/{id}/family-tree": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Get family tree by person ID */ - get: operations["getFamilyTreeById"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/person/{id}/recipes": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Get recipes by person ID */ - get: operations["getRecipesByPersonId"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/relationship": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** Create a relationship between two persons */ - post: operations["createRelationship"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/relationship/{id1}/{id2}": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Get relationship between two persons */ - get: operations["getRelationship"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/recipe/{id}": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - post?: never; - /** Soft delete a recipe by ID */ - delete: operations["softDeleteRecipe"]; - options?: never; - head?: never; - /** Update a recipe by ID */ - patch: operations["updateRecipe"]; - trace?: never; - }; - "/recipe/{id}/hard-delete": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - post?: never; - /** Hard delete a recipe by ID */ - delete: operations["hardDeleteRecipe"]; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/recipe/{recipeId}/relationship": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** Create a relationship with an existing recipe */ - post: operations["createRecipeRelationship"]; - /** Delete a relationship with a recipe */ - delete: operations["deleteRecipeRelationship"]; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; + '/health': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Check the health of the server */ + get: operations['healthCheck']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/person_and_relationship/{id}': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Create a person and relationship */ + post: operations['createPersonAndRelationship']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/person': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Create a new person */ + post: operations['createPerson']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/person/{id}': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** Soft delete a person by ID */ + delete: operations['softDeletePerson']; + options?: never; + head?: never; + /** Update a person by ID */ + patch: operations['updatePerson']; + trace?: never; + }; + '/person/{id}/hard-delete': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** Hard delete a person by ID */ + delete: operations['hardDeletePerson']; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/person/google/{google_id}': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Get a person by Google ID */ + get: operations['getPersonByGoogleId']; + put?: never; + /** Create a new person by Google ID */ + post: operations['createPersonByGoogleId']; + delete?: never; + options?: never; + head?: never; + /** Create a new person by Google ID with invite code */ + patch: operations['createPersonByGoogleIdAndInviteCode']; + trace?: never; + }; + '/person/{id}/family-tree': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Get family tree by person ID */ + get: operations['getFamilyTreeById']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/person/{id}/recipes': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Get recipes by person ID */ + get: operations['getRecipesByPersonId']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/relationship': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Create a relationship between two persons */ + post: operations['createRelationship']; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/relationship/{id1}/{id2}': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Get relationship between two persons */ + get: operations['getRelationship']; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/recipe/{id}': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** Soft delete a recipe by ID */ + delete: operations['softDeleteRecipe']; + options?: never; + head?: never; + /** Update a recipe by ID */ + patch: operations['updateRecipe']; + trace?: never; + }; + '/recipe/{id}/hard-delete': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + /** Hard delete a recipe by ID */ + delete: operations['hardDeleteRecipe']; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + '/recipe/{recipeId}/relationship': { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Create a relationship with an existing recipe */ + post: operations['createRecipeRelationship']; + /** Delete a relationship with a recipe */ + delete: operations['deleteRecipeRelationship']; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; } export type webhooks = Record; export interface components { - schemas: { - PersonProperties: { - allow_admin_access?: { - id?: number; - name?: string; - }[] | null; - invite_code?: string | null; - google_id?: string | null; - first_name?: string | null; - middle_name?: string | null; - last_name?: string | null; - titles?: string[] | null; - suffixes?: string[] | null; - extra_names?: string[] | null; - aliases?: string[] | null; - mothers_first_name?: string | null; - mothers_last_name?: string | null; - /** Format: date */ - born?: string | null; - place_of_birth?: string | null; - /** Format: date */ - died?: string | null; - place_of_death?: string | null; - life_events?: { - /** Format: date */ - from?: string; - /** Format: date */ - to?: string; - description?: string; - }[] | null; - occupations?: string[] | null; - occupation_to_display?: string | null; - others_said?: { - id?: number; - name?: string; - relationship?: string; - description?: string; - url?: string | null; - }[] | null; - limit?: number | null; - photos?: { - url?: string; - description?: string; - /** Format: date */ - date?: string; - name?: string; - }[] | null; - videos?: { - url?: string; - description?: string; - /** Format: date */ - date?: string; - name?: string; - }[] | null; - audios?: { - url?: string; - description?: string; - /** Format: date */ - date?: string; - name?: string; - }[] | null; - profile_picture?: string | null; - verified?: boolean | null; - email?: string | null; - phone?: string | null; - residence?: { - city?: string; - country?: string; - zip_code?: string; - address_line_1?: string; - address_line_2?: string; - } | null; - religion?: string | null; - baptized?: string | null; - ideologies?: string[] | null; - blood_type?: string | null; - allergies?: string[] | null; - medications?: { - name?: string; - description?: string | null; - components?: string | null; - dosage?: string | null; - /** Format: date */ - from?: string | null; - /** Format: date */ - to?: string | null; - }[] | null; - medical_conditions?: Record[] | null; - height?: number | null; - weight?: number | null; - hair_colour?: string | null; - skin_colour?: string | null; - eye_colour?: string | null; - sports?: string[] | null; - hobbies?: string[] | null; - interests?: string[] | null; - languages?: { - language?: string; - level?: string | null; - }[] | null; - notes?: { - /** Format: date */ - date?: string | null; - title?: string | null; - note?: string; - url?: string | null; - }[] | null; - }; - PersonRegistration: { - first_name: string; - last_name: string; - /** Format: email */ - email?: string | null; - limit: number; - /** Format: date */ - born: string; - mothers_first_name: string; - mothers_last_name: string; - }; - Person: { - id?: number; - labels?: string[]; - type?: string | null; - properties?: components["schemas"]["PersonProperties"]; - }; - FamilyRelationship: { - verified?: boolean | null; - notes?: string | null; - /** Format: date */ - from?: string | null; - /** Format: date */ - to?: string | null; - }; - Relationship: { - id?: number; - label?: string; - type?: string | null; - start?: number; - end?: number; - properties?: components["schemas"]["FamilyRelationship"]; - }; - OptimizedPersonNode: { - id?: number; - labels?: string[]; - type?: string | null; - first_name?: string; - middle_name?: string; - last_name?: string; - /** Format: date */ - born?: string; - /** Format: date */ - died?: string | null; - }; - FamilyTree: { - ancestors?: components["schemas"]["OptimizedPersonNode"][]; - prel1?: components["schemas"]["Relationship"]; - children?: components["schemas"]["OptimizedPersonNode"][]; - prel2?: components["schemas"]["Relationship"]; - spouses?: string; - srel?: components["schemas"]["Relationship"]; - user?: string; - }; - RecipeProperties: { - name?: string | null; - origin?: string | null; - allow_admin_access?: { - id?: number; - name?: string; - }[]; - category?: string | null; - /** Format: date */ - first_recorded?: string | null; - description?: string | null; - ingredients?: string[] | null; - instructions?: string[] | null; - photo?: string | null; - notes?: string | null; - others_said?: { - id?: number; - name?: string; - said?: string; - }[] | null; - }; - Recipe: { - id?: number; - labels?: string[]; - properties?: components["schemas"]["RecipeProperties"]; - }; - Likes: { - id?: number; - label?: string; - start?: string; - end?: string; - properties?: components["schemas"]["LikesProperties"]; - }; - LikesProperties: { - favourite?: boolean | null; - like_it?: boolean | null; - could_make_it?: boolean | null; - }; - }; - responses: never; - parameters: never; - requestBodies: never; - headers: never; - pathItems: never; + schemas: { + PersonProperties: { + allow_admin_access?: + | { + id?: number; + name?: string; + }[] + | null; + invite_code?: string | null; + google_id?: string | null; + first_name?: string | null; + middle_name?: string | null; + last_name?: string | null; + titles?: string[] | null; + suffixes?: string[] | null; + extra_names?: string[] | null; + aliases?: string[] | null; + mothers_first_name?: string | null; + mothers_last_name?: string | null; + /** Format: date */ + born?: string | null; + place_of_birth?: string | null; + /** Format: date */ + died?: string | null; + place_of_death?: string | null; + life_events?: + | { + /** Format: date */ + from?: string; + /** Format: date */ + to?: string; + description?: string; + }[] + | null; + occupations?: string[] | null; + occupation_to_display?: string | null; + others_said?: + | { + id?: number; + name?: string; + relationship?: string; + description?: string; + url?: string | null; + }[] + | null; + limit?: number | null; + photos?: + | { + url?: string; + description?: string; + /** Format: date */ + date?: string; + name?: string; + }[] + | null; + videos?: + | { + url?: string; + description?: string; + /** Format: date */ + date?: string; + name?: string; + }[] + | null; + audios?: + | { + url?: string; + description?: string; + /** Format: date */ + date?: string; + name?: string; + }[] + | null; + profile_picture?: string | null; + verified?: boolean | null; + email?: string | null; + phone?: string | null; + residence?: { + city?: string; + country?: string; + zip_code?: string; + address_line_1?: string; + address_line_2?: string; + } | null; + religion?: string | null; + baptized?: string | null; + ideologies?: string[] | null; + blood_type?: string | null; + allergies?: string[] | null; + medications?: + | { + name?: string; + description?: string | null; + components?: string | null; + dosage?: string | null; + /** Format: date */ + from?: string | null; + /** Format: date */ + to?: string | null; + }[] + | null; + medical_conditions?: Record[] | null; + height?: number | null; + weight?: number | null; + hair_colour?: string | null; + skin_colour?: string | null; + eye_colour?: string | null; + sports?: string[] | null; + hobbies?: string[] | null; + interests?: string[] | null; + languages?: + | { + language?: string; + level?: string | null; + }[] + | null; + notes?: + | { + /** Format: date */ + date?: string | null; + title?: string | null; + note?: string; + url?: string | null; + }[] + | null; + }; + PersonRegistration: { + first_name: string; + last_name: string; + /** Format: email */ + email?: string | null; + limit: number; + /** Format: date */ + born: string; + mothers_first_name: string; + mothers_last_name: string; + }; + Person: { + id?: number; + labels?: string[]; + type?: string | null; + properties?: components['schemas']['PersonProperties']; + }; + FamilyRelationship: { + verified?: boolean | null; + notes?: string | null; + /** Format: date */ + from?: string | null; + /** Format: date */ + to?: string | null; + }; + Relationship: { + id?: number; + label?: string; + type?: string | null; + start?: number; + end?: number; + properties?: components['schemas']['FamilyRelationship']; + }; + OptimizedPersonNode: { + id?: number; + labels?: string[]; + type?: string | null; + first_name?: string; + middle_name?: string; + last_name?: string; + /** Format: date */ + born?: string; + /** Format: date */ + died?: string | null; + }; + FamilyTree: { + ancestors?: components['schemas']['OptimizedPersonNode'][]; + prel1?: components['schemas']['Relationship']; + children?: components['schemas']['OptimizedPersonNode'][]; + prel2?: components['schemas']['Relationship']; + spouses?: string; + srel?: components['schemas']['Relationship']; + user?: string; + }; + RecipeProperties: { + name?: string | null; + origin?: string | null; + allow_admin_access?: { + id?: number; + name?: string; + }[]; + category?: string | null; + /** Format: date */ + first_recorded?: string | null; + description?: string | null; + ingredients?: string[] | null; + instructions?: string[] | null; + photo?: string | null; + notes?: string | null; + others_said?: + | { + id?: number; + name?: string; + said?: string; + }[] + | null; + }; + Recipe: { + id?: number; + labels?: string[]; + properties?: components['schemas']['RecipeProperties']; + }; + Likes: { + id?: number; + label?: string; + start?: string; + end?: string; + properties?: components['schemas']['LikesProperties']; + }; + LikesProperties: { + favourite?: boolean | null; + like_it?: boolean | null; + could_make_it?: boolean | null; + }; + }; + responses: never; + parameters: never; + requestBodies: never; + headers: never; + pathItems: never; } export type $defs = Record; export interface operations { - healthCheck: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Server is healthy */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Server is unhealthy */ - 503: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; - createPersonAndRelationship: { - parameters: { - query?: never; - header: { - "X-User-ID": number; - }; - path: { - id: number; - }; - cookie?: never; - }; - requestBody: { - content: { - "application/json": { - person: components["schemas"]["PersonRegistration"]; - relationship: components["schemas"]["FamilyRelationship"]; - }; - }; - }; - responses: { - /** @description Person and relationship created */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - person?: components["schemas"]["Person"]; - relationship?: components["schemas"]["Relationship"]; - }; - }; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; - createPerson: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["PersonRegistration"]; - }; - }; - responses: { - /** @description Person created */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Person"]; - }; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; - softDeletePerson: { - parameters: { - query?: never; - header: { - "X-User-ID": number; - }; - path: { - id: number; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Person soft deleted */ - 200: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; - updatePerson: { - parameters: { - query?: never; - header: { - "X-User-ID": number; - }; - path: { - id: number; - }; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["PersonProperties"]; - }; - }; - responses: { - /** @description Person updated */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Person"]; - }; - }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; - hardDeletePerson: { - parameters: { - query?: never; - header: { - "X-User-ID": number; - }; - path: { - id: number; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Person hard deleted */ - 200: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; - getPersonByGoogleId: { - parameters: { - query?: never; - header?: never; - path: { - google_id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Person retrieved */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Person"]; - }; - }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; - createPersonByGoogleId: { - parameters: { - query?: never; - header?: never; - path: { - google_id: string; - }; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["PersonRegistration"]; - }; - }; - responses: { - /** @description Person created */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Person"]; - }; - }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; - createPersonByGoogleIdAndInviteCode: { - parameters: { - query?: never; - header?: never; - path: { - google_id: string; - }; - cookie?: never; - }; - requestBody: { - content: { - "application/json": { - invite_code?: string; - person?: components["schemas"]["PersonRegistration"]; - }; - }; - }; - responses: { - /** @description Person created */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Person"]; - }; - }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; - getFamilyTreeById: { - parameters: { - query?: never; - header?: never; - path: { - id: number; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Family tree retrieved */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["FamilyTree"]; - }; - }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; - getRecipesByPersonId: { - parameters: { - query?: never; - header: { - "X-User-ID": number; - }; - path: { - id: number; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Recipes retrieved */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - recipeRelations?: components["schemas"]["Likes"][]; - recipes?: components["schemas"]["Recipe"][]; - }; - }; - }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; - createRelationship: { - parameters: { - query?: never; - header: { - "X-User-ID": number; - }; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - "application/json": { - id1?: string; - id2?: string; - relationship?: components["schemas"]["FamilyRelationship"]; - }; - }; - }; - responses: { - /** @description Relationship created */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Relationship"]; - }; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; - getRelationship: { - parameters: { - query?: never; - header: { - "X-User-ID": number; - }; - path: { - id1: number; - id2: number; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Relationship retrieved */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Relationship"]; - }; - }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; - softDeleteRecipe: { - parameters: { - query?: never; - header: { - "X-User-ID": number; - }; - path: { - id: number; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Recipe soft deleted */ - 200: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; - updateRecipe: { - parameters: { - query?: never; - header: { - "X-User-ID": number; - }; - path: { - id: number; - }; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["RecipeProperties"]; - }; - }; - responses: { - /** @description Recipe updated */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Recipe"]; - }; - }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; - hardDeleteRecipe: { - parameters: { - query?: never; - header: { - "X-User-ID": number; - }; - path: { - id: number; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Recipe hard deleted */ - 200: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; - createRecipeRelationship: { - parameters: { - query?: never; - header: { - "X-User-ID": number; - }; - path: { - recipeId: number; - }; - cookie?: never; - }; - requestBody: { - content: { - "application/json": { - id: number; - relationship: { - schema?: components["schemas"]["LikesProperties"]; - }; - }; - }; - }; - responses: { - /** @description Relationship with recipe created */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["Likes"]; - }; - }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; - deleteRecipeRelationship: { - parameters: { - query: { - personId: number; - }; - header: { - "X-User-ID": number; - }; - path: { - recipeId: number; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description Relationship with recipe deleted */ - 200: { - headers: { - [name: string]: unknown; - }; - content?: never; - }; - /** @description Bad request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Unauthorized */ - 401: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - /** @description Internal server error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": { - msg?: string; - }; - }; - }; - }; - }; + healthCheck: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Server is healthy */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Server is unhealthy */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; + createPersonAndRelationship: { + parameters: { + query?: never; + header: { + 'X-User-ID': number; + }; + path: { + id: number; + }; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + person: components['schemas']['PersonRegistration']; + relationship: components['schemas']['FamilyRelationship']; + }; + }; + }; + responses: { + /** @description Person and relationship created */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + person?: components['schemas']['Person']; + relationship?: components['schemas']['Relationship']; + }; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; + createPerson: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': components['schemas']['PersonRegistration']; + }; + }; + responses: { + /** @description Person created */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Person']; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; + softDeletePerson: { + parameters: { + query?: never; + header: { + 'X-User-ID': number; + }; + path: { + id: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Person soft deleted */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; + updatePerson: { + parameters: { + query?: never; + header: { + 'X-User-ID': number; + }; + path: { + id: number; + }; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': components['schemas']['PersonProperties']; + }; + }; + responses: { + /** @description Person updated */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Person']; + }; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; + hardDeletePerson: { + parameters: { + query?: never; + header: { + 'X-User-ID': number; + }; + path: { + id: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Person hard deleted */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; + getPersonByGoogleId: { + parameters: { + query?: never; + header?: never; + path: { + google_id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Person retrieved */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Person']; + }; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; + createPersonByGoogleId: { + parameters: { + query?: never; + header?: never; + path: { + google_id: string; + }; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': components['schemas']['PersonRegistration']; + }; + }; + responses: { + /** @description Person created */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Person']; + }; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; + createPersonByGoogleIdAndInviteCode: { + parameters: { + query?: never; + header?: never; + path: { + google_id: string; + }; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + invite_code?: string; + person?: components['schemas']['PersonRegistration']; + }; + }; + }; + responses: { + /** @description Person created */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Person']; + }; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; + getFamilyTreeById: { + parameters: { + query?: never; + header?: never; + path: { + id: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Family tree retrieved */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['FamilyTree']; + }; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; + getRecipesByPersonId: { + parameters: { + query?: never; + header: { + 'X-User-ID': number; + }; + path: { + id: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Recipes retrieved */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + recipeRelations?: components['schemas']['Likes'][]; + recipes?: components['schemas']['Recipe'][]; + }; + }; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; + createRelationship: { + parameters: { + query?: never; + header: { + 'X-User-ID': number; + }; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + id1?: string; + id2?: string; + relationship?: components['schemas']['FamilyRelationship']; + }; + }; + }; + responses: { + /** @description Relationship created */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Relationship']; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; + getRelationship: { + parameters: { + query?: never; + header: { + 'X-User-ID': number; + }; + path: { + id1: number; + id2: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Relationship retrieved */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Relationship']; + }; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; + softDeleteRecipe: { + parameters: { + query?: never; + header: { + 'X-User-ID': number; + }; + path: { + id: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Recipe soft deleted */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; + updateRecipe: { + parameters: { + query?: never; + header: { + 'X-User-ID': number; + }; + path: { + id: number; + }; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': components['schemas']['RecipeProperties']; + }; + }; + responses: { + /** @description Recipe updated */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Recipe']; + }; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; + hardDeleteRecipe: { + parameters: { + query?: never; + header: { + 'X-User-ID': number; + }; + path: { + id: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Recipe hard deleted */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; + createRecipeRelationship: { + parameters: { + query?: never; + header: { + 'X-User-ID': number; + }; + path: { + recipeId: number; + }; + cookie?: never; + }; + requestBody: { + content: { + 'application/json': { + id: number; + relationship: { + schema?: components['schemas']['LikesProperties']; + }; + }; + }; + }; + responses: { + /** @description Relationship with recipe created */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': components['schemas']['Likes']; + }; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; + deleteRecipeRelationship: { + parameters: { + query: { + personId: number; + }; + header: { + 'X-User-ID': number; + }; + path: { + recipeId: number; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description Relationship with recipe deleted */ + 200: { + headers: { + [name: string]: unknown; + }; + content?: never; + }; + /** @description Bad request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Unauthorized */ + 401: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + /** @description Internal server error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + 'application/json': { + msg?: string; + }; + }; + }; + }; + }; } diff --git a/apps/app/src/lib/cookiesAlert.svelte b/apps/app/src/lib/cookiesAlert.svelte index 14677e3..7396e94 100644 --- a/apps/app/src/lib/cookiesAlert.svelte +++ b/apps/app/src/lib/cookiesAlert.svelte @@ -1,10 +1,20 @@ \ No newline at end of file + + + + +
+ + +
+ diff --git a/apps/app/src/lib/model.ts b/apps/app/src/lib/model.ts index 3362b1e..125653f 100644 --- a/apps/app/src/lib/model.ts +++ b/apps/app/src/lib/model.ts @@ -2,64 +2,64 @@ import { Node, Relationship, Date } from 'neo4j-driver'; import { Integer } from 'neo4j-driver'; export interface PersonProperties { - allow_admin_access: boolean; - google_id: string; - first_name: string; - middle_name?: string; - last_name: string; - titles?: string[]; // e.g. Jr., Sr., III - suffixes?: string[]; // e.g. Ph.D., M.D. - extra_names?: string[]; - aliases?: string[]; - mothers_first_name?: string; - mothers_last_name?: string; - born?: Date; - place_of_birth?: string; - died?: Date; - place_of_death?: string; - life_events?: { [key: string]: {from: Date, to:Date, desription: string} }[]; - occupations?: string[]; - occupation_to_display?: string; - others_said?: { [key: string]: string }; - limit: number; - photos?: { [key: string]: string }; - videos?: { [key: string]: string }; - audios?: { [key: string]: string }; - profile_picture?: string; - verified: boolean; - email?: string; - phone?: string; - residence?: { - city?: string; - country?: string; - zip_code?: string; - address_line_1?: string; - address_line_2?: string; - }; - religion?: string; - baptized?: string; - ideology?: string; - blood_type?: string; - allergies?: string[]; - medications?: string[]; - medical_conditions?: string[]; - height?: number; - weight?: number; - hair_colour?: string; - skin_colour?: string; - eye_colour?: string; - sports?: string[]; - hobbies?: string[]; - interests?: string[]; - languages?: { [key: string]: string }; - notes?: string; + allow_admin_access: boolean; + google_id: string; + first_name: string; + middle_name?: string; + last_name: string; + titles?: string[]; // e.g. Jr., Sr., III + suffixes?: string[]; // e.g. Ph.D., M.D. + extra_names?: string[]; + aliases?: string[]; + mothers_first_name?: string; + mothers_last_name?: string; + born?: Date; + place_of_birth?: string; + died?: Date; + place_of_death?: string; + life_events?: { [key: string]: { from: Date; to: Date; desription: string } }[]; + occupations?: string[]; + occupation_to_display?: string; + others_said?: { [key: string]: string }; + limit: number; + photos?: { [key: string]: string }; + videos?: { [key: string]: string }; + audios?: { [key: string]: string }; + profile_picture?: string; + verified: boolean; + email?: string; + phone?: string; + residence?: { + city?: string; + country?: string; + zip_code?: string; + address_line_1?: string; + address_line_2?: string; + }; + religion?: string; + baptized?: string; + ideology?: string; + blood_type?: string; + allergies?: string[]; + medications?: string[]; + medical_conditions?: string[]; + height?: number; + weight?: number; + hair_colour?: string; + skin_colour?: string; + eye_colour?: string; + sports?: string[]; + hobbies?: string[]; + interests?: string[]; + languages?: { [key: string]: string }; + notes?: string; } export interface FamilyRelationship { - verified: boolean; - notes?: string; - from?: Date; - to?: Date; + verified: boolean; + notes?: string; + from?: Date; + to?: Date; } export type Person = Node; @@ -69,36 +69,38 @@ export type Spouse = Relationship; export type Child = Relationship; export interface RecipeProperties { - id: string; - name: string; - origin: string; - category: string; - first_recorded: Date; - description: string; - ingredients: string[]; - instructions: string[]; - photo: string; - notes?: string; + id: string; + name: string; + origin: string; + category: string; + first_recorded: Date; + description: string; + ingredients: string[]; + instructions: string[]; + photo: string; + notes?: string; } export type Recipe = Node; -export type Likes = Relationship; +export type Likes = Relationship< + Integer, + { + favourite: boolean; + like_it: boolean; + could_make_it: boolean; + } +>; export interface FamilyTree { - ancestors: String; - prel1: FamilyRelationship; - children: String; - prel2: FamilyRelationship; - spouses: String; - srel: FamilyRelationship; - user: String; - + ancestors: String; + prel1: FamilyRelationship; + children: String; + prel2: FamilyRelationship; + spouses: String; + srel: FamilyRelationship; + user: String; } export interface FamilyMember { - person: Person; -} \ No newline at end of file + person: Person; +} diff --git a/apps/app/src/lib/server/oauth.ts b/apps/app/src/lib/server/oauth.ts index 1e4a11f..b63cfc6 100644 --- a/apps/app/src/lib/server/oauth.ts +++ b/apps/app/src/lib/server/oauth.ts @@ -1,4 +1,8 @@ -import { Google } from "arctic"; -import { GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_CALLBACK_URI } from "$env/static/private"; +import { Google } from 'arctic'; +import { GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_CALLBACK_URI } from '$env/static/private'; -export const google = new Google(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_CALLBACK_URI || "http://localhost:5173/login/google/callback"); \ No newline at end of file +export const google = new Google( + GOOGLE_CLIENT_ID, + GOOGLE_CLIENT_SECRET, + GOOGLE_CALLBACK_URI || 'http://localhost:5173/login/google/callback' +); diff --git a/apps/app/src/lib/server/session.ts b/apps/app/src/lib/server/session.ts index 76f2b09..cb7b12e 100644 --- a/apps/app/src/lib/server/session.ts +++ b/apps/app/src/lib/server/session.ts @@ -1,15 +1,18 @@ -import type { KVNamespace } from "@cloudflare/workers-types"; -import { encodeBase32, encodeHexLowerCase } from "@oslojs/encoding"; -import { sha256 } from "@oslojs/crypto/sha2"; +import type { KVNamespace } from '@cloudflare/workers-types'; +import { encodeBase32, encodeHexLowerCase } from '@oslojs/encoding'; +import { sha256 } from '@oslojs/crypto/sha2'; -import type { RequestEvent } from "@sveltejs/kit"; +import type { RequestEvent } from '@sveltejs/kit'; // in seconds const EXPIRATION_TTL: number = 60 * 60 * 24 * 7; -export async function validateSessionToken(token: string, sessions: KVNamespace): Promise { +export async function validateSessionToken( + token: string, + sessions: KVNamespace +): Promise { const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token))); - const session: Session | null = await sessions.get(sessionId, { type: "json" }); + const session: Session | null = await sessions.get(sessionId, { type: 'json' }); if (!session) { return null; @@ -33,21 +36,21 @@ export async function invalidateUserSessions(userId: number, sessions: KVNamespa } export function setSessionTokenCookie(event: RequestEvent, token: string, expiresAt: Date): void { - event.cookies.set("session", token, { + event.cookies.set('session', token, { httpOnly: true, - path: "/", + path: '/', secure: import.meta.env.PROD, - sameSite: "lax", + sameSite: 'lax', expires: expiresAt }); } export function deleteSessionTokenCookie(event: RequestEvent): void { - event.cookies.set("session", "", { + event.cookies.set('session', '', { httpOnly: true, - path: "/", + path: '/', secure: import.meta.env.PROD, - sameSite: "lax", + sameSite: 'lax', maxAge: 0 }); } @@ -59,7 +62,11 @@ export function generateSessionToken(): string { return token; } -export async function createSession(token: string, userId: string, sessions: KVNamespace): Promise { +export async function createSession( + token: string, + userId: string, + sessions: KVNamespace +): Promise { const sessionId = `${userId}:${encodeHexLowerCase(sha256(new TextEncoder().encode(token)))}`; const session: Session = { id: sessionId, diff --git a/apps/app/src/lib/switchToLanguage.test.ts b/apps/app/src/lib/switchToLanguage.test.ts index 32c9797..6a7d6e7 100644 --- a/apps/app/src/lib/switchToLanguage.test.ts +++ b/apps/app/src/lib/switchToLanguage.test.ts @@ -4,37 +4,37 @@ import { i18n } from '$lib/i18n'; import { goto } from '$app/navigation'; vi.mock('$lib/i18n', () => ({ - i18n: { - route: vi.fn().mockImplementation((translatedPath: string) => ''), - resolveRoute: vi.fn().mockImplementation((path: string, lang?: string) => '') - } + i18n: { + route: vi.fn().mockImplementation((translatedPath: string) => ''), + resolveRoute: vi.fn().mockImplementation((path: string, lang?: string) => '') + } })); vi.mock('$app/state', () => ({ - page: { - url: { - pathname: '/current-path' - } - } + page: { + url: { + pathname: '/current-path' + } + } })); vi.mock('$app/navigation', () => ({ - goto: vi.fn() + goto: vi.fn() })); describe('switchToLanguage', () => { - it('should switch to the new language', () => { - const newLanguage = 'en'; - const canonicalPath = '/canonical-path'; - const localisedPath = '/en/canonical-path'; + it('should switch to the new language', () => { + const newLanguage = 'en'; + const canonicalPath = '/canonical-path'; + const localisedPath = '/en/canonical-path'; - i18n.route.mockReturnValue(canonicalPath); - i18n.resolveRoute.mockReturnValue(localisedPath); + i18n.route.mockReturnValue(canonicalPath); + i18n.resolveRoute.mockReturnValue(localisedPath); - switchToLanguage(newLanguage); + switchToLanguage(newLanguage); - expect(i18n.route).toHaveBeenCalledWith('/current-path'); - expect(i18n.resolveRoute).toHaveBeenCalledWith(canonicalPath, newLanguage); - expect(goto).toHaveBeenCalledWith(localisedPath); - }); -}); \ No newline at end of file + expect(i18n.route).toHaveBeenCalledWith('/current-path'); + expect(i18n.resolveRoute).toHaveBeenCalledWith(canonicalPath, newLanguage); + expect(goto).toHaveBeenCalledWith(localisedPath); + }); +}); diff --git a/apps/app/src/lib/switchToLanguage.ts b/apps/app/src/lib/switchToLanguage.ts index 13d5fc8..fe191ca 100644 --- a/apps/app/src/lib/switchToLanguage.ts +++ b/apps/app/src/lib/switchToLanguage.ts @@ -4,7 +4,7 @@ import { page } from '$app/state'; import { goto } from '$app/navigation'; export function switchToLanguage(newLanguage: AvailableLanguageTag) { - const canonicalPath = i18n.route(page.url.pathname); - const localisedPath = i18n.resolveRoute(canonicalPath, newLanguage); - goto(localisedPath); -} \ No newline at end of file + const canonicalPath = i18n.route(page.url.pathname); + const localisedPath = i18n.resolveRoute(canonicalPath, newLanguage); + goto(localisedPath); +} diff --git a/apps/app/src/lib/theme-select.svelte b/apps/app/src/lib/theme-select.svelte index 3f91ca7..1b3b3ba 100644 --- a/apps/app/src/lib/theme-select.svelte +++ b/apps/app/src/lib/theme-select.svelte @@ -37,7 +37,7 @@ } - - diff --git a/apps/app/src/routes/login/+page.server.ts b/apps/app/src/routes/login/+page.server.ts index 41ba086..067f22f 100644 --- a/apps/app/src/routes/login/+page.server.ts +++ b/apps/app/src/routes/login/+page.server.ts @@ -1,11 +1,11 @@ -import { redirect } from "@sveltejs/kit"; +import { redirect } from '@sveltejs/kit'; -import type { RequestEvent } from "./$types"; +import type { RequestEvent } from './$types'; export async function load(event: RequestEvent) { if (event.locals.session !== null) { - return redirect(302, "/"); + return redirect(302, '/'); } - + return {}; -} \ No newline at end of file +} diff --git a/apps/app/src/routes/login/+page.svelte b/apps/app/src/routes/login/+page.svelte index 27a015c..ba661ba 100644 --- a/apps/app/src/routes/login/+page.svelte +++ b/apps/app/src/routes/login/+page.svelte @@ -17,7 +17,7 @@

{site_intro()}

- + { //prevent loading in developer mode, due to some issues with universal load, even if this is a server only ts,it will still run on client in dev mode idk - if (browser) { - return {} + if (browser) { + return {}; } - const storedState = event.cookies.get("google_oauth_state") ?? null; - const codeVerifier = event.cookies.get("google_code_verifier") ?? null; - const code = event.url.searchParams.get("code"); - const state = event.url.searchParams.get("state"); + const storedState = event.cookies.get('google_oauth_state') ?? null; + const codeVerifier = event.cookies.get('google_code_verifier') ?? null; + const code = event.url.searchParams.get('code'); + const state = event.url.searchParams.get('state'); if (storedState === null || codeVerifier === null || code === null || state === null) { - return error(400, { message: "Please restart the process." }) + return error(400, { message: 'Please restart the process.' }); } if (storedState !== state) { - return error(400, { message: "Please restart the process." }) + return error(400, { message: 'Please restart the process.' }); } let tokens: OAuth2Tokens; try { tokens = await google.validateAuthorizationCode(code, codeVerifier); } catch (e) { - return error(400, { message: "Failed to validate authorization code with " + e }); + return error(400, { message: 'Failed to validate authorization code with ' + e }); } // if (!event.platform || !event.platform.env || !event.platform.env.GH_SESSIONS) { @@ -47,10 +55,10 @@ export const load: PageServerLoad = async (event: RequestEvent) => { const claims = decodeIdToken(tokens.idToken()); const claimsParser = new ObjectParser(claims); - const sub = claimsParser.getString("sub"); - const family_name = claimsParser.getString("family_name"); - const first_name = claimsParser.getString("given_name"); - const email = claimsParser.getString("email"); + const sub = claimsParser.getString('sub'); + const family_name = claimsParser.getString('family_name'); + const first_name = claimsParser.getString('given_name'); + const email = claimsParser.getString('email'); const dbSession = DB.session(); const existingUser = await getUserFromGoogleId(dbSession, sub); @@ -62,7 +70,7 @@ export const load: PageServerLoad = async (event: RequestEvent) => { // const session = await createSession(sessionToken, eUser.get('elementId'), event.platform.env.GH_SESSIONS); // setSessionTokenCookie(event, sessionToken, session.expiresAt); - return redirect(302, "/"); + return redirect(302, '/'); } let personP: PersonProperties = { @@ -72,13 +80,13 @@ export const load: PageServerLoad = async (event: RequestEvent) => { email: email, allow_admin_access: false, limit: StorageLimit, - verified: false, + verified: false }; return { props: personP }; -} +}; export const actions: Actions = { register: register @@ -89,15 +97,15 @@ async function register(event: RequestEvent) { // if (!event.platform || !event.platform.env || !event.platform.env.GH_SESSIONS) { // return fail(500, { message: "Server configuration error. GH_SESSIONS KeyValue store missing" }); // } - const google_id = data.get('google_id') + const google_id = data.get('google_id'); if (google_id === null) { return fail(400, { message: missing_field({ - field: "google_id" + field: 'google_id' }) }); } - const first_name_f = data.get('first_name') + const first_name_f = data.get('first_name'); if (first_name_f === null) { return fail(400, { message: missing_field({ @@ -105,49 +113,44 @@ async function register(event: RequestEvent) { }) }); } - const last_name_f = data.get('last_name') + const last_name_f = data.get('last_name'); if (last_name_f === null) { return fail(400, { - message: - missing_field({ - field: last_name() - }) + message: missing_field({ + field: last_name() + }) }); } - const email = data.get('email') + const email = data.get('email'); if (email === null) { return fail(400, { - message: - missing_field({ - field: "Email" - }) + message: missing_field({ + field: 'Email' + }) }); } const birth_date = data.get('birth_date'); if (birth_date === null) { return fail(400, { - message: - missing_field({ - field: born() - }) + message: missing_field({ + field: born() + }) }); } const mothers_first_name_f = data.get('mothers_first_name'); if (mothers_first_name_f === null) { return fail(400, { - message: - missing_field({ - field: mothers_first_name() - }) + message: missing_field({ + field: mothers_first_name() + }) }); } const mothers_last_name_f = data.get('mothers_last_name'); if (mothers_last_name_f === null) { return fail(400, { - message: - missing_field({ - field: mothers_last_name() - }) + message: missing_field({ + field: mothers_last_name() + }) }); } @@ -158,12 +161,16 @@ async function register(event: RequestEvent) { first_name: first_name_f as string, last_name: last_name_f as string, email: email as string, - born: new neoDate(parsed_date.getFullYear(), parsed_date.getUTCMonth(), parsed_date.getUTCDate()), + born: new neoDate( + parsed_date.getFullYear(), + parsed_date.getUTCMonth(), + parsed_date.getUTCDate() + ), mothers_first_name: mothers_first_name_f as string, mothers_last_name: mothers_last_name_f as string, allow_admin_access: false, limit: StorageLimit, - verified: false, + verified: false }; const dbSession = DB.session(); @@ -179,5 +186,5 @@ async function register(event: RequestEvent) { // const session = await createSession(sessionToken, user.get('elementId'), event.platform.env.GH_SESSIONS); // setSessionTokenCookie(event, sessionToken, session.expiresAt); - return redirect(302, "/"); -} \ No newline at end of file + return redirect(302, '/'); +} diff --git a/apps/app/src/routes/login/google/callback/+page.svelte b/apps/app/src/routes/login/google/callback/+page.svelte index b40a845..6a42cac 100644 --- a/apps/app/src/routes/login/google/callback/+page.svelte +++ b/apps/app/src/routes/login/google/callback/+page.svelte @@ -12,7 +12,7 @@ last_name, first_name, email, - allow_family_tree_admin_access, + allow_family_tree_admin_access } from '$lib/paraglide/messages'; import FamilyTree from '../../highresolution_icon_no_background_croped.png'; let { data, form }: PageProps = $props(); @@ -49,24 +49,65 @@
{#if form?.message} -
- {/if } + + {/if} - - + + - + - - - + + + - + - - import Page from './+page.svelte'; + import Page from './+page.svelte'; \ No newline at end of file + + diff --git a/apps/app/src/stories/Button.stories.svelte b/apps/app/src/stories/Button.stories.svelte index 4c8c7cc..d11a56d 100644 --- a/apps/app/src/stories/Button.stories.svelte +++ b/apps/app/src/stories/Button.stories.svelte @@ -1,24 +1,24 @@ diff --git a/apps/app/src/stories/Button.svelte b/apps/app/src/stories/Button.svelte index b31f5bf..9ed8114 100644 --- a/apps/app/src/stories/Button.svelte +++ b/apps/app/src/stories/Button.svelte @@ -1,29 +1,29 @@ diff --git a/apps/app/src/stories/Configure.mdx b/apps/app/src/stories/Configure.mdx index 549973e..f74b88b 100644 --- a/apps/app/src/stories/Configure.mdx +++ b/apps/app/src/stories/Configure.mdx @@ -1,35 +1,37 @@ -import { Meta } from "@storybook/blocks"; +import { Meta } from '@storybook/blocks'; -import Github from "./assets/github.svg"; -import Discord from "./assets/discord.svg"; -import Youtube from "./assets/youtube.svg"; -import Tutorials from "./assets/tutorials.svg"; -import Styling from "./assets/styling.png"; -import Context from "./assets/context.png"; -import Assets from "./assets/assets.png"; -import Docs from "./assets/docs.png"; -import Share from "./assets/share.png"; -import FigmaPlugin from "./assets/figma-plugin.png"; -import Testing from "./assets/testing.png"; -import Accessibility from "./assets/accessibility.png"; -import Theming from "./assets/theming.png"; -import AddonLibrary from "./assets/addon-library.png"; +import Github from './assets/github.svg'; +import Discord from './assets/discord.svg'; +import Youtube from './assets/youtube.svg'; +import Tutorials from './assets/tutorials.svg'; +import Styling from './assets/styling.png'; +import Context from './assets/context.png'; +import Assets from './assets/assets.png'; +import Docs from './assets/docs.png'; +import Share from './assets/share.png'; +import FigmaPlugin from './assets/figma-plugin.png'; +import Testing from './assets/testing.png'; +import Accessibility from './assets/accessibility.png'; +import Theming from './assets/theming.png'; +import AddonLibrary from './assets/addon-library.png'; -export const RightArrow = () => - - +export const RightArrow = () => ( + + + +); @@ -38,6 +40,7 @@ export const RightArrow = () =>