not importing stuff from env

This commit is contained in:
matthieu42morin 2024-04-29 05:59:11 +02:00
parent 37880d297b
commit 68311ecd7c
13 changed files with 358 additions and 51 deletions

19
.development Normal file
View File

@ -0,0 +1,19 @@
# General
NODE_ENV=development
URARA_SITE_DOMAIN=localhost
URARA_SITE_PROTOCOL=http://
PUBLIC_SITE_URL=localhost:5173
# Sentry
PUBLIC_SENTRY_ORG=mattmor
PUBLIC_SENTRY_PROJECT=itspersonal
PUBLIC_SENTRY_KEY=cc0a2e656e0cbbcade519f24627044df
PUBLIC_SENTRY_PROJECT_ID=4506781187899392
PUBLIC_SENTRY_ORG_ID=o4505828687478784
SENTRY_AUTH_TOKEN="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"
SENTRT_LOG_LEVEL=debug
# Cloudinary
PUBLIC_CLOUDINARY_NAME=dbex8wss6
CLOUDINARY_API_KEY=998888477457534
CLOUDINARY_API_SECRET=E0-FptJ1rFiyxe9Z9F6SEr9CJns

View File

@ -0,0 +1,21 @@
name: Vercel Preview Deployment
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
on:
push:
branches-ignore:
- main
jobs:
Deploy-Preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Vercel CLI
run: npm install --global vercel@latest
- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
- name: Build Project Artifacts
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
- name: Deploy Project Artifacts to Vercel
run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }}

View File

@ -1,15 +1,6 @@
// https://gist.github.com/acoyfellow/d8e86979c66ebea25e1643594e38be73, Rodney Lab
import {
URARA_SITE_DOMAIN,
PUBLIC_SENTRY_KEY,
PUBLIC_SENTRY_PROJECT_ID,
PUBLIC_SENTRY_ORG_ID,
PUBLIC_WORKER_URL,
URARA_SITE_PROTOCOL
} from '$env/static/public'
console.log(`${URARA_SITE_PROTOCOL}${URARA_SITE_DOMAIN}`)
import { site } from '$lib/config/site'
import { PUBLIC_SENTRY_KEY, PUBLIC_SENTRY_PROJECT_ID, PUBLIC_SENTRY_ORG_ID } from '$env/static/public'
const directives = {
'base-uri': ["'self'"],
@ -21,10 +12,9 @@ const directives = {
'https://hcaptcha.com',
'https://*.hcaptcha.com',
'https://*.cartocdn.com',
URARA_SITE_DOMAIN,
PUBLIC_WORKER_URL
'https://*.mattmor.in/**'
],
'img-src': ["'self'", 'data:', 'https://images.unsplash.com', `${URARA_SITE_PROTOCOL}${URARA_SITE_DOMAIN}`],
'img-src': ["'self'", 'data:', 'https://images.unsplash.com', `${site.protocol}${site.domain}`],
'font-src': ["'self'", 'data:'],
'form-action': ["'self'"],
'frame-ancestors': ["'self'"],
@ -45,8 +35,8 @@ const directives = {
'style-src': ["'self'", "'unsafe-inline'", 'https://hcaptcha.com', 'https://*.hcaptcha.com'],
'default-src': [
"'self'",
URARA_SITE_DOMAIN,
`ws://${URARA_SITE_DOMAIN}`,
site.domain,
`ws://${site.domain}`,
// 'https://*.google.com',
// 'https://*.googleapis.com',
// 'https://*.firebase.com',

View File

@ -4,7 +4,7 @@ import { site } from '$lib/config/site'
import { handleErrorWithSentry, sentryHandle } from '@sentry/sveltekit'
import * as Sentry from '@sentry/sveltekit'
import { PUBLIC_SENTRY_KEY, PUBLIC_SENTRY_PROJECT_ID, PUBLIC_SENTRY_ORG_ID, URARA_SITE_DOMAIN } from '$env/static/public'
import { PUBLIC_SENTRY_KEY, PUBLIC_SENTRY_PROJECT_ID, PUBLIC_SENTRY_ORG_ID } from '$env/static/public'
import { csp } from './cspDirectives'
@ -23,7 +23,7 @@ export const cspHandle: Handle = async ({ event, resolve }) => {
const headers = {
'X-Frame-Options': 'SAMEORIGIN',
'Referrer-Policy': 'no-referrer',
'Permissions-Policy': `accelerometer=(), autoplay=(), camera=(), document-domain=(self, 'js-profiling'), encrypted-media=(), fullscreen=(self ${URARA_SITE_DOMAIN}), gyroscope=(), interest-cohort=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), sync-xhr=(), usb=(), xr-spatial-tracking=(), geolocation=()`,
'Permissions-Policy': `accelerometer=(), autoplay=(), camera=(), document-domain=(self, 'js-profiling'), encrypted-media=(), fullscreen=(self ${site.domain}), gyroscope=(), interest-cohort=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), sync-xhr=(), usb=(), xr-spatial-tracking=(), geolocation=()`,
'X-Content-Type-Options': 'nosniff',
// 'Content-Security-Policy-Report-Only': csp,
'Content-Security-Policy': csp,

View File

@ -1,6 +1,6 @@
<script lang="ts">
import GiteaLogo from '$lib/assets/logos/GiteaLogo.svelte';
import SocialsCloud from '$lib/components/SocialsCloud.svelte';
import SocialsCloud from '$lib/components/main/SocialsCloud.svelte';
const year = new Date().getFullYear();
</script>

View File

@ -1,32 +0,0 @@
<script lang="ts">
import socials from '$lib/config/socialsObjects';
import Envelope from '$lib/assets/Envelope.svelte'
export let mail: string = socials[0].href;
export let clazz: string = '';
export let w: number = 24;
export let h: number = 24;
</script>
<div class={` ${clazz}`}>
<svg xmlns="http://www.w3.org/2000/svg" lang="en-GB" aria-labelledby="title" class="w-[{w}px] h-[{h}px]">
<title id="title">Send me a mail!</title>
<defs />
<a href={mail} target="_blank" rel="noreferrer" aria-label="Send me a mail!">
<rect class="fill-current text-transparent" width="100%" height="100%" />
<foreignObject x="0" y="0" width="100%" height="100%">
<div class="email-icon-wrapper">
<Envelope />
</div>
</foreignObject>
</a>
</svg>
</div>
<style lang="postcss">
.email-icon-wrapper {
@apply flex items-center justify-center w-full h-full;
}
</style>

View File

@ -0,0 +1,32 @@
---
title: First post
excerpt: First post
date: 2021-01-01
tags:
- first
- post
published: true
image: Feature.jpg
---
## Svelte
Media inside the **Svelte** folder is served from the `static` folder.
```python
input_text = ''' "yahooapis.com",
"hotmail.com",
"gfx.ms",
"afx.ms",
"live.com",
'''
# and so on...
lines = input_text.split('\n')
formatted_lines = ['* ' + line.strip()[1:-2] + ' * block' for line in lines if line]
output_text = '\n'.join(formatted_lines)
print(output_text)
```

View File

@ -0,0 +1,12 @@
---
title: w post
excerpt: w post
date: 2021-01-01
tags:
- first
- post
published: true
image: Feature.jpg
---
## Svelte

View File

@ -0,0 +1,27 @@
---
title: Second post
excerpt: Second post
date: 2023-01-01
tags:
- first
- post
published: true
image: Feature.jpg
---
## Switching to Self-Hosted Git
You can check it out on git.mattmor.in, it's a simple encrypted gitea instance running on AWS
### Media
Media inside the **Svelte** folder is server from the `static` folder.
### Bye Bye Github with your fancy features
I am ditching the societal value of having a contributions table on my profile, you should view it on git.mattmor.in
--- If my contributions in 3d do not work, Github made breaking changes to their frontend and I can't scrape it anymore.

View File

@ -0,0 +1,15 @@
---
title: Erant
excerpt: A SaaS helping SMEs in the tourism sector with virtualization, customer experience & analytics. It got into the republic finale of Soutěž & Podnikej.
date: 2021-01-01
published: true
image: Feature.jpg
---
## Svelte
Media inside the **Svelte** folder is served from the `static` folder.
```python
```

View File

@ -0,0 +1,27 @@
---
title: Seedling
excerpt: An Iot Project, where we built a sensor system for plant care and accompanying app that alerted the user to what their plant needs. We made PCBs, industrial designs, 3D printed cases as clueless students.
date: 2021-01-01
published: true
image: Feature.jpg
---
This is a recollection of my first "startup" journey.
In 2020, after the onset of Covid, I remembered a presentation I heard from the founder of "Soutěž & Podnikej" Martin Vítek, on a meeting of the Prague Highschool Assembly.
It was an invitation to join their great program guiding highschoolers to launch an idea to financial fruition. The program, now sadly no longer operating, was inspirational to me as entrepreneurship and tech startups for me was a way to bring about a revolution, to solve a problem.
The journey that I embarked on, however, was not something I thought I signed up for.
I have not yet till that point in my life understood the deep rabbit hole of truly understanding a problem, the markets and people's needs, technical difficulties and the state of current technological developments, having the methodologies, networks of contacts and partners and capital at my disposal.
However what the program gave me was at least a brief outline of where to begin and how to progress. I began with a problem. As I was engaged in discussions and student organizations centered on ecology, especially thanks to being a part of many MUN and EYP conferences, I remembered a paper of the UN FAO called [2050: A third more mouths to feed](https://www.fao.org/newsroom/detail/2050-A-third-more-mouths-to-feed/), basically amongst the array of possibilities - water scarcity, food demand, population will increase
[Ben Einsteins LinkedIn post](https://www.linkedin.com/pulse/heres-why-juiceros-press-so-expensive-ben-einstein/) sums up the problem of Hardware startups
## Svelte
Media inside the **Svelte** folder is served from the `static` folder.
```python
```

163
src/lib/utils/helpers.ts Normal file
View File

@ -0,0 +1,163 @@
import { readable } from 'svelte/store';
import type { create_ssr_component } from 'svelte/internal';
/**
* Parses an object of data that has string keys and values of type `T` that have an optional `date` property.
* @param data - The object of data to parse.
* @param dateSort - A function that sorts an array of objects by their `date` property in descending order.
* @param mdPathToSlug - A function that converts an md file path to a slug.
* @returns An array of objects that have a `slug` property and the properties of the original data objects.
*/
export function parseReadContent<T extends { date?: string }>(data: Record<string, T>): T[] {
return Object.entries(data)
.map(([file, data]) => ({
slug: mdPathToSlug(file),
...data
}))
.sort(dateSort);
}
/**
* Sorts an array of objects by their `date` property in descending order.
* @param a - The first object to compare.
* @param b - The second object to compare.
* @returns A number that represents the difference between the parsed dates of the two objects.
*/
export function dateSort<T extends { date?: string }>(a: T, b: T): number {
return Date.parse(b.date) - Date.parse(a.date);
}
/**
* Renders an mdsvex component and returns the resulting HTML string.
* @param component - The mdsvex component to render.
* @returns The HTML string that was generated by rendering the component.
* @throws An error if the `render` property of the component is not a function.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function renderMdsvexComponent(component: any): string {
if (typeof component['render'] != 'function') {
throw new Error("Unable to render something that isn't a mdsvex component");
}
return (component as ReturnType<typeof create_ssr_component>).render().html;
}
/**
* Converts an md file path to a slug by removing the last segment of the path and the `.md` extension.
* @param path - The path of the md file.
* @returns The slug of the md file.
*/
export function mdPathToSlug(path: string) {
return path.split('/').at(-1).slice(0, -3);
}
/**
* Determines if the current timezone is between 0 and +3 hours UTC.
* @returns {boolean} True if the timezone is between 0 and +3 hours UTC, false otherwise.
*/
export const isEurope = () => {
const offset = new Date().getTimezoneOffset();
return offset <= 0 && offset >= -180; // Returns true if the timezone is between 0 and +3 hours UTC, false otherwise
};
/**
* Takes a string and returns a beautified version of it.
* @param str The input string to be beautified.
* @returns The beautified string.
*/
export const stringToBeautifiedFragment = (str = '') =>
(str || '').toLocaleLowerCase().replace(/\s/g, '-').replace(/\?/g, '').replace(/,/g, '');
/**
* Toggles the 'overflow-y-hidden' class on the 'html' element of the document.
* @param bool A boolean value indicating whether to show or hide the overflow-y scrollbar.
*/
export const showHideOverflowY = (bool: boolean) => {
const html = document.querySelector('html');
if (html) {
if (bool) {
html.classList.add('overflow-y-hidden');
} else {
html.classList.remove('overflow-y-hidden');
}
}
};
/**
* Scrolls to the first element that matches the given selector within the provided element.
* @param element The element to search within.
* @param selector The selector to match against.
*/
export const scrollToElement = async (element: HTMLElement, selector: string) => {
const firstElement: HTMLElement | null = element.querySelector(selector);
if (!firstElement) {
return;
}
firstElement.scrollIntoView({
behavior: 'smooth'
});
};
/**
* Checks if a given URL is an external link.
* @param href - The URL to check.
* @returns True if the URL is an external link, false otherwise.
*/
export const isAnExternalLink = (href: string) => href.startsWith('http');
/**
* Checks if the user agent is running on a Mac or iPad.
* @returns {boolean} Returns true if the user agent is running on a Mac or iPad, false otherwise.
*/
export const isMac = () =>
navigator.userAgent.includes('Macintosh') || navigator.userAgent.includes('iPad');
/**
* Removes the trailing slash from a given string.
* @param site - The string to remove the trailing slash from.
* @returns The string without the trailing slash.
*/
export const removeTrailingSlash = (site: string) => {
return site.replace(/\/$/, '');
};
/**
* Returns a readable store that tracks whether the media query string matches the current viewport.
* @param mediaQueryString - The media query string to match against the viewport.
* @returns A readable store that tracks whether the media query string matches the current viewport.
*/
export const useMediaQuery = (mediaQueryString: string) => {
const matches = readable<boolean | undefined>(undefined, (set) => {
if (typeof globalThis['window'] === 'undefined') return;
const match = window.matchMedia(mediaQueryString);
set(match.matches);
const element = (event: MediaQueryListEvent) => set(event.matches);
match.addEventListener('change', element);
return () => {
match.removeEventListener('change', element);
};
});
return matches;
};
/**
* Scrolls the page to the nearest element matching the given selector.
* @param selector - The CSS selector of the element to scroll to.
*/
export const scrollIntoView = (selector: string) => {
const scrollToElement = document.querySelector(selector);
if (!scrollToElement) return;
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
scrollToElement.scrollIntoView({
block: 'nearest',
inline: 'start',
behavior: mediaQuery.matches ? 'auto' : 'smooth'
});
};
export const generateURL = (href?: string, type: string, slug?: string) => {
if (href) return href;
return `/${type}/${slug}`;
};

33
src/lib/utils/images.ts Normal file
View File

@ -0,0 +1,33 @@
import { v2 as cloudinary } from 'cloudinary';
import { PUBLIC_CLOUDINARY_NAME } from '$env/static/public';
import { CLOUDINARY_API_KEY, CLOUDINARY_API_SECRET } from '$env/static/private';
cloudinary.config({
cloud_name: PUBLIC_CLOUDINARY_NAME,
api_key: CLOUDINARY_API_KEY,
api_secret: CLOUDINARY_API_SECRET
});
type ImageTransformationOptions = {
width?: number;
height?: number;
crop?: string;
format?: string;
quality?: string | number;
[key: string]: string;
};
export function getImageUrl(publicId: string, options: ImageTransformationOptions = {}): string {
return cloudinary.url(publicId, {
...options,
crop: options.crop || 'fill',
format: options.format || 'auto',
quality: options.quality || 'auto'
});
}
export const getImagePublicId = (imageKey: string) => {
return images[imageKey] || '';
};
export default cloudinary;