ui: redesign a lot

This commit is contained in:
Andras Bacsai 2022-08-09 15:28:26 +00:00
parent 839e8179fe
commit 4049af6220
46 changed files with 625 additions and 338 deletions

View File

@ -1,2 +1,6 @@
# Low - Destination/new is not working?
- Create previews model in Coolify DB - Check GitLab new repo
- Services new empty secret errors
- Services new empty storage errors
- New SSH key modal redesign
- Change license every package.json

View File

@ -1,5 +1,5 @@
{ {
"name": "coolify-api", "name": "api",
"description": "Coolify's Fastify API", "description": "Coolify's Fastify API",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"scripts": { "scripts": {

View File

@ -1,5 +1,5 @@
{ {
"name": "coolify-ui", "name": "ui",
"description": "Coolify's SvelteKit UI", "description": "Coolify's SvelteKit UI",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"scripts": { "scripts": {
@ -41,6 +41,7 @@
"@sveltejs/adapter-static": "1.0.0-next.37", "@sveltejs/adapter-static": "1.0.0-next.37",
"@zerodevx/svelte-toast": "0.7.2", "@zerodevx/svelte-toast": "0.7.2",
"cuid": "2.1.8", "cuid": "2.1.8",
"daisyui": "2.22.0",
"js-cookie": "3.0.1", "js-cookie": "3.0.1",
"p-limit": "4.0.0", "p-limit": "4.0.0",
"svelte-select": "4.4.7", "svelte-select": "4.4.7",

View File

@ -21,4 +21,5 @@ declare namespace App {
} }
declare const GITPOD_WORKSPACE_URL: string declare const GITPOD_WORKSPACE_URL: string

View File

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html data-theme="coollabs" lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" /> <link rel="icon" href="%sveltekit.assets%/favicon.png" />

View File

@ -1,4 +1,4 @@
import { toast } from '@zerodevx/svelte-toast'; import { addToast } from '$lib/store';
export const supportedServiceTypesAndVersions = [ export const supportedServiceTypesAndVersions = [
{ {
@ -167,12 +167,20 @@ export const asyncSleep = (delay: number) =>
export function errorNotification(error: any): void { export function errorNotification(error: any): void {
if (error.message) { if (error.message) {
if (error.message === 'Cannot read properties of undefined (reading \'postMessage\')') { if (error.message === 'Cannot read properties of undefined (reading \'postMessage\')') {
toast.push('Currently there is background process in progress. Please try again later.'); return addToast({
return; message: 'Currently there is background process in progress. Please try again later.',
type: 'error',
});
} }
toast.push(error.message); addToast({
message: error.message,
type: 'error',
});
} else { } else {
toast.push('Ooops, something is not okay, are you okay?'); addToast({
message: 'Ooops, something is not okay, are you okay?',
type: 'error',
});
} }
console.error(JSON.stringify(error)); console.error(JSON.stringify(error));
} }

View File

@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import { browser } from '$app/env'; import { browser } from '$app/env';
import { addToast } from '$lib/store';
import { toast } from '@zerodevx/svelte-toast'; import { toast } from '@zerodevx/svelte-toast';
let showPassword = false; let showPassword = false;
@ -20,7 +21,10 @@
function copyToClipboard() { function copyToClipboard() {
if (isHttps && navigator.clipboard) { if (isHttps && navigator.clipboard) {
navigator.clipboard.writeText(value); navigator.clipboard.writeText(value);
toast.push('Copied to clipboard.'); addToast({
message: 'Copied to clipboard.',
type: 'success',
});
} }
} }
</script> </script>

View File

@ -0,0 +1,52 @@
<script>
export let type = 'info';
</script>
<div
class="alert shadow-lg text-white rounded"
class:alert-success={type === 'success'}
class:alert-error={type === 'error'}
class:alert-info={type === 'info'}
>
{#if type === 'success'}
<svg
xmlns="http://www.w3.org/2000/svg"
class="stroke-current flex-shrink-0 h-6 w-6"
fill="none"
viewBox="0 0 24 24"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
/></svg
>
{:else if type === 'error'}
<svg
xmlns="http://www.w3.org/2000/svg"
class="stroke-current flex-shrink-0 h-6 w-6"
fill="none"
viewBox="0 0 24 24"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
/></svg
>
{:else if type === 'info'}
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
class="stroke-current flex-shrink-0 w-6 h-6"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/></svg
>
{/if}
<slot />
</div>

View File

@ -0,0 +1,22 @@
<script lang="ts">
import { fade } from 'svelte/transition';
import Toast from './Toast.svelte';
import { toasts } from '$lib/store';
</script>
{#if $toasts}
<section>
<article class="toast toast-bottom toast-end rounded-none" role="alert" transition:fade>
{#each $toasts as toast (toast.id)}
<Toast type={toast.type}>{toast.message}</Toast>
{/each}
</article>
</section>
{/if}
<style lang="postcss">
section {
@apply fixed top-0 left-0 right-0 w-full flex flex-col mt-4 justify-center z-[1000];
}
</style>

View File

@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { dev } from '$app/env'; import { dev } from '$app/env';
import { get, post } from '$lib/api'; import { get, post } from '$lib/api';
import { appSession, features } from '$lib/store'; import { addToast, appSession, features } from '$lib/store';
import { toast } from '@zerodevx/svelte-toast'; import { toast } from '@zerodevx/svelte-toast';
import { asyncSleep, errorNotification } from '$lib/common'; import { asyncSleep, errorNotification } from '$lib/common';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
@ -22,7 +22,11 @@
return window.location.reload(); return window.location.reload();
} else { } else {
await post(`/update`, { type: 'update', latestVersion }); await post(`/update`, { type: 'update', latestVersion });
toast.push('Update completed.<br><br>Waiting for the new version to start...'); addToast({
message: 'Update completed.<br><br>Waiting for the new version to start...',
type: 'success'
});
let reachable = false; let reachable = false;
let tries = 0; let tries = 0;
do { do {
@ -36,7 +40,10 @@
if (reachable) break; if (reachable) break;
tries++; tries++;
} while (!reachable || tries < 120); } while (!reachable || tries < 120);
toast.push('New version reachable. Reloading...'); addToast({
message: 'New version reachable. Reloading...',
type: 'success'
});
updateStatus.loading = false; updateStatus.loading = false;
updateStatus.success = true; updateStatus.success = true;
await asyncSleep(3000); await asyncSleep(3000);

View File

@ -19,9 +19,10 @@
}; };
let usageInterval: any; let usageInterval: any;
let loading = { let loading = {
usage: false usage: false,
cleanup: false
}; };
import { appSession } from '$lib/store'; import { addToast, appSession } from '$lib/store';
import { onDestroy, onMount } from 'svelte'; import { onDestroy, onMount } from 'svelte';
import { get, post } from '$lib/api'; import { get, post } from '$lib/api';
import { errorNotification } from '$lib/common'; import { errorNotification } from '$lib/common';
@ -60,7 +61,18 @@
disk: 'stable' disk: 'stable'
}; };
async function manuallyCleanupStorage() { async function manuallyCleanupStorage() {
return await post('/internal/cleanup', {}); try {
loading.cleanup = true
await post('/internal/cleanup', {});
return addToast({
message: "Cleanup done.",
type:"success"
})
} catch(error) {
return errorNotification(error);
} finally {
loading.cleanup = false
}
} }
</script> </script>
@ -132,7 +144,7 @@
<dd class="mt-1 text-3xl font-semibold text-white"> <dd class="mt-1 text-3xl font-semibold text-white">
{usage?.disk.usedGb}<span class="text-sm">GB</span> {usage?.disk.usedGb}<span class="text-sm">GB</span>
</dd> </dd>
<button on:click={manuallyCleanupStorage} class="bg-coollabs hover:bg-coollabs-100" <button on:click={manuallyCleanupStorage} class:loading={loading.cleanup} class="btn btn-sm"
>Cleanup Storage</button >Cleanup Storage</button
> >
</div> </div>

View File

@ -88,7 +88,7 @@
"removing": "Removing...", "removing": "Removing...",
"remove_domain": "Remove domain", "remove_domain": "Remove domain",
"public_port_range": "Public Port Range", "public_port_range": "Public Port Range",
"public_port_range_explainer": "Ports used to expose databases/services/internal services.<br> Add them to your firewall (if applicable).<br><br>You can specify a range of ports, eg: <span class='text-yellow-500 font-bold'>9000-9100</span>", "public_port_range_explainer": "Ports used to expose databases/services/internal services.<br> Add them to your firewall (if applicable).<br><br>You can specify a range of ports, eg: <span class='text-settings font-bold'>9000-9100</span>",
"no_actions_available": "No actions available", "no_actions_available": "No actions available",
"admin_api_key": "Admin API key" "admin_api_key": "Admin API key"
}, },
@ -144,8 +144,8 @@
}, },
"preview": { "preview": {
"need_during_buildtime": "Need during buildtime?", "need_during_buildtime": "Need during buildtime?",
"setup_secret_app_first": "You can add secrets to PR/MR deployments. Please add secrets to the application first. <br>Useful for creating <span class='text-green-500 font-bold'>staging</span> environments.", "setup_secret_app_first": "You can add secrets to PR/MR deployments. Please add secrets to the application first. <br>Useful for creating <span class='text-applications font-bold'>staging</span> environments.",
"values_overwriting_app_secrets": "These values overwrite application secrets in PR/MR deployments. Useful for creating <span class='text-green-500 font-bold'>staging</span> environments.", "values_overwriting_app_secrets": "These values overwrite application secrets in PR/MR deployments. Useful for creating <span class='text-applications font-bold'>staging</span> environments.",
"redeploy": "Redeploy", "redeploy": "Redeploy",
"no_previews_available": "No previews available" "no_previews_available": "No previews available"
}, },
@ -194,14 +194,14 @@
"application": "Application", "application": "Application",
"url_fqdn": "URL (FQDN)", "url_fqdn": "URL (FQDN)",
"domain_fqdn": "Domain (FQDN)", "domain_fqdn": "Domain (FQDN)",
"https_explainer": "If you specify <span class='text-green-500 font-bold'>https</span>, the application will be accessible only over https. SSL certificate will be generated for you.<br>If you specify <span class='text-green-500 font-bold'>www</span>, the application will be redirected (302) from non-www and vice versa.<br><br>To modify the domain, you must first stop the application.<br><br><span class='text-white font-bold'>You must set your DNS to point to the server IP in advance.</span>", "https_explainer": "If you specify <span class='text-applications font-bold'>https</span>, the application will be accessible only over https. SSL certificate will be generated for you.<br>If you specify <span class='text-applications font-bold'>www</span>, the application will be redirected (302) from non-www and vice versa.<br><br>To modify the domain, you must first stop the application.<br><br><span class='text-white font-bold'>You must set your DNS to point to the server IP in advance.</span>",
"ssl_www_and_non_www": "Generate SSL for www and non-www?", "ssl_www_and_non_www": "Generate SSL for www and non-www?",
"ssl_explainer": "It will generate certificates for both www and non-www. <br>You need to have <span class='font-bold text-green-500'>both DNS entries</span> set in advance.<br><br>Useful if you expect to have visitors on both.", "ssl_explainer": "It will generate certificates for both www and non-www. <br>You need to have <span class='font-bold text-applications'>both DNS entries</span> set in advance.<br><br>Useful if you expect to have visitors on both.",
"install_command": "Install Command", "install_command": "Install Command",
"build_command": "Build Command", "build_command": "Build Command",
"start_command": "Start Command", "start_command": "Start Command",
"directory_to_use_explainer": "Directory to use as the base for all commands.<br>Could be useful with <span class='text-green-500 font-bold'>monorepos</span>.", "directory_to_use_explainer": "Directory to use as the base for all commands.<br>Could be useful with <span class='text-applications font-bold'>monorepos</span>.",
"publish_directory_explainer": "Directory containing all the assets for deployment. <br> For example: <span class='text-green-500 font-bold'>dist</span>,<span class='text-green-500 font-bold'>_site</span> or <span class='text-green-500 font-bold'>public</span>.", "publish_directory_explainer": "Directory containing all the assets for deployment. <br> For example: <span class='text-applications font-bold'>dist</span>,<span class='text-applications font-bold'>_site</span> or <span class='text-applications font-bold'>public</span>.",
"features": "Features", "features": "Features",
"enable_automatic_deployment": "Enable Automatic Deployment", "enable_automatic_deployment": "Enable Automatic Deployment",
"enable_auto_deploy_webhooks": "Enable automatic deployment through webhooks.", "enable_auto_deploy_webhooks": "Enable automatic deployment through webhooks.",
@ -306,7 +306,7 @@
"change_language": "Change Language", "change_language": "Change Language",
"permission_denied": "You do not have permission to do this. \\nAsk an admin to modify your permissions.", "permission_denied": "You do not have permission to do this. \\nAsk an admin to modify your permissions.",
"domain_removed": "Domain removed", "domain_removed": "Domain removed",
"ssl_explainer": "If you specify <span class='text-yellow-500 font-bold'>https</span>, Coolify will be accessible only over https. SSL certificate will be generated for you.<br>If you specify <span class='text-yellow-500 font-bold'>www</span>, Coolify will be redirected (302) from non-www and vice versa.<br><br><span class='text-yellow-500 font-bold'>WARNING:</span> If you change an already set domain, it will brake webhooks and other integrations! You need to manually update them.", "ssl_explainer": "If you specify <span class='text-settings font-bold'>https</span>, Coolify will be accessible only over https. SSL certificate will be generated for you.<br>If you specify <span class='text-settings font-bold'>www</span>, Coolify will be redirected (302) from non-www and vice versa.<br><br><span class='text-settings font-bold'>WARNING:</span> If you change an already set domain, it will brake webhooks and other integrations! You need to manually update them.",
"must_remove_domain_before_changing": "Must remove the domain before you can change this setting.", "must_remove_domain_before_changing": "Must remove the domain before you can change this setting.",
"registration_allowed": "Registration allowed?", "registration_allowed": "Registration allowed?",
"registration_allowed_explainer": "Allow further registrations to the application. <br>It's turned off after the first registration.", "registration_allowed_explainer": "Allow further registrations to the application. <br>It's turned off after the first registration.",
@ -314,7 +314,7 @@
"credential_stat_explainer": "Credentials for <a class=\"text-white font-bold\" href=\"{{link}}\" target=\"_blank\">stats</a> page.", "credential_stat_explainer": "Credentials for <a class=\"text-white font-bold\" href=\"{{link}}\" target=\"_blank\">stats</a> page.",
"auto_update_enabled": "Auto update enabled?", "auto_update_enabled": "Auto update enabled?",
"auto_update_enabled_explainer": "Enable automatic updates for Coolify. It will be done automatically behind the scenes, if there is no build process running.", "auto_update_enabled_explainer": "Enable automatic updates for Coolify. It will be done automatically behind the scenes, if there is no build process running.",
"generate_www_non_www_ssl": "It will generate certificates for both www and non-www. <br>You need to have <span class='font-bold text-yellow-500'>both DNS entries</span> set in advance.", "generate_www_non_www_ssl": "It will generate certificates for both www and non-www. <br>You need to have <span class='font-bold text-settings'>both DNS entries</span> set in advance.",
"is_dns_check_enabled": "DNS check enabled?", "is_dns_check_enabled": "DNS check enabled?",
"is_dns_check_enabled_explainer": "You can disable DNS check before creating SSL certificates.<br><br>Turning it off is useful when Coolify is behind a reverse proxy or tunnel." "is_dns_check_enabled_explainer": "You can disable DNS check before creating SSL certificates.<br><br>Turning it off is useful when Coolify is behind a reverse proxy or tunnel."
}, },

View File

@ -50,7 +50,7 @@
"delete_application": "Supprimer l'application", "delete_application": "Supprimer l'application",
"deployment_queued": "Déploiement en file d'attente.", "deployment_queued": "Déploiement en file d'attente.",
"destination": "Destination", "destination": "Destination",
"directory_to_use_explainer": "Répertoire à utiliser comme base pour toutes les commandes.<br>Pourrait être utile avec <span class='text-green-500 font-bold'>monorepos</span>.", "directory_to_use_explainer": "Répertoire à utiliser comme base pour toutes les commandes.<br>Pourrait être utile avec <span class='text-applications font-bold'>monorepos</span>.",
"dns_not_set_error": "DNS non défini ou propagé pour {{domain}}.<br><br>Veuillez vérifier vos paramètres DNS.", "dns_not_set_error": "DNS non défini ou propagé pour {{domain}}.<br><br>Veuillez vérifier vos paramètres DNS.",
"dns_not_set_partial_error": "DNS non défini", "dns_not_set_partial_error": "DNS non défini",
"domain_already_in_use": "Le domaine {{domain}} est déjà utilisé.", "domain_already_in_use": "Le domaine {{domain}} est déjà utilisé.",
@ -65,7 +65,7 @@
"features": "Caractéristiques", "features": "Caractéristiques",
"git_repository": "Dépôt Git", "git_repository": "Dépôt Git",
"git_source": "Source Git", "git_source": "Source Git",
"https_explainer": "Si vous spécifiez <span class='text-green-500 font-bold'>https</span>, l'application sera accessible uniquement via https. \nUn certificat SSL sera généré pour vous.<br>Si vous spécifiez <span class='text-green-500 font-bold'>www</span>, l'application sera redirigée (302) à partir de non-www et vice versa \n.<br><br>Pour modifier le domaine, vous devez d'abord arrêter l'application.<br><br><span class='text-white font-bold'>Vous devez configurer, en avance, votre DNS pour pointer vers l'IP du serveur.</span>", "https_explainer": "Si vous spécifiez <span class='text-applications font-bold'>https</span>, l'application sera accessible uniquement via https. \nUn certificat SSL sera généré pour vous.<br>Si vous spécifiez <span class='text-applications font-bold'>www</span>, l'application sera redirigée (302) à partir de non-www et vice versa \n.<br><br>Pour modifier le domaine, vous devez d'abord arrêter l'application.<br><br><span class='text-white font-bold'>Vous devez configurer, en avance, votre DNS pour pointer vers l'IP du serveur.</span>",
"install_command": "Commande d'installation", "install_command": "Commande d'installation",
"logs": "Journaux des applications", "logs": "Journaux des applications",
"no_applications_found": "Aucune application trouvée", "no_applications_found": "Aucune application trouvée",
@ -78,11 +78,11 @@
"need_during_buildtime": "Besoin pendant la build ?", "need_during_buildtime": "Besoin pendant la build ?",
"no_previews_available": "Aucun aperçu disponible", "no_previews_available": "Aucun aperçu disponible",
"redeploy": "Redéployer", "redeploy": "Redéployer",
"setup_secret_app_first": "Vous pouvez ajouter des secrets aux déploiements PR/MR. \nVeuillez d'abord ajouter des secrets à l'application. \n<br>Utile pour créer des environnements <span class='text-green-500 font-bold'>de mise en scène</span>.", "setup_secret_app_first": "Vous pouvez ajouter des secrets aux déploiements PR/MR. \nVeuillez d'abord ajouter des secrets à l'application. \n<br>Utile pour créer des environnements <span class='text-applications font-bold'>de mise en scène</span>.",
"values_overwriting_app_secrets": "Ces valeurs remplacent les secrets d'application dans les déploiements PR/MR. \nUtile pour créer des environnements <span class='text-green-500 font-bold'>de mise en scène</span>." "values_overwriting_app_secrets": "Ces valeurs remplacent les secrets d'application dans les déploiements PR/MR. \nUtile pour créer des environnements <span class='text-applications font-bold'>de mise en scène</span>."
}, },
"previews": "Aperçus", "previews": "Aperçus",
"publish_directory_explainer": "Répertoire contenant tous les actifs à déployer. \n<br> Par exemple : <span class='text-green-500 font-bold'>dist</span>,<span class='text-green-500 font-bold'>_site</span> ou <span \nclass='text-green-500 font-bold'>public</span>.", "publish_directory_explainer": "Répertoire contenant tous les actifs à déployer. \n<br> Par exemple : <span class='text-applications font-bold'>dist</span>,<span class='text-applications font-bold'>_site</span> ou <span \nclass='text-applications font-bold'>public</span>.",
"rebuild_application": "Re-build l'application", "rebuild_application": "Re-build l'application",
"secret": "secrets", "secret": "secrets",
"secrets": { "secrets": {
@ -91,7 +91,7 @@
"use_isbuildsecret": "Utiliser isBuildSecret" "use_isbuildsecret": "Utiliser isBuildSecret"
}, },
"settings_saved": "Paramètres sauvegardés.", "settings_saved": "Paramètres sauvegardés.",
"ssl_explainer": "Il générera des certificats pour www et non-www. \n<br>Vous devez avoir <span class='font-bold text-green-500'>les deux entrées DNS</span> définies à l'avance.<br><br>Utile si vous prévoyez d'avoir des visiteurs sur les deux.", "ssl_explainer": "Il générera des certificats pour www et non-www. \n<br>Vous devez avoir <span class='font-bold text-applications'>les deux entrées DNS</span> définies à l'avance.<br><br>Utile si vous prévoyez d'avoir des visiteurs sur les deux.",
"ssl_www_and_non_www": "Générer SSL pour www et non-www ?", "ssl_www_and_non_www": "Générer SSL pour www et non-www ?",
"start_command": "Démarrer la commande", "start_command": "Démarrer la commande",
"stop_application": "Arrêter l'application", "stop_application": "Arrêter l'application",
@ -181,7 +181,7 @@
"path": "Chemin", "path": "Chemin",
"port": "Port", "port": "Port",
"public_port_range": "Gamme de ports publics", "public_port_range": "Gamme de ports publics",
"public_port_range_explainer": "Ports utilisés pour exposer les bases de données/services/services internes.<br> Ajoutez-les à votre pare-feu (le cas échéant).<br><br>Vous pouvez spécifier une plage de ports, par exemple : <span class='text-yellow-500 \nfont-bold'>9000-9100</span>", "public_port_range_explainer": "Ports utilisés pour exposer les bases de données/services/services internes.<br> Ajoutez-les à votre pare-feu (le cas échéant).<br><br>Vous pouvez spécifier une plage de ports, par exemple : <span class='text-settings \nfont-bold'>9000-9100</span>",
"publish_directory": "Publier le répertoire", "publish_directory": "Publier le répertoire",
"remove": "Retirer", "remove": "Retirer",
"remove_domain": "Supprimer le domaine", "remove_domain": "Supprimer le domaine",
@ -266,7 +266,7 @@
"permission_denied": "Vous n'avez pas la permission de faire cela. \n\\nDemandez à un administrateur de modifier vos autorisations.", "permission_denied": "Vous n'avez pas la permission de faire cela. \n\\nDemandez à un administrateur de modifier vos autorisations.",
"registration_allowed": "Inscription autorisée ?", "registration_allowed": "Inscription autorisée ?",
"registration_allowed_explainer": "Autoriser d'autres inscriptions à l'application. \n<br>Il est désactivé après la première inscription.", "registration_allowed_explainer": "Autoriser d'autres inscriptions à l'application. \n<br>Il est désactivé après la première inscription.",
"ssl_explainer": "Si vous spécifiez <span class='text-yellow-500 font-bold'>https</span>, Coolify sera accessible uniquement via https. \nUn certificat SSL sera généré pour vous.<br>Si vous spécifiez <span class='text-yellow-500 font-bold'>www</span>, Coolify sera redirigé (302) à partir de non-www et vice versa." "ssl_explainer": "Si vous spécifiez <span class='text-settings font-bold'>https</span>, Coolify sera accessible uniquement via https. \nUn certificat SSL sera généré pour vous.<br>Si vous spécifiez <span class='text-settings font-bold'>www</span>, Coolify sera redirigé (302) à partir de non-www et vice versa."
}, },
"source": { "source": {
"application_id": "ID d'application", "application_id": "ID d'application",

View File

@ -17,6 +17,11 @@ interface AppSession {
gitlab: string | null, gitlab: string | null,
} }
} }
interface AddToast {
type?: "info" | "success" | "error",
message: string,
timeout?: number | undefined
}
export const loginEmail: Writable<string | undefined> = writable() export const loginEmail: Writable<string | undefined> = writable()
export const appSession: Writable<AppSession> = writable({ export const appSession: Writable<AppSession> = writable({
ipv4: null, ipv4: null,
@ -74,4 +79,30 @@ export const setLocation = (resource: any) => {
} else { } else {
location.set(resource.fqdn) location.set(resource.fqdn)
} }
}
export const toasts: any = writable([])
export const dismissToast = (id: number) => {
toasts.update((all: any) => all.filter((t: any) => t.id !== id))
}
export const addToast = (toast: AddToast) => {
// Create a unique ID so we can easily find/remove it
// if it is dismissible/has a timeout.
const id = Math.floor(Math.random() * 10000)
// Setup some sensible defaults for a toast.
const defaults = {
id,
type: 'info',
timeout: 2000,
}
// Push the toast to the top of the list of toasts
const t = { ...defaults, ...toast }
toasts.update((all: any) => [t, ...all])
// If toast is dismissible, dismiss it after "timeout" amount of time.
if (t.timeout) setTimeout(() => dismissToast(id), t.timeout)
} }

View File

@ -86,6 +86,7 @@
import PageLoader from '$lib/components/PageLoader.svelte'; import PageLoader from '$lib/components/PageLoader.svelte';
import { errorNotification } from '$lib/common'; import { errorNotification } from '$lib/common';
import { appSession } from '$lib/store'; import { appSession } from '$lib/store';
import Toasts from '$lib/components/Toasts.svelte';
if (userId) $appSession.userId = userId; if (userId) $appSession.userId = userId;
if (teamId) $appSession.teamId = teamId; if (teamId) $appSession.teamId = teamId;
@ -110,7 +111,8 @@
<link rel="icon" href={$appSession.whiteLabeledDetails.icon} /> <link rel="icon" href={$appSession.whiteLabeledDetails.icon} />
{/if} {/if}
</svelte:head> </svelte:head>
<SvelteToast options={{ intro: { y: -64 }, duration: 3000, pausable: true }} /> <Toasts />
<!-- <SvelteToast options={{ intro: { y: -64 }, duration: 3000, pausable: true }} /> -->
{#if $navigating} {#if $navigating}
<div out:fade={{ delay: 100 }}> <div out:fade={{ delay: 100 }}>
<PageLoader /> <PageLoader />

View File

@ -12,8 +12,8 @@
import { del } from '$lib/api'; import { del } from '$lib/api';
import { errorNotification } from '$lib/common'; import { errorNotification } from '$lib/common';
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte'; import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
import { addToast } from '$lib/store';
import { t } from '$lib/translations'; import { t } from '$lib/translations';
import { toast } from '@zerodevx/svelte-toast';
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
import { saveSecret } from './utils'; import { saveSecret } from './utils';
@ -28,7 +28,10 @@
value = ''; value = '';
isBuildSecret = false; isBuildSecret = false;
} }
toast.push('Secret removed.'); addToast({
message: 'Secret removed.',
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} }
@ -36,6 +39,7 @@
async function createSecret(isNew: any) { async function createSecret(isNew: any) {
try { try {
if (!name || !value) return
await saveSecret({ await saveSecret({
isNew, isNew,
name, name,
@ -51,9 +55,12 @@
isBuildSecret = false; isBuildSecret = false;
} }
dispatch('refresh'); dispatch('refresh');
toast.push('Secret saved.'); addToast({
message: 'Secret removed.',
type: 'success'
});
} catch (error) { } catch (error) {
console.log(error) console.log(error);
return errorNotification(error); return errorNotification(error);
} }
} }
@ -71,7 +78,10 @@
isNewSecret, isNewSecret,
applicationId: id applicationId: id
}); });
toast.push('Secret saved.'); addToast({
message: 'Secret removed.',
type: 'success'
});
} }
} }
} }
@ -100,8 +110,7 @@
/> />
</td> </td>
<td class="text-center"> <td class="text-center">
<div <button
type="button"
on:click={setSecretValue} on:click={setSecretValue}
aria-pressed="false" aria-pressed="false"
class="relative inline-flex h-6 w-11 flex-shrink-0 rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out" class="relative inline-flex h-6 w-11 flex-shrink-0 rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out"
@ -146,23 +155,25 @@
</svg> </svg>
</span> </span>
</span> </span>
</div> </button>
</td> </td>
<td> <td>
{#if isNewSecret} {#if isNewSecret}
<div class="flex items-center justify-center"> <div class="flex items-center justify-center">
<button class="bg-green-600 hover:bg-green-500" on:click={() => createSecret(true)} <button class="btn bg-applications btn-sm" on:click={() => createSecret(true)}
>{$t('forms.add')}</button >{$t('forms.add')}</button
> >
</div> </div>
{:else} {:else}
<div class="flex flex-row justify-center space-x-2"> <div class="flex flex-row justify-center space-x-2">
<div class="flex items-center justify-center"> <div class="flex items-center justify-center">
<button class="" on:click={() => createSecret(false)}>{$t('forms.set')}</button> <button class="btn bg-application btn-sm" on:click={() => createSecret(false)}
>{$t('forms.set')}</button
>
</div> </div>
{#if !isPRMRSecret} {#if !isPRMRSecret}
<div class="flex justify-center items-end"> <div class="flex justify-center items-end">
<button class="bg-red-600 hover:bg-red-500" on:click={removeSecret} <button class="btn btn-sm bg-red-600 hover:bg-red-500" on:click={removeSecret}
>{$t('forms.remove')}</button >{$t('forms.remove')}</button
> >
</div> </div>

View File

@ -11,6 +11,7 @@
import { toast } from '@zerodevx/svelte-toast'; import { toast } from '@zerodevx/svelte-toast';
import { t } from '$lib/translations'; import { t } from '$lib/translations';
import { errorNotification } from '$lib/common'; import { errorNotification } from '$lib/common';
import { addToast } from '$lib/store';
const { id } = $page.params; const { id } = $page.params;
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
@ -30,8 +31,17 @@
storage.path = null; storage.path = null;
storage.id = null; storage.id = null;
} }
if (newStorage) toast.push($t('application.storage.storage_saved')); if (newStorage) {
else toast.push($t('application.storage.storage_updated')); addToast({
message: $t('application.storage.storage_saved'),
type: 'success'
});
} else {
addToast({
message: $t('application.storage.storage_updated'),
type: 'success'
});
}
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} }
@ -40,7 +50,10 @@
try { try {
await del(`/applications/${id}/storages`, { path: storage.path }); await del(`/applications/${id}/storages`, { path: storage.path });
dispatch('refresh'); dispatch('refresh');
toast.push($t('application.storage.storage_deleted')); addToast({
message: $t('application.storage.storage_deleted'),
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} }
@ -58,17 +71,19 @@
<td> <td>
{#if isNew} {#if isNew}
<div class="flex items-center justify-center"> <div class="flex items-center justify-center">
<button class="bg-green-600 hover:bg-green-500" on:click={() => saveStorage(true)} <button class="btn btn-sm bg-applications" on:click={() => saveStorage(true)}
>{$t('forms.add')}</button >{$t('forms.add')}</button
> >
</div> </div>
{:else} {:else}
<div class="flex flex-row justify-center space-x-2"> <div class="flex flex-row justify-center space-x-2">
<div class="flex items-center justify-center"> <div class="flex items-center justify-center">
<button class="" on:click={() => saveStorage(false)}>{$t('forms.set')}</button> <button class="btn btn-sm bg-applications" on:click={() => saveStorage(false)}
>{$t('forms.set')}</button
>
</div> </div>
<div class="flex justify-center items-end"> <div class="flex justify-center items-end">
<button class="bg-red-600 hover:bg-red-500" on:click={removeStorage} <button class="btn btn-sm bg-red-600 hover:bg-red-500" on:click={removeStorage}
>{$t('forms.remove')}</button >{$t('forms.remove')}</button
> >
</div> </div>

View File

@ -60,7 +60,7 @@
import { toast } from '@zerodevx/svelte-toast'; import { toast } from '@zerodevx/svelte-toast';
import { onDestroy, onMount } from 'svelte'; import { onDestroy, onMount } from 'svelte';
import { t } from '$lib/translations'; import { t } from '$lib/translations';
import { appSession, disabledButton, status, location, setLocation } from '$lib/store'; import { appSession, disabledButton, status, location, setLocation, addToast } from '$lib/store';
import { errorNotification, handlerNotFoundLoad } from '$lib/common'; import { errorNotification, handlerNotFoundLoad } from '$lib/common';
import Loading from '$lib/components/Loading.svelte'; import Loading from '$lib/components/Loading.svelte';
@ -80,7 +80,10 @@
async function handleDeploySubmit() { async function handleDeploySubmit() {
try { try {
const { buildId } = await post(`/applications/${id}/deploy`, { ...application }); const { buildId } = await post(`/applications/${id}/deploy`, { ...application });
toast.push($t('application.deployment_queued')); addToast({
message: $t('application.deployment_queued'),
type: 'success'
});
if ($page.url.pathname.startsWith(`/applications/${id}/logs/build`)) { if ($page.url.pathname.startsWith(`/applications/${id}/logs/build`)) {
return window.location.assign(`/applications/${id}/logs/build?buildId=${buildId}`); return window.location.assign(`/applications/${id}/logs/build?buildId=${buildId}`);
} else { } else {

View File

@ -190,11 +190,11 @@
</div> </div>
<div class="pt-5 flex-col flex justify-center items-center space-y-4"> <div class="pt-5 flex-col flex justify-center items-center space-y-4">
<button <button
class="w-40" class="btn btn-wide"
type="submit" type="submit"
disabled={!showSave} disabled={!showSave}
class:bg-orange-600={showSave} class:bg-applications={showSave}
class:hover:bg-orange-500={showSave}>{$t('forms.save')}</button >{$t('forms.save')}</button
> >
</div> </div>
</form> </form>

View File

@ -413,11 +413,10 @@
<div class="flex flex-col items-center justify-center space-y-4 pt-5"> <div class="flex flex-col items-center justify-center space-y-4 pt-5">
<button <button
on:click|preventDefault={save} on:click|preventDefault={save}
class="w-40" class="btn btn-wide"
type="submit" type="submit"
disabled={!showSave || loading.save} disabled={!showSave || loading.save}
class:bg-orange-600={showSave && !loading.save} class:bg-applications={showSave && !loading.save}
class:hover:bg-orange-500={showSave && !loading.save}
>{loading.save ? $t('forms.saving') : $t('forms.save')}</button >{loading.save ? $t('forms.saving') : $t('forms.save')}</button
> >
{#if tryAgain} {#if tryAgain}

View File

@ -35,13 +35,14 @@
import { get, post } from '$lib/api'; import { get, post } from '$lib/api';
import cuid from 'cuid'; import cuid from 'cuid';
import { browser } from '$app/env'; import { browser } from '$app/env';
import { appSession, disabledButton, setLocation, status } from '$lib/store'; import { addToast, appSession, disabledButton, setLocation, status } from '$lib/store';
import { t } from '$lib/translations'; import { t } from '$lib/translations';
import { errorNotification, getDomain, notNodeDeployments, staticDeployments } from '$lib/common'; import { errorNotification, getDomain, notNodeDeployments, staticDeployments } from '$lib/common';
import Setting from './_Setting.svelte'; import Setting from './_Setting.svelte';
const { id } = $page.params; const { id } = $page.params;
$: isDisabled = !$appSession.isAdmin || $status.application.isRunning || $status.application.initialLoading; $: isDisabled =
!$appSession.isAdmin || $status.application.isRunning || $status.application.initialLoading;
let domainEl: HTMLInputElement; let domainEl: HTMLInputElement;
@ -138,7 +139,10 @@
branch: application.branch, branch: application.branch,
projectId: application.projectId projectId: application.projectId
}); });
return toast.push($t('application.settings_saved')); return addToast({
message: $t('application.settings_saved'),
type: 'success'
});
} catch (error) { } catch (error) {
if (name === 'debug') { if (name === 'debug') {
debug = !debug; debug = !debug;
@ -169,10 +173,13 @@
exposePort: application.exposePort exposePort: application.exposePort
}); });
await post(`/applications/${id}`, { ...application }); await post(`/applications/${id}`, { ...application });
setLocation(application) setLocation(application);
$disabledButton = false; $disabledButton = false;
forceSave = false; forceSave = false;
return toast.push('Configurations saved.'); addToast({
message: 'Configuration saved.',
type: 'success',
});
} catch (error) { } catch (error) {
console.log(error); console.log(error);
//@ts-ignore //@ts-ignore
@ -215,7 +222,10 @@
async function isDNSValid(domain: any, isWWW: any) { async function isDNSValid(domain: any, isWWW: any) {
try { try {
await get(`/applications/${id}/check?domain=${domain}`); await get(`/applications/${id}/check?domain=${domain}`);
toast.push('DNS configuration is valid.'); addToast({
message: 'DNS configuration is valid.',
type: 'success'
});
isWWW ? (isWWWDomainOK = true) : (isNonWWWDomainOK = true); isWWW ? (isWWWDomainOK = true) : (isNonWWWDomainOK = true);
return true; return true;
} catch (error) { } catch (error) {
@ -312,29 +322,21 @@
<div class="title">{$t('general')}</div> <div class="title">{$t('general')}</div>
{#if $appSession.isAdmin} {#if $appSession.isAdmin}
<button <button
class="btn btn-sm"
type="submit" type="submit"
class:bg-green-600={!loading} class:bg-applications={!loading}
class:loading={loading}
class:bg-orange-600={forceSave} class:bg-orange-600={forceSave}
class:hover:bg-green-500={!loading}
class:hover:bg-orange-400={forceSave} class:hover:bg-orange-400={forceSave}
disabled={loading} disabled={loading}
>{loading >{$t('forms.save')}</button
? $t('forms.saving')
: forceSave
? $t('forms.confirm_continue')
: $t('forms.save')}</button
> >
{/if} {/if}
</div> </div>
<div class="grid grid-flow-row gap-2 px-10"> <div class="grid grid-flow-row gap-2 px-10">
<div class="mt-2 grid grid-cols-2 items-center"> <div class="mt-2 grid grid-cols-2 items-center">
<label for="name" class="text-base font-bold text-stone-100">{$t('forms.name')}</label> <label for="name" class="text-base font-bold text-stone-100">{$t('forms.name')}</label>
<input <input name="name" id="name" bind:value={application.name} required />
name="name"
id="name"
bind:value={application.name}
required
/>
</div> </div>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="gitSource" class="text-base font-bold text-stone-100" <label for="gitSource" class="text-base font-bold text-stone-100"

View File

@ -28,6 +28,7 @@
import { errorNotification, getDomain } from '$lib/common'; import { errorNotification, getDomain } from '$lib/common';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import Loading from '$lib/components/Loading.svelte'; import Loading from '$lib/components/Loading.svelte';
import { addToast } from '$lib/store';
const { id } = $page.params; const { id } = $page.params;
@ -59,7 +60,10 @@
pullmergeRequestId: container.pullmergeRequestId, pullmergeRequestId: container.pullmergeRequestId,
branch: container.branch branch: container.branch
}); });
toast.push('Deployment queued'); addToast({
message: 'Deployment queued',
type: 'success'
});
if ($page.url.pathname.startsWith(`/applications/${id}/logs/build`)) { if ($page.url.pathname.startsWith(`/applications/${id}/logs/build`)) {
return window.location.assign(`/applications/${id}/logs/build?buildId=${buildId}`); return window.location.assign(`/applications/${id}/logs/build?buildId=${buildId}`);
} else { } else {

View File

@ -28,6 +28,7 @@
import { get } from '$lib/api'; import { get } from '$lib/api';
import { saveSecret } from './utils'; import { saveSecret } from './utils';
import { toast } from '@zerodevx/svelte-toast'; import { toast } from '@zerodevx/svelte-toast';
import { addToast } from '$lib/store';
const limit = pLimit(1); const limit = pLimit(1);
const { id } = $page.params; const { id } = $page.params;
@ -59,7 +60,10 @@
); );
batchSecrets = ''; batchSecrets = '';
await refreshSecrets(); await refreshSecrets();
toast.push('Secrets saved.'); addToast({
message: 'Secrets saved.',
type: 'success'
});
} }
</script> </script>
@ -148,7 +152,7 @@
<form on:submit|preventDefault={getValues} class="mb-12 w-full"> <form on:submit|preventDefault={getValues} class="mb-12 w-full">
<textarea bind:value={batchSecrets} class="mb-2 min-h-[200px] w-full" /> <textarea bind:value={batchSecrets} class="mb-2 min-h-[200px] w-full" />
<button <button
class="bg-green-600 hover:bg-green-500 disabled:text-white disabled:opacity-40" class="btn btn-sm bg-applications"
type="submit">Batch add secrets</button type="submit">Batch add secrets</button
> >
</form> </form>

View File

@ -61,14 +61,14 @@
</script> </script>
<div class="flex space-x-1 p-6 font-bold"> <div class="flex space-x-1 p-6 font-bold">
<div class="mr-4 text-2xl ">{$t('index.applications')}</div> <div class="mr-4 text-2xl">{$t('index.applications')}</div>
{#if $appSession.isAdmin} {#if $appSession.isAdmin}
<button <button
on:click={newApplication} on:click={newApplication}
class="add-icon cursor-pointer bg-green-600 hover:bg-green-500" class="btn btn-square btn-sm bg-applications"
> >
<svg <svg
class="w-6" class="h-6 w-6"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
fill="none" fill="none"
viewBox="0 0 24 24" viewBox="0 0 24 24"

View File

@ -16,7 +16,7 @@
import { toast } from '@zerodevx/svelte-toast'; import { toast } from '@zerodevx/svelte-toast';
import { t } from '$lib/translations'; import { t } from '$lib/translations';
import { errorNotification } from '$lib/common'; import { errorNotification } from '$lib/common';
import { appSession, status } from '$lib/store'; import { addToast, appSession, status } from '$lib/store';
import Explainer from '$lib/components/Explainer.svelte'; import Explainer from '$lib/components/Explainer.svelte';
const { id } = $page.params; const { id } = $page.params;
@ -92,7 +92,10 @@
loading = true; loading = true;
await post(`/databases/${id}`, { ...database, isRunning: $status.database.isRunning }); await post(`/databases/${id}`, { ...database, isRunning: $status.database.isRunning });
generateDbDetails(); generateDbDetails();
toast.push('Configuration saved.'); addToast({
message: 'Configuration saved.',
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} finally { } finally {
@ -108,9 +111,10 @@
{#if $appSession.isAdmin} {#if $appSession.isAdmin}
<button <button
type="submit" type="submit"
class:bg-purple-600={!loading} class="btn btn-sm"
class:hover:bg-purple-500={!loading} class:loading={loading}
disabled={loading}>{loading ? $t('forms.saving') : $t('forms.save')}</button class:bg-databases={!loading}
disabled={loading}>{$t('forms.save')}</button
> >
{/if} {/if}
</div> </div>

View File

@ -50,21 +50,24 @@
<div class="flex space-x-1 p-6 font-bold"> <div class="flex space-x-1 p-6 font-bold">
<div class="mr-4 text-2xl tracking-tight">{$t('index.databases')}</div> <div class="mr-4 text-2xl tracking-tight">{$t('index.databases')}</div>
<div on:click={newDatabase} class="add-icon cursor-pointer bg-purple-600 hover:bg-purple-500"> <button
<svg on:click={newDatabase}
class="w-6" class="btn btn-square btn-sm bg-databases"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 6v6m0 0v6m0-6h6m-6 0H6"
/></svg
> >
</div> <svg
class="h-6 w-6"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 6v6m0 0v6m0-6h6m-6 0H6"
/></svg
>
</button>
</div> </div>
<div class="flex-col justify-center"> <div class="flex-col justify-center">

View File

@ -9,7 +9,7 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { t } from '$lib/translations'; import { t } from '$lib/translations';
import { errorNotification } from '$lib/common'; import { errorNotification } from '$lib/common';
import { appSession } from '$lib/store'; import { addToast, appSession } from '$lib/store';
import Setting from '$lib/components/Setting.svelte'; import Setting from '$lib/components/Setting.svelte';
const { id } = $page.params; const { id } = $page.params;
@ -24,7 +24,10 @@
loading.save = true; loading.save = true;
try { try {
await post(`/destinations/${id}`, { ...destination }); await post(`/destinations/${id}`, { ...destination });
toast.push('Configuration saved.'); addToast({
message: 'Configuration saved.',
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} finally { } finally {
@ -96,7 +99,10 @@
async function stopProxy() { async function stopProxy() {
try { try {
await post(`/destinations/${id}/stop`, { engine: destination.engine }); await post(`/destinations/${id}/stop`, { engine: destination.engine });
return toast.push($t('destination.coolify_proxy_stopped')); return addToast({
message: $t('destination.coolify_proxy_stopped'),
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} }
@ -104,7 +110,10 @@
async function startProxy() { async function startProxy() {
try { try {
await post(`/destinations/${id}/start`, { engine: destination.engine }); await post(`/destinations/${id}/start`, { engine: destination.engine });
return toast.push($t('destination.coolify_proxy_started')); return addToast({
message: $t('destination.coolify_proxy_started'),
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} }
@ -114,7 +123,10 @@
if (sure) { if (sure) {
try { try {
loading.restart = true; loading.restart = true;
toast.push($t('destination.coolify_proxy_restarting')); addToast({
message: $t('destination.coolify_proxy_restarting'),
type: 'success'
});
await post(`/destinations/${id}/restart`, { await post(`/destinations/${id}/restart`, {
engine: destination.engine, engine: destination.engine,
fqdn: settings.fqdn fqdn: settings.fqdn
@ -136,19 +148,18 @@
{#if $appSession.isAdmin} {#if $appSession.isAdmin}
<button <button
type="submit" type="submit"
class="bg-sky-600 hover:bg-sky-500" class="btn btn-sm"
class:bg-sky-600={!loading.save} class:bg-destinations={!loading.save}
class:hover:bg-sky-500={!loading.save} class:loading={loading.save}
disabled={loading.save} disabled={loading.save}
>{loading.save ? $t('forms.saving') : $t('forms.save')} >{$t('forms.save')}
</button> </button>
<button <button
class={loading.restart ? '' : 'bg-red-600 hover:bg-red-500'} class="btn btn-sm"
class:loading={loading.restart}
class:bg-error={!loading.restart}
disabled={loading.restart} disabled={loading.restart}
on:click|preventDefault={forceRestartProxy} on:click|preventDefault={forceRestartProxy}>{$t('destination.force_restart_proxy')}</button
>{loading.restart
? $t('destination.restarting_please_wait')
: $t('destination.force_restart_proxy')}</button
> >
{/if} {/if}
</div> </div>

View File

@ -40,10 +40,10 @@
<div class="flex-col space-y-2 pb-10 text-center"> <div class="flex-col space-y-2 pb-10 text-center">
<div class="text-xl font-bold text-white">{$t('destination.new.predefined_destinations')}</div> <div class="text-xl font-bold text-white">{$t('destination.new.predefined_destinations')}</div>
<div class="flex justify-center space-x-2"> <div class="flex justify-center space-x-2">
<button class="w-32" on:click={() => setPredefined('localDocker')} <button class="btn btn-sm" on:click={() => setPredefined('localDocker')}
>{$t('sources.local_docker')}</button >{$t('sources.local_docker')}</button
> >
<button class="w-32" on:click={() => setPredefined('remoteDocker')}>Remote Docker</button> <button class="btn btn-sm" on:click={() => setPredefined('remoteDocker')}>Remote Docker</button>
<!-- <button class="w-32" on:click={() => setPredefined('kubernetes')}>Kubernetes</button> --> <!-- <button class="w-32" on:click={() => setPredefined('kubernetes')}>Kubernetes</button> -->
</div> </div>
</div> </div>

View File

@ -10,7 +10,7 @@
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { t } from '$lib/translations'; import { t } from '$lib/translations';
import { errorNotification } from '$lib/common'; import { errorNotification } from '$lib/common';
import { appSession } from '$lib/store'; import { addToast, appSession } from '$lib/store';
const { id } = $page.params; const { id } = $page.params;
@ -28,7 +28,10 @@
loading.save = true; loading.save = true;
try { try {
await post(`/destinations/${id}`, { ...destination }); await post(`/destinations/${id}`, { ...destination });
toast.push('Configuration saved.'); addToast({
message: 'Configuration saved.',
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} finally { } finally {
@ -103,7 +106,10 @@
async function stopProxy() { async function stopProxy() {
try { try {
await post(`/destinations/${id}/stop`, { engine: destination.engine }); await post(`/destinations/${id}/stop`, { engine: destination.engine });
return toast.push($t('destination.coolify_proxy_stopped')); return addToast({
message: $t('destination.coolify_proxy_stopped'),
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} }
@ -111,7 +117,10 @@
async function startProxy() { async function startProxy() {
try { try {
await post(`/destinations/${id}/start`, { engine: destination.engine }); await post(`/destinations/${id}/start`, { engine: destination.engine });
return toast.push($t('destination.coolify_proxy_started')); return addToast({
message: $t('destination.coolify_proxy_started'),
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} }
@ -121,7 +130,10 @@
if (sure) { if (sure) {
try { try {
loading.restart = true; loading.restart = true;
toast.push($t('destination.coolify_proxy_restarting')); addToast({
message: $t('destination.coolify_proxy_restarting'),
type: 'success'
});
await post(`/destinations/${id}/restart`, { await post(`/destinations/${id}/restart`, {
engine: destination.engine, engine: destination.engine,
fqdn: settings.fqdn fqdn: settings.fqdn
@ -140,8 +152,10 @@
loading.verify = true; loading.verify = true;
await post(`/destinations/${id}/verify`, {}); await post(`/destinations/${id}/verify`, {});
destination.remoteVerified = true; destination.remoteVerified = true;
toast.push('Remote Docker Engine verified!'); return addToast({
return; message: 'Remote Docker Engine verified!',
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} finally { } finally {
@ -156,26 +170,28 @@
{#if $appSession.isAdmin} {#if $appSession.isAdmin}
<button <button
type="submit" type="submit"
class="bg-sky-600 hover:bg-sky-500" class="btn btn-sm"
class:bg-sky-600={!loading.save} class:loading={loading.save}
class:hover:bg-sky-500={!loading.save} class:bg-destinations={!loading.save}
disabled={loading.save} disabled={loading.save}
>{loading.save ? $t('forms.saving') : $t('forms.save')} >{$t('forms.save')}
</button> </button>
{#if !destination.remoteVerified} {#if !destination.remoteVerified}
<button <button
disabled={loading.verify} disabled={loading.verify}
class="btn btn-sm"
class:loading={loading.verify}
on:click|preventDefault|stopPropagation={verifyRemoteDocker} on:click|preventDefault|stopPropagation={verifyRemoteDocker}
>{loading.verify ? 'Verifying...' : 'Verify Remote Docker Engine'}</button >Verify Remote Docker Engine</button
> >
{:else} {:else}
<button <button
class={loading.restart ? '' : 'bg-red-600 hover:bg-red-500'} class="btn btn-sm"
class:loading={loading.restart}
class:bg-error={!loading.restart}
disabled={loading.restart} disabled={loading.restart}
on:click|preventDefault={forceRestartProxy} on:click|preventDefault={forceRestartProxy}
>{loading.restart >{$t('destination.force_restart_proxy')}</button
? $t('destination.restarting_please_wait')
: $t('destination.force_restart_proxy')}</button
> >
{/if} {/if}
{/if} {/if}

View File

@ -39,9 +39,9 @@
<div class="flex space-x-1 p-6 font-bold"> <div class="flex space-x-1 p-6 font-bold">
<div class="mr-4 text-2xl tracking-tight">{$t('index.destinations')}</div> <div class="mr-4 text-2xl tracking-tight">{$t('index.destinations')}</div>
{#if $appSession.isAdmin} {#if $appSession.isAdmin}
<a href="/destinations/new" class="add-icon bg-sky-600 hover:bg-sky-500"> <a href="/destinations/new" class="btn btn-square btn-sm bg-destinations">
<svg <svg
class="w-6" class="h-6 w-6"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
fill="none" fill="none"
viewBox="0 0 24 24" viewBox="0 0 24 24"

View File

@ -28,7 +28,7 @@
import { del, get, post } from '$lib/api'; import { del, get, post } from '$lib/api';
import { toast } from '@zerodevx/svelte-toast'; import { toast } from '@zerodevx/svelte-toast';
import { errorNotification } from '$lib/common'; import { errorNotification } from '$lib/common';
import { appSession } from '$lib/store'; import { addToast, appSession } from '$lib/store';
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
if (accounts.length === 0) { if (accounts.length === 0) {
@ -42,7 +42,10 @@
} }
try { try {
await post(`/iam/user/password`, { id }); await post(`/iam/user/password`, { id });
toast.push('Password reset successfully. Please relogin to reset it.'); return addToast({
message: 'Password reset successfully. Please relogin to reset it.',
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} }
@ -54,7 +57,10 @@
} }
try { try {
await del(`/iam/user/remove`, { id }); await del(`/iam/user/remove`, { id });
toast.push('Account deleted.'); addToast({
message: 'Account deleted.',
type: 'success'
});
const data = await get('/iam'); const data = await get('/iam');
accounts = data.accounts; accounts = data.accounts;
} catch (error) { } catch (error) {
@ -104,21 +110,24 @@
<div class="flex space-x-1 p-6 font-bold"> <div class="flex space-x-1 p-6 font-bold">
<div class="mr-4 text-2xl tracking-tight">Identity and Access Management</div> <div class="mr-4 text-2xl tracking-tight">Identity and Access Management</div>
<div on:click={newTeam} class="add-icon cursor-pointer bg-fuchsia-600 hover:bg-fuchsia-500"> <button
<svg on:click={newTeam}
class="w-6" class="btn btn-square btn-sm bg-iam"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 6v6m0 0v6m0-6h6m-6 0H6"
/></svg
> >
</div> <svg
class="h-6 w-6"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 6v6m0 0v6m0-6h6m-6 0H6"
/></svg
>
</button>
</div> </div>
{#if invitations.length > 0} {#if invitations.length > 0}
@ -132,11 +141,11 @@
<span class="font-bold text-rose-600">{invitation.permission}</span> permission. <span class="font-bold text-rose-600">{invitation.permission}</span> permission.
</div> </div>
<button <button
class="hover:bg-green-500" class="btn btn-sm btn-success"
on:click={() => acceptInvitation(invitation.id, invitation.teamId)}>Accept</button on:click={() => acceptInvitation(invitation.id, invitation.teamId)}>Accept</button
> >
<button <button
class="hover:bg-red-600" class="btn btn-sm btn-error"
on:click={() => revokeInvitation(invitation.id, invitation.teamId)}>Delete</button on:click={() => revokeInvitation(invitation.id, invitation.teamId)}>Delete</button
> >
</div> </div>
@ -168,14 +177,14 @@
<td class="flex space-x-2"> <td class="flex space-x-2">
<form on:submit|preventDefault={() => resetPassword(account.id)}> <form on:submit|preventDefault={() => resetPassword(account.id)}>
<button <button
class="mx-auto my-4 w-32 bg-fuchsia-600 hover:bg-fuchsia-500 disabled:bg-coolgray-200" class="my-4 btn btn-sm bg-iam"
>Reset Password</button >Reset Password</button
> >
</form> </form>
<form on:submit|preventDefault={() => deleteUser(account.id)}> <form on:submit|preventDefault={() => deleteUser(account.id)}>
<button <button
disabled={account.id === $appSession.userId} disabled={account.id === $appSession.userId}
class="mx-auto my-4 w-32 bg-red-600 hover:bg-red-500 disabled:bg-coolgray-200" class="my-4 btn btn-sm"
type="submit">Delete User</button type="submit">Delete User</button
> >
</form> </form>

View File

@ -91,7 +91,7 @@
<form on:submit|preventDefault={handleSubmit} class=" py-4"> <form on:submit|preventDefault={handleSubmit} class=" py-4">
<div class="flex space-x-1 pb-5"> <div class="flex space-x-1 pb-5">
<div class="title font-bold">{$t('index.settings')}</div> <div class="title font-bold">{$t('index.settings')}</div>
<button class="bg-fuchsia-600 hover:bg-fuchsia-500" type="submit">{$t('forms.save')}</button> <button class="btn btn-sm bg-iam" type="submit">{$t('forms.save')}</button>
</div> </div>
<div class="grid grid-flow-row gap-2 px-10"> <div class="grid grid-flow-row gap-2 px-10">
<div class="mt-2 grid grid-cols-2"> <div class="mt-2 grid grid-cols-2">
@ -130,11 +130,11 @@
{#if $appSession.isAdmin && permission.user.id !== $appSession.userId && permission.permission !== 'owner'} {#if $appSession.isAdmin && permission.user.id !== $appSession.userId && permission.permission !== 'owner'}
<td class="flex flex-col items-center justify-center space-y-2 py-4 text-center"> <td class="flex flex-col items-center justify-center space-y-2 py-4 text-center">
<button <button
class="w-52 bg-red-600 hover:bg-red-500" class="btn btn-sm btn-error"
on:click={() => removeFromTeam(permission.user.id)}>{$t('forms.remove')}</button on:click={() => removeFromTeam(permission.user.id)}>{$t('forms.remove')}</button
> >
<button <button
class="w-52" class="btn btn-sm"
on:click={() => on:click={() =>
changePermission(permission.user.id, permission.id, permission.permission)} changePermission(permission.user.id, permission.id, permission.permission)}
>{$t('team.promote_to', { >{$t('team.promote_to', {
@ -157,7 +157,7 @@
{#if isAdmin(team.permissions[0].permission)} {#if isAdmin(team.permissions[0].permission)}
<td class="flex-col space-y-2 py-4 text-center"> <td class="flex-col space-y-2 py-4 text-center">
<button <button
class="w-52 bg-red-600 hover:bg-red-500" class="btn btn-sm btn-error"
on:click={() => revokeInvitation(invitation.id)} on:click={() => revokeInvitation(invitation.id)}
>{$t('team.revoke_invitation')}</button >{$t('team.revoke_invitation')}</button
> >
@ -174,7 +174,7 @@
<div class="flex space-x-1"> <div class="flex space-x-1">
<div class="flex space-x-1"> <div class="flex space-x-1">
<div class="title font-bold">{$t('team.invite_new_member')}</div> <div class="title font-bold">{$t('team.invite_new_member')}</div>
<button class="bg-fuchsia-600 hover:bg-fuchsia-500" type="submit" <button class="btn btn-sm bg-iam" type="submit"
>{$t('team.send_invitation')}</button >{$t('team.send_invitation')}</button
> >
</div> </div>
@ -191,14 +191,14 @@
<div class="flex-1" /> <div class="flex-1" />
<button <button
on:click={() => (invitation.permission = 'read')} on:click={() => (invitation.permission = 'read')}
class="rounded-none rounded-l border border-dashed border-transparent" class="px-2 rounded-none rounded-l border border-dashed border-transparent"
type="button" type="button"
class:border-coolgray-300={invitation.permission !== 'read'} class:border-coolgray-300={invitation.permission !== 'read'}
class:bg-fuchsia-500={invitation.permission === 'read'}>{$t('team.read')}</button class:bg-fuchsia-500={invitation.permission === 'read'}>{$t('team.read')}</button
> >
<button <button
on:click={() => (invitation.permission = 'admin')} on:click={() => (invitation.permission = 'admin')}
class="rounded-none rounded-r border border-dashed border-transparent" class="px-2 rounded-none rounded-r border border-dashed border-transparent"
type="button" type="button"
class:border-coolgray-300={invitation.permission !== 'admin'} class:border-coolgray-300={invitation.permission !== 'admin'}
class:bg-red-500={invitation.permission === 'admin'}>{$t('team.admin')}</button class:bg-red-500={invitation.permission === 'admin'}>{$t('team.admin')}</button

View File

@ -7,6 +7,7 @@
import { del, post } from '$lib/api'; import { del, post } from '$lib/api';
import { errorNotification } from '$lib/common'; import { errorNotification } from '$lib/common';
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte'; import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
import { addToast } from '$lib/store';
import { toast } from '@zerodevx/svelte-toast'; import { toast } from '@zerodevx/svelte-toast';
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
@ -31,7 +32,6 @@
await post(`/services/${id}/secrets`, { await post(`/services/${id}/secrets`, {
name, name,
value, value,
isNew isNew
}); });
dispatch('refresh'); dispatch('refresh');
@ -39,7 +39,10 @@
name = ''; name = '';
value = ''; value = '';
} }
toast.push('Secret saved.'); addToast({
message: 'Secret saved.',
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} }
@ -72,15 +75,15 @@
<td> <td>
{#if isNewSecret} {#if isNewSecret}
<div class="flex items-center justify-center"> <div class="flex items-center justify-center">
<button class="bg-green-600 hover:bg-green-500" on:click={() => saveSecret(true)}>Add</button> <button class="btn btn-sm bg-success" on:click={() => saveSecret(true)}>Add</button>
</div> </div>
{:else} {:else}
<div class="flex flex-row justify-center space-x-2"> <div class="flex flex-row justify-center space-x-2">
<div class="flex items-center justify-center"> <div class="flex items-center justify-center">
<button class="" on:click={() => saveSecret(false)}>Set</button> <button class="btn btn-sm bg-success" on:click={() => saveSecret(false)}>Set</button>
</div> </div>
<div class="flex justify-center items-end"> <div class="flex justify-center items-end">
<button class="bg-red-600 hover:bg-red-500" on:click={removeSecret}>Remove</button> <button class="btn btn-sm bg-error" on:click={removeSecret}>Remove</button>
</div> </div>
</div> </div>
{/if} {/if}

View File

@ -13,7 +13,7 @@
import { get, post } from '$lib/api'; import { get, post } from '$lib/api';
import { errorNotification, getDomain } from '$lib/common'; import { errorNotification, getDomain } from '$lib/common';
import { t } from '$lib/translations'; import { t } from '$lib/translations';
import { appSession, disabledButton, status, location, setLocation } from '$lib/store'; import { appSession, disabledButton, status, location, setLocation, addToast } from '$lib/store';
import CopyPasswordField from '$lib/components/CopyPasswordField.svelte'; import CopyPasswordField from '$lib/components/CopyPasswordField.svelte';
import Explainer from '$lib/components/Explainer.svelte'; import Explainer from '$lib/components/Explainer.svelte';
import Setting from '$lib/components/Setting.svelte'; import Setting from '$lib/components/Setting.svelte';
@ -45,7 +45,10 @@
async function isDNSValid(domain: any, isWWW: any) { async function isDNSValid(domain: any, isWWW: any) {
try { try {
await get(`/services/${id}/check?domain=${domain}`); await get(`/services/${id}/check?domain=${domain}`);
toast.push('DNS configuration is valid.'); addToast({
message: 'DNS configuration is valid.',
type: 'success'
});
isWWW ? (isWWWDomainOK = true) : (isNonWWWDomainOK = true); isWWW ? (isWWWDomainOK = true) : (isNonWWWDomainOK = true);
return true; return true;
} catch (error) { } catch (error) {
@ -70,7 +73,10 @@
setLocation(service); setLocation(service);
$disabledButton = false; $disabledButton = false;
forceSave = false; forceSave = false;
toast.push('Configuration saved.'); return addToast({
message: 'Configuration saved.',
type: 'success'
});
} catch (error) { } catch (error) {
//@ts-ignore //@ts-ignore
if (error?.message.startsWith($t('application.dns_not_set_partial_error'))) { if (error?.message.startsWith($t('application.dns_not_set_partial_error'))) {
@ -96,7 +102,10 @@
loadingVerification = true; loadingVerification = true;
try { try {
await post(`/services/${id}/${service.type}/activate`, { id: service.id }); await post(`/services/${id}/${service.type}/activate`, { id: service.id });
toast.push(t.get('services.all_email_verified')); return addToast({
message: t.get('services.all_email_verified'),
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} finally { } finally {
@ -109,7 +118,10 @@
dualCerts = !dualCerts; dualCerts = !dualCerts;
} }
await post(`/services/${id}/settings`, { dualCerts }); await post(`/services/${id}/settings`, { dualCerts });
return toast.push(t.get('application.settings_saved')); return addToast({
message: t.get('application.settings_saved'),
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} }
@ -145,13 +157,14 @@
{#if $appSession.isAdmin} {#if $appSession.isAdmin}
<button <button
type="submit" type="submit"
class:bg-pink-600={!loading} class="btn btn-sm"
class:bg-orange-600={forceSave} class:bg-orange-600={forceSave}
class:hover:bg-pink-500={!loading}
class:hover:bg-orange-400={forceSave} class:hover:bg-orange-400={forceSave}
class:loading={loading}
class:bg-services={!loading}
disabled={loading} disabled={loading}
>{loading >{loading
? $t('forms.saving') ? $t('forms.save')
: forceSave : forceSave
? $t('forms.confirm_continue') ? $t('forms.confirm_continue')
: $t('forms.save')}</button : $t('forms.save')}</button

View File

@ -10,6 +10,7 @@
import { toast } from '@zerodevx/svelte-toast'; import { toast } from '@zerodevx/svelte-toast';
import { errorNotification } from '$lib/common'; import { errorNotification } from '$lib/common';
import { addToast } from '$lib/store';
const { id } = $page.params; const { id } = $page.params;
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
@ -29,8 +30,10 @@
storage.path = null; storage.path = null;
storage.id = null; storage.id = null;
} }
if (newStorage) toast.push('Storage saved.'); addToast({
else toast.push('Storage updated.'); message: 'Storage saved.',
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} }
@ -39,16 +42,19 @@
try { try {
await del(`/services/${id}/storages`, { path: storage.path }); await del(`/services/${id}/storages`, { path: storage.path });
dispatch('refresh'); dispatch('refresh');
toast.push('Storage deleted.'); return addToast({
message: 'Storage deleted.',
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} }
} }
async function handleSubmit() { async function handleSubmit() {
if (isNew) { if (isNew) {
await saveStorage(true) await saveStorage(true);
} else { } else {
await saveStorage(false) await saveStorage(false);
} }
} }
</script> </script>
@ -66,16 +72,16 @@
<td> <td>
{#if isNew} {#if isNew}
<div class="flex items-center justify-center"> <div class="flex items-center justify-center">
<button class="bg-green-600 hover:bg-green-500" on:click={() => saveStorage(true)}>Add</button <button class="btn btn-sm btn-success" on:click={() => saveStorage(true)}>Add</button
> >
</div> </div>
{:else} {:else}
<div class="flex flex-row justify-center space-x-2"> <div class="flex flex-row justify-center space-x-2">
<div class="flex items-center justify-center"> <div class="flex items-center justify-center">
<button class="" on:click={() => saveStorage(false)}>Set</button> <button class="btn btn-sm btn-success" on:click={() => saveStorage(false)}>Set</button>
</div> </div>
<div class="flex justify-center items-end"> <div class="flex justify-center items-end">
<button class="bg-red-600 hover:bg-red-500" on:click={removeStorage}>Remove</button> <button class="btn btn-sm btn-error" on:click={removeStorage}>Remove</button>
</div> </div>
</div> </div>
{/if} {/if}

View File

@ -46,21 +46,24 @@
<div class="flex space-x-1 p-6 font-bold"> <div class="flex space-x-1 p-6 font-bold">
<div class="mr-4 text-2xl tracking-tight">{$t('index.services')}</div> <div class="mr-4 text-2xl tracking-tight">{$t('index.services')}</div>
<div on:click={newService} class="add-icon cursor-pointer bg-pink-600 hover:bg-pink-500"> <button
<svg on:click={newService}
class="w-6" class="btn btn-square btn-sm bg-services"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 6v6m0 0v6m0-6h6m-6 0H6"
/></svg
> >
</div> <svg
class="h-6 w-6"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 6v6m0 0v6m0-6h6m-6 0H6"
/></svg
>
</button>
</div> </div>
<div class="flex-col justify-center"> <div class="flex-col justify-center">

View File

@ -24,7 +24,7 @@
import { browser } from '$app/env'; import { browser } from '$app/env';
import { toast } from '@zerodevx/svelte-toast'; import { toast } from '@zerodevx/svelte-toast';
import { t } from '$lib/translations'; import { t } from '$lib/translations';
import { appSession, features } from '$lib/store'; import { addToast, appSession, features } from '$lib/store';
import { errorNotification, getDomain } from '$lib/common'; import { errorNotification, getDomain } from '$lib/common';
import Menu from './_Menu.svelte'; import Menu from './_Menu.svelte';
@ -83,7 +83,10 @@
isAutoUpdateEnabled, isAutoUpdateEnabled,
isDNSCheckEnabled isDNSCheckEnabled
}); });
return toast.push(t.get('application.settings_saved')); return addToast({
message: t.get('application.settings_saved'),
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} }
@ -104,7 +107,10 @@
settings.maxPort = maxPort; settings.maxPort = maxPort;
} }
forceSave = false; forceSave = false;
toast.push('Configuration saved.'); return addToast({
message: 'Configuration saved.',
type: 'success'
});
} catch (error) { } catch (error) {
if (error.message?.startsWith($t('application.dns_not_set_partial_error'))) { if (error.message?.startsWith($t('application.dns_not_set_partial_error'))) {
forceSave = true; forceSave = true;
@ -129,7 +135,10 @@
async function isDNSValid(domain: any, isWWW: any) { async function isDNSValid(domain: any, isWWW: any) {
try { try {
await get(`/settings/check?domain=${domain}`); await get(`/settings/check?domain=${domain}`);
toast.push('DNS configuration is valid.'); addToast({
message:'DNS configuration is valid.',
type: 'success'
});
isWWW ? (isWWWDomainOK = true) : (isNonWWWDomainOK = true); isWWW ? (isWWWDomainOK = true) : (isNonWWWDomainOK = true);
return true; return true;
} catch (error) { } catch (error) {
@ -154,10 +163,9 @@
<div class="flex space-x-1 pb-6"> <div class="flex space-x-1 pb-6">
<div class="title font-bold">{$t('index.global_settings')}</div> <div class="title font-bold">{$t('index.global_settings')}</div>
<button <button
class="btn btn-sm bg-settings text-black"
type="submit" type="submit"
class:bg-yellow-500={!loading.save}
class:bg-orange-600={forceSave} class:bg-orange-600={forceSave}
class:hover:bg-yellow-500={!loading.save}
class:hover:bg-orange-400={forceSave} class:hover:bg-orange-400={forceSave}
disabled={loading.save} disabled={loading.save}
>{loading.save >{loading.save

View File

@ -69,8 +69,7 @@
<div class="title font-bold">SSH Keys</div> <div class="title font-bold">SSH Keys</div>
<button <button
on:click={() => (isModalActive = true)} on:click={() => (isModalActive = true)}
class:bg-yellow-500={!loading.save} class="btn btn-sm bg-settings text-black"
class:hover:bg-yellow-400={!loading.save}
disabled={loading.save}>New SSH Key</button disabled={loading.save}>New SSH Key</button
> >
</div> </div>
@ -82,7 +81,7 @@
<div class="box-selection group relative"> <div class="box-selection group relative">
<div class="text-xl font-bold">{key.name}</div> <div class="text-xl font-bold">{key.name}</div>
<div class="py-3 text-stone-600">Added on {key.createdAt}</div> <div class="py-3 text-stone-600">Added on {key.createdAt}</div>
<button on:click={() => deleteSSHKey(key.id)} class="bg-red-500">Delete</button> <button on:click={() => deleteSSHKey(key.id)} class="btn btn-sm bg-error">Delete</button>
</div> </div>
{/each} {/each}
{/if} {/if}
@ -91,7 +90,7 @@
</div> </div>
</div> </div>
{#if isModalActive} {#if isModalActive}
<div class="relative z-10" aria-labelledby="modal-title" role="dialog" aria-modal="true"> <div class="relative z-10" aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div class="fixed inset-0 bg-coolgray-500 bg-opacity-75 transition-opacity" /> <div class="fixed inset-0 bg-coolgray-500 bg-opacity-75 transition-opacity" />
<div class="fixed z-10 inset-0 overflow-y-auto text-white"> <div class="fixed z-10 inset-0 overflow-y-auto text-white">
<div class="flex items-end sm:items-center justify-center min-h-full p-4 text-center sm:p-0"> <div class="flex items-end sm:items-center justify-center min-h-full p-4 text-center sm:p-0">

View File

@ -7,7 +7,7 @@
import { toast } from '@zerodevx/svelte-toast'; import { toast } from '@zerodevx/svelte-toast';
import { t } from '$lib/translations'; import { t } from '$lib/translations';
import { dashify, errorNotification, getDomain } from '$lib/common'; import { dashify, errorNotification, getDomain } from '$lib/common';
import { appSession } from '$lib/store'; import { addToast, appSession } from '$lib/store';
import { dev } from '$app/env'; import { dev } from '$app/env';
const { id } = $page.params; const { id } = $page.params;
@ -24,7 +24,10 @@
htmlUrl: source.htmlUrl.replace(/\/$/, ''), htmlUrl: source.htmlUrl.replace(/\/$/, ''),
apiUrl: source.apiUrl.replace(/\/$/, '') apiUrl: source.apiUrl.replace(/\/$/, '')
}); });
toast.push('Configuration saved.'); return addToast({
message:'Configuration saved.',
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} finally { } finally {
@ -115,7 +118,7 @@
<div class="flex space-x-1 pb-7"> <div class="flex space-x-1 pb-7">
<div class="title">General</div> <div class="title">General</div>
{#if !source.githubAppId} {#if !source.githubAppId}
<button class="bg-orange-600 font-normal" type="submit">Save</button> <button class="btn btn-sm bg-sources" type="submit">Save & Redirect to GitHub</button>
{/if} {/if}
</div> </div>
<div class="grid grid-flow-row gap-2 px-10"> <div class="grid grid-flow-row gap-2 px-10">
@ -171,13 +174,12 @@
<div class="title">{$t('general')}</div> <div class="title">{$t('general')}</div>
{#if $appSession.isAdmin} {#if $appSession.isAdmin}
<button <button
class="btn btn-sm bg-sources"
type="submit" type="submit"
class:bg-orange-600={!loading}
class:hover:bg-orange-500={!loading}
disabled={loading}>{loading ? 'Saving...' : 'Save'}</button disabled={loading}>{loading ? 'Saving...' : 'Save'}</button
> >
<a <a
class="no-underline button justify-center flex items-center" class="btn btn-sm"
href={`${source.htmlUrl}/apps/${source.githubApp.name}/installations/new`} href={`${source.htmlUrl}/apps/${source.githubApp.name}/installations/new`}
>{$t('source.change_app_settings', { name: 'GitHub' })}</a >{$t('source.change_app_settings', { name: 'GitHub' })}</a
> >
@ -250,7 +252,7 @@
{:else} {:else}
<div class="text-center"> <div class="text-center">
<a href={`${source.htmlUrl}/apps/${source.githubApp.name}/installations/new`}> <a href={`${source.htmlUrl}/apps/${source.githubApp.name}/installations/new`}>
<button class="box-selection bg-orange-600 hover:bg-orange-500 text-xl" <button class="box-selection bg-sources text-xl"
>Install Repositories</button >Install Repositories</button
></a ></a
> >

View File

@ -11,7 +11,7 @@
import { t } from '$lib/translations'; import { t } from '$lib/translations';
import { errorNotification } from '$lib/common'; import { errorNotification } from '$lib/common';
import { appSession } from '$lib/store'; import { addToast, appSession } from '$lib/store';
const { id } = $page.params; const { id } = $page.params;
let url = settings.fqdn ? settings.fqdn : window.location.origin; let url = settings.fqdn ? settings.fqdn : window.location.origin;
@ -73,7 +73,10 @@
apiUrl: source.apiUrl.replace(/\/$/, ''), apiUrl: source.apiUrl.replace(/\/$/, ''),
customPort: source.customPort customPort: source.customPort
}); });
toast.push('Configuration saved.'); return addToast({
message: 'Configuration saved.',
type: 'success'
});
} catch (error) { } catch (error) {
return errorNotification(error); return errorNotification(error);
} finally { } finally {
@ -124,8 +127,10 @@
break; break;
case 'group': case 'group':
if (!source.gitlabApp.groupName) { if (!source.gitlabApp.groupName) {
toast.push('Please enter a group name first.'); return addToast({
return; message: 'Please enter a group name first.',
type: 'error'
});
} }
window.open( window.open(
`${source.htmlUrl}/groups/${source.gitlabApp.groupName}/-/settings/applications` `${source.htmlUrl}/groups/${source.gitlabApp.groupName}/-/settings/applications`
@ -146,21 +151,32 @@
{#if $appSession.isAdmin} {#if $appSession.isAdmin}
<button <button
type="submit" type="submit"
class:bg-orange-600={!loading} class="btn btn-sm bg-sources"
class:hover:bg-orange-500={!loading}
disabled={loading}>{loading ? $t('forms.saving') : $t('forms.save')}</button disabled={loading}>{loading ? $t('forms.saving') : $t('forms.save')}</button
> >
{#if source.gitlabAppId} {#if source.gitlabAppId}
<button on:click|preventDefault={changeSettings} <button class="btn btn-sm" on:click|preventDefault={changeSettings}
>{$t('source.change_app_settings', { name: 'GitLab' })}</button >{$t('source.change_app_settings', { name: 'GitLab' })}</button
> >
{:else} {:else}
<button on:click|preventDefault|stopPropagation={newApp}>Create new GitLab App</button> <button class="btn btn-sm" on:click|preventDefault|stopPropagation={newApp}
>Create new GitLab App manually</button
>
{/if} {/if}
{/if} {/if}
</div> </div>
<div class="grid grid-flow-row gap-2 px-10"> <div class="grid grid-flow-row gap-2 px-10">
{#if !source.gitlabAppId} {#if !source.gitlabAppId}
<Explainer
customClass="w-full"
text="<span class='font-bold text-base text-white'>Scopes required:</span>
<br>- <span class='text-sources font-bold'>api</span> (Access the authenticated user's API)
<br>- <span class='text-sources font-bold'>read_repository</span> (Allows read-only access to the repository)
<br>- <span class='text-sources font-bold'>email</span> (Allows read-only access to the user's primary email address using OpenID Connect)
<br>
<br>For extra security, you can set <span class='text-sources font-bold'>Expire Access Tokens</span>
<br><br>Webhook URL: <span class='text-sources font-bold'>{url}/webhooks/gitlab</span>"
/>
<div class="grid grid-cols-2 items-center"> <div class="grid grid-cols-2 items-center">
<label for="type" class="text-base font-bold text-stone-100">Application Type</label> <label for="type" class="text-base font-bold text-stone-100">Application Type</label>
<select name="type" id="type" class="w-96" bind:value={applicationType}> <select name="type" id="type" class="w-96" bind:value={applicationType}>
@ -295,16 +311,4 @@
</div> </div>
</div> </div>
</form> </form>
{#if !source.gitlabAppId}
<Explainer
customClass="w-full"
text="<span class='font-bold text-base text-white'>Scopes required:</span>
<br>- <span class='text-orange-500 font-bold'>api</span> (Access the authenticated user's API)
<br>- <span class='text-orange-500 font-bold'>read_repository</span> (Allows read-only access to the repository)
<br>- <span class='text-orange-500 font-bold'>email</span> (Allows read-only access to the user's primary email address using OpenID Connect)
<br>
<br>For extra security, you can set <span class='text-orange-500 font-bold'>Expire Access Tokens</span>
<br><br>Webhook URL: <span class='text-orange-500 font-bold'>{url}/webhooks/gitlab</span>"
/>
{/if}
</div> </div>

View File

@ -44,10 +44,10 @@
</div> </div>
<div class="flex flex-col justify-center"> <div class="flex flex-col justify-center">
<div class="flex-col space-y-2 pb-10 text-center"> <div class="flex-col space-y-2 pb-10 text-center">
<div class="text-xl font-bold text-white">Select a provider</div> <div class="text-xl font-bold text-white">Select a git type</div>
<div class="flex justify-center space-x-2"> <div class="flex justify-center space-x-2">
<button class="w-32" on:click={() => setPredefined('github')}>GitHub.com</button> <button class="btn btn-sm" on:click={() => setPredefined('github')}>GitHub</button>
<button class="w-32" on:click={() => setPredefined('gitlab')}>GitLab.com</button> <button class="btn btn-sm" on:click={() => setPredefined('gitlab')}>GitLab</button>
</div> </div>
</div> </div>
{#if source?.type} {#if source?.type}

View File

@ -39,9 +39,9 @@
<div class="flex space-x-1 p-6 font-bold"> <div class="flex space-x-1 p-6 font-bold">
<div class="mr-4 text-2xl tracking-tight">{$t('index.git_sources')}</div> <div class="mr-4 text-2xl tracking-tight">{$t('index.git_sources')}</div>
{#if $appSession.isAdmin} {#if $appSession.isAdmin}
<a href="/sources/new" class="add-icon bg-orange-600 hover:bg-orange-500"> <a href="/sources/new" class="btn btn-square btn-sm bg-sources">
<svg <svg
class="w-6" class="h-6 w-6"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
fill="none" fill="none"
viewBox="0 0 24 24" viewBox="0 0 24 24"

View File

@ -90,10 +90,12 @@ select {
label { label {
@apply inline-block w-64 text-xs tracking-tight md:text-sm; @apply inline-block w-64 text-xs tracking-tight md:text-sm;
} }
.btn {
button, .button { @apply text-white tracking-tighter;
@apply rounded bg-coolgray-200 p-2 px-3 text-sm outline-none transition-all duration-100 hover:bg-coolgray-500 disabled:cursor-not-allowed disabled:bg-coolblack disabled:text-stone-600;
} }
/*button, .button {
@apply rounded bg-coolgray-200 p-2 px-3 text-sm outline-none transition-all duration-100 hover:bg-coolgray-500 disabled:cursor-not-allowed disabled:bg-coolblack disabled:text-stone-600;
}*/
a { a {
@apply underline hover:text-white; @apply underline hover:text-white;

View File

@ -1,8 +1,30 @@
const defaultTheme = require('tailwindcss/defaultTheme'); const defaultTheme = require('tailwindcss/defaultTheme');
// const colors = require('tailwindcss/colors');
module.exports = { module.exports = {
content: ['./**/*.html', './src/**/*.{js,jsx,ts,tsx,svelte}'], content: ['./**/*.html', './src/**/*.{js,jsx,ts,tsx,svelte}'],
important: true, important: true,
daisyui: {
themes: [
{
coollabs: {
"base-100":"#323232",
"base-200":"#242424",
"base-300":"#181818",
"primary": "#6d28d9",
"primary-content": "#fff",
"secondary": "#343232",
"accent": "#343232",
"neutral": "#272626",
"info": "#0284c7",
"success": "#16A34A",
"warning": "#FFFF00",
"error": "#DC2626",
"--rounded-btn": "0.3rem",
"--btn-text-case": "normal"
},
}
],
},
theme: { theme: {
extend: { extend: {
keyframes: { keyframes: {
@ -18,6 +40,13 @@ module.exports = {
sans: ['Poppins', ...defaultTheme.fontFamily.sans] sans: ['Poppins', ...defaultTheme.fontFamily.sans]
}, },
colors: { colors: {
"applications":"#16A34A",
"databases":"#9333EA",
"destinations":"#0284C7",
"sources":"#EA580C",
"services":"#DB2777",
"settings":"#FEE440",
"iam":"#C026D3",
coollabs: '#6B16ED', coollabs: '#6B16ED',
'coollabs-100': '#7317FF', 'coollabs-100': '#7317FF',
coolblack: '#161616', coolblack: '#161616',
@ -33,5 +62,5 @@ module.exports = {
scrollbar: ['dark'], scrollbar: ['dark'],
extend: {} extend: {}
}, },
plugins: [require('tailwindcss-scrollbar')] plugins: [require('tailwindcss-scrollbar'), require('daisyui')]
}; };

View File

@ -6,20 +6,20 @@
"repository": "github:coollabsio/coolify", "repository": "github:coollabsio/coolify",
"scripts": { "scripts": {
"oc": "opencollective-setup", "oc": "opencollective-setup",
"db:studio": "pnpm run --filter coolify-api db:studio", "db:studio": "pnpm run --filter api db:studio",
"db:push": "pnpm run --filter coolify-api db:push", "db:push": "pnpm run --filter api db:push",
"db:seed": "pnpm run --filter coolify-api db:seed", "db:seed": "pnpm run --filter api db:seed",
"db:migrate": "pnpm run --filter coolify-api db:migrate", "db:migrate": "pnpm run --filter api db:migrate",
"format": "run-p -l -n format:*", "format": "run-p -l -n format:*",
"format:api": "NODE_ENV=development pnpm run --filter coolify-api format", "format:api": "NODE_ENV=development pnpm run --filter api format",
"lint": "run-p -l -n lint:*", "lint": "run-p -l -n lint:*",
"lint:api": "NODE_ENV=development pnpm run --filter coolify-api lint", "lint:api": "NODE_ENV=development pnpm run --filter api lint",
"dev": "run-p -l -n dev:*", "dev": "run-p -l -n dev:*",
"dev:api": "NODE_ENV=development pnpm run --filter coolify-api dev", "dev:api": "NODE_ENV=development pnpm run --filter api dev",
"dev:ui": "NODE_ENV=development pnpm run --filter coolify-ui dev", "dev:ui": "NODE_ENV=development pnpm run --filter ui dev",
"build": "NODE_ENV=production run-p -n build:*", "build": "NODE_ENV=production run-p -n build:*",
"build:api": "NODE_ENV=production pnpm run --filter coolify-api build", "build:api": "NODE_ENV=production pnpm run --filter api build",
"build:ui": "NODE_ENV=production pnpm run --filter coolify-ui build", "build:ui": "NODE_ENV=production pnpm run --filter ui build",
"dockerlogin": "echo $DOCKER_PASS | docker login --username=$DOCKER_USER --password-stdin", "dockerlogin": "echo $DOCKER_PASS | docker login --username=$DOCKER_USER --password-stdin",
"release:staging:amd": "cross-var docker buildx build --platform linux/amd64 -t coollabsio/coolify:$npm_package_version --push .", "release:staging:amd": "cross-var docker buildx build --platform linux/amd64 -t coollabsio/coolify:$npm_package_version --push .",
"release:local": "rm -fr ./local-serve && mkdir ./local-serve && pnpm build && cp -Rp apps/api/build/* ./local-serve && cp -Rp apps/ui/build/ ./local-serve/public && cp -Rp apps/api/prisma/ ./local-serve/prisma && cp -Rp apps/api/package.json ./local-serve && env | grep '^COOLIFY_' > ./local-serve/.env && cd ./local-serve && pnpm install . && pnpm start" "release:local": "rm -fr ./local-serve && mkdir ./local-serve && pnpm build && cp -Rp apps/api/build/* ./local-serve && cp -Rp apps/ui/build/ ./local-serve/public && cp -Rp apps/api/prisma/ ./local-serve/prisma && cp -Rp apps/api/package.json ./local-serve && env | grep '^COOLIFY_' > ./local-serve/.env && cd ./local-serve && pnpm install . && pnpm start"

149
pnpm-lock.yaml generated
View File

@ -22,7 +22,7 @@ importers:
'@fastify/jwt': 6.3.1 '@fastify/jwt': 6.3.1
'@fastify/static': 6.4.1 '@fastify/static': 6.4.1
'@iarna/toml': 2.2.5 '@iarna/toml': 2.2.5
'@prisma/client': 4.1.0 '@prisma/client': 3.15.2
'@types/node': 18.6.1 '@types/node': 18.6.1
'@types/node-os-utils': 1.3.0 '@types/node-os-utils': 1.3.0
'@typescript-eslint/eslint-plugin': 5.31.0 '@typescript-eslint/eslint-plugin': 5.31.0
@ -54,7 +54,7 @@ importers:
nodemon: 2.0.19 nodemon: 2.0.19
p-queue: 7.2.0 p-queue: 7.2.0
prettier: 2.7.1 prettier: 2.7.1
prisma: 4.1.0 prisma: 3.15.2
public-ip: 6.0.1 public-ip: 6.0.1
rimraf: 3.0.2 rimraf: 3.0.2
ssh-config: 4.1.6 ssh-config: 4.1.6
@ -71,7 +71,7 @@ importers:
'@fastify/jwt': 6.3.1 '@fastify/jwt': 6.3.1
'@fastify/static': 6.4.1 '@fastify/static': 6.4.1
'@iarna/toml': 2.2.5 '@iarna/toml': 2.2.5
'@prisma/client': 4.1.0_prisma@4.1.0 '@prisma/client': 3.15.2_prisma@3.15.2
axios: 0.27.2 axios: 0.27.2
bcryptjs: 2.4.3 bcryptjs: 2.4.3
bree: 9.1.1 bree: 9.1.1
@ -108,7 +108,7 @@ importers:
eslint-plugin-prettier: 4.2.1_g4fztgbwjyq2fvmcscny2sj6fy eslint-plugin-prettier: 4.2.1_g4fztgbwjyq2fvmcscny2sj6fy
nodemon: 2.0.19 nodemon: 2.0.19
prettier: 2.7.1 prettier: 2.7.1
prisma: 4.1.0 prisma: 3.15.2
rimraf: 3.0.2 rimraf: 3.0.2
tsconfig-paths: 4.0.0 tsconfig-paths: 4.0.0
typescript: 4.7.4 typescript: 4.7.4
@ -124,6 +124,7 @@ importers:
'@zerodevx/svelte-toast': 0.7.2 '@zerodevx/svelte-toast': 0.7.2
autoprefixer: 10.4.7 autoprefixer: 10.4.7
cuid: 2.1.8 cuid: 2.1.8
daisyui: ^2.22.0
eslint: 8.20.0 eslint: 8.20.0
eslint-config-prettier: 8.5.0 eslint-config-prettier: 8.5.0
eslint-plugin-svelte3: 4.0.0 eslint-plugin-svelte3: 4.0.0
@ -146,6 +147,7 @@ importers:
'@sveltejs/adapter-static': 1.0.0-next.37 '@sveltejs/adapter-static': 1.0.0-next.37
'@zerodevx/svelte-toast': 0.7.2 '@zerodevx/svelte-toast': 0.7.2
cuid: 2.1.8 cuid: 2.1.8
daisyui: 2.22.0_ugi4xkrfysqkt4c4y6hkyfj344
js-cookie: 3.0.1 js-cookie: 3.0.1
p-limit: 4.0.0 p-limit: 4.0.0
svelte-select: 4.4.7 svelte-select: 4.4.7
@ -373,12 +375,10 @@ packages:
dependencies: dependencies:
'@nodelib/fs.stat': 2.0.5 '@nodelib/fs.stat': 2.0.5
run-parallel: 1.2.0 run-parallel: 1.2.0
dev: true
/@nodelib/fs.stat/2.0.5: /@nodelib/fs.stat/2.0.5:
resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
dev: true
/@nodelib/fs.walk/1.2.8: /@nodelib/fs.walk/1.2.8:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
@ -386,7 +386,6 @@ packages:
dependencies: dependencies:
'@nodelib/fs.scandir': 2.1.5 '@nodelib/fs.scandir': 2.1.5
fastq: 1.13.0 fastq: 1.13.0
dev: true
/@playwright/test/1.23.4: /@playwright/test/1.23.4:
resolution: {integrity: sha512-iIsoMJDS/lyuhw82FtcV/B3PXikgVD3hNe5hyvOpRM0uRr1OIpN3LgPeRbBjhzBWmyf6RgRg5fqK5sVcpA03yA==} resolution: {integrity: sha512-iIsoMJDS/lyuhw82FtcV/B3PXikgVD3hNe5hyvOpRM0uRr1OIpN3LgPeRbBjhzBWmyf6RgRg5fqK5sVcpA03yA==}
@ -397,9 +396,9 @@ packages:
playwright-core: 1.23.4 playwright-core: 1.23.4
dev: true dev: true
/@prisma/client/4.1.0_prisma@4.1.0: /@prisma/client/3.15.2_prisma@3.15.2:
resolution: {integrity: sha512-MvfPGAd42vHTiCYxwS6N+2U3F+ukoJ48D2QRnX1zSPJHBkh1CBtshl75daKzvVfgQwSouzSQeugKDej5di+E/g==} resolution: {integrity: sha512-ErqtwhX12ubPhU4d++30uFY/rPcyvjk+mdifaZO5SeM21zS3t4jQrscy8+6IyB0GIYshl5ldTq6JSBo1d63i8w==}
engines: {node: '>=14.17'} engines: {node: '>=12.6'}
requiresBuild: true requiresBuild: true
peerDependencies: peerDependencies:
prisma: '*' prisma: '*'
@ -407,16 +406,16 @@ packages:
prisma: prisma:
optional: true optional: true
dependencies: dependencies:
'@prisma/engines-version': 4.1.0-48.8d8414deb360336e4698a65aa45a1fbaf1ce13d8 '@prisma/engines-version': 3.15.1-1.461d6a05159055555eb7dfb337c9fb271cbd4d7e
prisma: 4.1.0 prisma: 3.15.2
dev: false dev: false
/@prisma/engines-version/4.1.0-48.8d8414deb360336e4698a65aa45a1fbaf1ce13d8: /@prisma/engines-version/3.15.1-1.461d6a05159055555eb7dfb337c9fb271cbd4d7e:
resolution: {integrity: sha512-cRRJwpHFGFJZvtHbY3GZjMffNBEjjZk68ztn+S2hDgPCGB4H66IK26roK94GJxBodSehwRJ0wGyebC2GoIH1JQ==} resolution: {integrity: sha512-e3k2Vd606efd1ZYy2NQKkT4C/pn31nehyLhVug6To/q8JT8FpiMrDy7zmm3KLF0L98NOQQcutaVtAPhzKhzn9w==}
dev: false dev: false
/@prisma/engines/4.1.0: /@prisma/engines/3.15.1-1.461d6a05159055555eb7dfb337c9fb271cbd4d7e:
resolution: {integrity: sha512-quqHXD3P83NBLVtRlts4SgKHmqgA8GMiyDTJ7af03Wg0gl6F5t65mBYvIuwmD+52vHm42JtIsp/fAO9YIV0JBA==} resolution: {integrity: sha512-NHlojO1DFTsSi3FtEleL9QWXeSF/UjhCW0fgpi7bumnNZ4wj/eQ+BJJ5n2pgoOliTOGv9nX2qXvmHap7rJMNmg==}
requiresBuild: true requiresBuild: true
/@rollup/pluginutils/4.2.1: /@rollup/pluginutils/4.2.1:
@ -867,12 +866,10 @@ packages:
acorn: 7.4.1 acorn: 7.4.1
acorn-walk: 7.2.0 acorn-walk: 7.2.0
xtend: 4.0.2 xtend: 4.0.2
dev: true
/acorn-walk/7.2.0: /acorn-walk/7.2.0:
resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==}
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
dev: true
/acorn-walk/8.2.0: /acorn-walk/8.2.0:
resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
@ -883,7 +880,6 @@ packages:
resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
hasBin: true hasBin: true
dev: true
/acorn/8.7.1: /acorn/8.7.1:
resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==} resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==}
@ -981,7 +977,6 @@ packages:
dependencies: dependencies:
normalize-path: 3.0.0 normalize-path: 3.0.0
picomatch: 2.3.1 picomatch: 2.3.1
dev: true
/archy/1.0.0: /archy/1.0.0:
resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==}
@ -993,7 +988,6 @@ packages:
/arg/5.0.2: /arg/5.0.2:
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
dev: true
/argparse/2.0.1: /argparse/2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
@ -1051,7 +1045,6 @@ packages:
picocolors: 1.0.0 picocolors: 1.0.0
postcss: 8.4.14 postcss: 8.4.14
postcss-value-parser: 4.2.0 postcss-value-parser: 4.2.0
dev: true
/avvio/8.1.3: /avvio/8.1.3:
resolution: {integrity: sha512-tl9TC0yDRKzP6gFLkrInqPyx8AkfBC/0QRnwkE9Jo31+OJjLrE/73GJuE0QgSB0Vpv38CTJJZGqU9hczowclWw==} resolution: {integrity: sha512-tl9TC0yDRKzP6gFLkrInqPyx8AkfBC/0QRnwkE9Jo31+OJjLrE/73GJuE0QgSB0Vpv38CTJJZGqU9hczowclWw==}
@ -1787,7 +1780,6 @@ packages:
/binary-extensions/2.2.0: /binary-extensions/2.2.0:
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true
/bl/4.1.0: /bl/4.1.0:
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
@ -1823,7 +1815,6 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dependencies: dependencies:
fill-range: 7.0.1 fill-range: 7.0.1
dev: true
/bree/9.1.1: /bree/9.1.1:
resolution: {integrity: sha512-jNTi5+Su6AQfSz155Z3FJb+nNVexxWKlIp3SvPE5dAH0zr0ffzpK61BN943IF5+ZlJjQhyG5VcprCQY/Wjpdrw==} resolution: {integrity: sha512-jNTi5+Su6AQfSz155Z3FJb+nNVexxWKlIp3SvPE5dAH0zr0ffzpK61BN943IF5+ZlJjQhyG5VcprCQY/Wjpdrw==}
@ -1854,7 +1845,6 @@ packages:
electron-to-chromium: 1.4.191 electron-to-chromium: 1.4.191
node-releases: 2.0.6 node-releases: 2.0.6
update-browserslist-db: 1.0.4_browserslist@4.21.2 update-browserslist-db: 1.0.4_browserslist@4.21.2
dev: true
/bson-objectid/1.3.1: /bson-objectid/1.3.1:
resolution: {integrity: sha512-eQBNQXsisEAXlwiSy8zRNZdW2xDBJaEVkTPbodYR9hGxxtE548Qq7ilYOd8WAQ86xF7NRUdiWSQ1pa/TkKiE2A==} resolution: {integrity: sha512-eQBNQXsisEAXlwiSy8zRNZdW2xDBJaEVkTPbodYR9hGxxtE548Qq7ilYOd8WAQ86xF7NRUdiWSQ1pa/TkKiE2A==}
@ -1929,7 +1919,6 @@ packages:
/camelcase-css/2.0.1: /camelcase-css/2.0.1:
resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
dev: true
/camelcase/5.3.1: /camelcase/5.3.1:
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
@ -1938,7 +1927,6 @@ packages:
/caniuse-lite/1.0.30001366: /caniuse-lite/1.0.30001366:
resolution: {integrity: sha512-yy7XLWCubDobokgzudpkKux8e0UOOnLHE6mlNJBzT3lZJz6s5atSEzjoL+fsCPkI0G8MP5uVdDx1ur/fXEWkZA==} resolution: {integrity: sha512-yy7XLWCubDobokgzudpkKux8e0UOOnLHE6mlNJBzT3lZJz6s5atSEzjoL+fsCPkI0G8MP5uVdDx1ur/fXEWkZA==}
dev: true
/chalk/1.1.3: /chalk/1.1.3:
resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==}
@ -1984,7 +1972,6 @@ packages:
readdirp: 3.6.0 readdirp: 3.6.0
optionalDependencies: optionalDependencies:
fsevents: 2.3.2 fsevents: 2.3.2
dev: true
/chownr/1.1.4: /chownr/1.1.4:
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
@ -2036,14 +2023,27 @@ packages:
engines: {node: '>=7.0.0'} engines: {node: '>=7.0.0'}
dependencies: dependencies:
color-name: 1.1.4 color-name: 1.1.4
dev: true
/color-name/1.1.3: /color-name/1.1.3:
resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
/color-name/1.1.4: /color-name/1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
dev: true
/color-string/1.9.1:
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
dependencies:
color-name: 1.1.4
simple-swizzle: 0.2.2
dev: false
/color/4.2.3:
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
engines: {node: '>=12.5.0'}
dependencies:
color-convert: 2.0.1
color-string: 1.9.1
dev: false
/combine-errors/3.0.3: /combine-errors/3.0.3:
resolution: {integrity: sha512-C8ikRNRMygCwaTx+Ek3Yr+OuZzgZjduCOfSQBjbM8V3MfgcjSTeto/GXP6PAwKvJz/v15b7GHZvx5rOlczFw/Q==} resolution: {integrity: sha512-C8ikRNRMygCwaTx+Ek3Yr+OuZzgZjduCOfSQBjbM8V3MfgcjSTeto/GXP6PAwKvJz/v15b7GHZvx5rOlczFw/Q==}
@ -2195,11 +2195,17 @@ packages:
- supports-color - supports-color
dev: true dev: true
/css-selector-tokenizer/0.8.0:
resolution: {integrity: sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==}
dependencies:
cssesc: 3.0.0
fastparse: 1.1.2
dev: false
/cssesc/3.0.0: /cssesc/3.0.0:
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
engines: {node: '>=4'} engines: {node: '>=4'}
hasBin: true hasBin: true
dev: true
/cuid/2.1.8: /cuid/2.1.8:
resolution: {integrity: sha512-xiEMER6E7TlTPnDxrM4eRiC6TRgjNX9xzEZ5U/Se2YJKr7Mq4pJn/2XEHjl3STcSh96GmkHPcBXLES8M29wyyg==} resolution: {integrity: sha512-xiEMER6E7TlTPnDxrM4eRiC6TRgjNX9xzEZ5U/Se2YJKr7Mq4pJn/2XEHjl3STcSh96GmkHPcBXLES8M29wyyg==}
@ -2209,6 +2215,22 @@ packages:
resolution: {integrity: sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==} resolution: {integrity: sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==}
dev: false dev: false
/daisyui/2.22.0_ugi4xkrfysqkt4c4y6hkyfj344:
resolution: {integrity: sha512-H08aQP+Mfl2fQOmyaxd1NP54gQbr2xRUj2MmFFvfJ5EDGbthVBICDMNFKyia/zBfR58G8eTJo3CmydglM81/7Q==}
peerDependencies:
autoprefixer: ^10.0.2
postcss: ^8.1.6
dependencies:
autoprefixer: 10.4.7_postcss@8.4.14
color: 4.2.3
css-selector-tokenizer: 0.8.0
postcss: 8.4.14
postcss-js: 4.0.0_postcss@8.4.14
tailwindcss: 3.1.6
transitivePeerDependencies:
- ts-node
dev: false
/dayjs/1.11.4: /dayjs/1.11.4:
resolution: {integrity: sha512-Zj/lPM5hOvQ1Bf7uAvewDaUcsJoI6JmNqmHhHl3nyumwe0XHwt8sWdOVAPACJzCebL8gQCi+K49w7iKWnGwX9g==} resolution: {integrity: sha512-Zj/lPM5hOvQ1Bf7uAvewDaUcsJoI6JmNqmHhHl3nyumwe0XHwt8sWdOVAPACJzCebL8gQCi+K49w7iKWnGwX9g==}
dev: false dev: false
@ -2288,7 +2310,6 @@ packages:
/defined/1.0.0: /defined/1.0.0:
resolution: {integrity: sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==} resolution: {integrity: sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==}
dev: true
/delayed-stream/1.0.0: /delayed-stream/1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
@ -2330,7 +2351,6 @@ packages:
acorn-node: 1.8.2 acorn-node: 1.8.2
defined: 1.0.0 defined: 1.0.0
minimist: 1.2.6 minimist: 1.2.6
dev: true
/dezalgo/1.0.3: /dezalgo/1.0.3:
resolution: {integrity: sha512-K7i4zNfT2kgQz3GylDw40ot9GAE47sFZ9EXHFSPP6zONLgH6kWXE0KWJchkbQJLBkRazq4APwZ4OwiFFlT95OQ==} resolution: {integrity: sha512-K7i4zNfT2kgQz3GylDw40ot9GAE47sFZ9EXHFSPP6zONLgH6kWXE0KWJchkbQJLBkRazq4APwZ4OwiFFlT95OQ==}
@ -2341,7 +2361,6 @@ packages:
/didyoumean/1.2.2: /didyoumean/1.2.2:
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
dev: true
/diff/4.0.2: /diff/4.0.2:
resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
@ -2357,7 +2376,6 @@ packages:
/dlv/1.1.3: /dlv/1.1.3:
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
dev: true
/dns-packet/5.4.0: /dns-packet/5.4.0:
resolution: {integrity: sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==} resolution: {integrity: sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==}
@ -2446,7 +2464,6 @@ packages:
/electron-to-chromium/1.4.191: /electron-to-chromium/1.4.191:
resolution: {integrity: sha512-MeEaiuoSFh4G+rrN+Ilm1KJr8pTTZloeLurcZ+PRcthvdK1gWThje+E6baL7/7LoNctrzCncavAG/j/vpES9jg==} resolution: {integrity: sha512-MeEaiuoSFh4G+rrN+Ilm1KJr8pTTZloeLurcZ+PRcthvdK1gWThje+E6baL7/7LoNctrzCncavAG/j/vpES9jg==}
dev: true
/emoji-regex/8.0.0: /emoji-regex/8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@ -2937,7 +2954,6 @@ packages:
/escalade/3.1.1: /escalade/3.1.1:
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
engines: {node: '>=6'} engines: {node: '>=6'}
dev: true
/escape-html/1.0.3: /escape-html/1.0.3:
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
@ -3159,7 +3175,6 @@ packages:
glob-parent: 5.1.2 glob-parent: 5.1.2
merge2: 1.4.1 merge2: 1.4.1
micromatch: 4.0.5 micromatch: 4.0.5
dev: true
/fast-json-stable-stringify/2.1.0: /fast-json-stable-stringify/2.1.0:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
@ -3244,6 +3259,10 @@ packages:
xtend: 4.0.2 xtend: 4.0.2
dev: false dev: false
/fastparse/1.1.2:
resolution: {integrity: sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==}
dev: false
/fastq/1.13.0: /fastq/1.13.0:
resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==}
dependencies: dependencies:
@ -3275,7 +3294,6 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dependencies: dependencies:
to-regex-range: 5.0.1 to-regex-range: 5.0.1
dev: true
/find-my-way/7.0.0: /find-my-way/7.0.0:
resolution: {integrity: sha512-NHVohYPYRXgj6jxXVRwm4iMQjA2ggJpyewHz7Nq7hvBnHoYJJIyHuxNzs8QLPTLQfoqxZzls2g6Zm79XMbhXjA==} resolution: {integrity: sha512-NHVohYPYRXgj6jxXVRwm4iMQjA2ggJpyewHz7Nq7hvBnHoYJJIyHuxNzs8QLPTLQfoqxZzls2g6Zm79XMbhXjA==}
@ -3356,7 +3374,6 @@ packages:
/fraction.js/4.2.0: /fraction.js/4.2.0:
resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==}
dev: true
/fresh/0.5.2: /fresh/0.5.2:
resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
@ -3375,7 +3392,6 @@ packages:
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin] os: [darwin]
requiresBuild: true requiresBuild: true
dev: true
optional: true optional: true
/function-bind/1.1.1: /function-bind/1.1.1:
@ -3451,14 +3467,12 @@ packages:
engines: {node: '>= 6'} engines: {node: '>= 6'}
dependencies: dependencies:
is-glob: 4.0.3 is-glob: 4.0.3
dev: true
/glob-parent/6.0.2: /glob-parent/6.0.2:
resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
engines: {node: '>=10.13.0'} engines: {node: '>=10.13.0'}
dependencies: dependencies:
is-glob: 4.0.3 is-glob: 4.0.3
dev: true
/glob/7.2.3: /glob/7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
@ -3733,6 +3747,10 @@ packages:
/is-arrayish/0.2.1: /is-arrayish/0.2.1:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
/is-arrayish/0.3.2:
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
dev: false
/is-bigint/1.0.4: /is-bigint/1.0.4:
resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
dependencies: dependencies:
@ -3744,7 +3762,6 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dependencies: dependencies:
binary-extensions: 2.2.0 binary-extensions: 2.2.0
dev: true
/is-boolean-object/1.1.2: /is-boolean-object/1.1.2:
resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
@ -3784,7 +3801,6 @@ packages:
/is-extglob/2.1.1: /is-extglob/2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true
/is-finite/1.1.0: /is-finite/1.1.0:
resolution: {integrity: sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==} resolution: {integrity: sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==}
@ -3808,7 +3824,6 @@ packages:
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dependencies: dependencies:
is-extglob: 2.1.1 is-extglob: 2.1.1
dev: true
/is-invalid-path/0.1.0: /is-invalid-path/0.1.0:
resolution: {integrity: sha512-aZMG0T3F34mTg4eTdszcGXx54oiZ4NtHSft3hWNJMGJXUUqdIj3cOZuHcU0nCWWcY3jd7yRe/3AEm3vSNTpBGQ==} resolution: {integrity: sha512-aZMG0T3F34mTg4eTdszcGXx54oiZ4NtHSft3hWNJMGJXUUqdIj3cOZuHcU0nCWWcY3jd7yRe/3AEm3vSNTpBGQ==}
@ -3847,7 +3862,6 @@ packages:
/is-number/7.0.0: /is-number/7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'} engines: {node: '>=0.12.0'}
dev: true
/is-port-reachable/4.0.0: /is-port-reachable/4.0.0:
resolution: {integrity: sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==} resolution: {integrity: sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==}
@ -4058,7 +4072,6 @@ packages:
/lilconfig/2.0.6: /lilconfig/2.0.6:
resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==}
engines: {node: '>=10'} engines: {node: '>=10'}
dev: true
/lines-and-columns/1.2.4: /lines-and-columns/1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
@ -4229,7 +4242,6 @@ packages:
/merge2/1.4.1: /merge2/1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
dev: true
/methods/1.1.2: /methods/1.1.2:
resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==}
@ -4242,7 +4254,6 @@ packages:
dependencies: dependencies:
braces: 3.0.2 braces: 3.0.2
picomatch: 2.3.1 picomatch: 2.3.1
dev: true
/mime-db/1.52.0: /mime-db/1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
@ -4360,7 +4371,6 @@ packages:
resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true hasBin: true
dev: true
/natural-compare/1.4.0: /natural-compare/1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
@ -4396,7 +4406,6 @@ packages:
/node-releases/2.0.6: /node-releases/2.0.6:
resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==}
dev: true
/nodemon/2.0.19: /nodemon/2.0.19:
resolution: {integrity: sha512-4pv1f2bMDj0Eeg/MhGqxrtveeQ5/G/UVe9iO6uTZzjnRluSA4PVWf8CW99LUPwGB3eNIA7zUFoP77YuI7hOc0A==} resolution: {integrity: sha512-4pv1f2bMDj0Eeg/MhGqxrtveeQ5/G/UVe9iO6uTZzjnRluSA4PVWf8CW99LUPwGB3eNIA7zUFoP77YuI7hOc0A==}
@ -4438,12 +4447,10 @@ packages:
/normalize-path/3.0.0: /normalize-path/3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true
/normalize-range/0.1.2: /normalize-range/0.1.2:
resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true
/normalize-url/6.1.0: /normalize-url/6.1.0:
resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==}
@ -4473,7 +4480,6 @@ packages:
/object-hash/3.0.0: /object-hash/3.0.0:
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
dev: true
/object-inspect/1.12.1: /object-inspect/1.12.1:
resolution: {integrity: sha512-Y/jF6vnvEtOPGiKD1+q+X0CiUYRQtEHp89MLLUJ7TUivtH8Ugn2+3A7Rynqk7BRsAoqeOQWnFnjpDrKSxDgIGA==} resolution: {integrity: sha512-Y/jF6vnvEtOPGiKD1+q+X0CiUYRQtEHp89MLLUJ7TUivtH8Ugn2+3A7Rynqk7BRsAoqeOQWnFnjpDrKSxDgIGA==}
@ -4743,12 +4749,10 @@ packages:
/picocolors/1.0.0: /picocolors/1.0.0:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
dev: true
/picomatch/2.3.1: /picomatch/2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'} engines: {node: '>=8.6'}
dev: true
/pidtree/0.3.1: /pidtree/0.3.1:
resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==}
@ -4759,7 +4763,6 @@ packages:
/pify/2.3.0: /pify/2.3.0:
resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true
/pify/3.0.0: /pify/3.0.0:
resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==}
@ -4817,7 +4820,6 @@ packages:
postcss-value-parser: 4.2.0 postcss-value-parser: 4.2.0
read-cache: 1.0.0 read-cache: 1.0.0
resolve: 1.22.1 resolve: 1.22.1
dev: true
/postcss-js/4.0.0_postcss@8.4.14: /postcss-js/4.0.0_postcss@8.4.14:
resolution: {integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==} resolution: {integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==}
@ -4827,7 +4829,6 @@ packages:
dependencies: dependencies:
camelcase-css: 2.0.1 camelcase-css: 2.0.1
postcss: 8.4.14 postcss: 8.4.14
dev: true
/postcss-load-config/3.1.4_postcss@8.4.14: /postcss-load-config/3.1.4_postcss@8.4.14:
resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
@ -4844,7 +4845,6 @@ packages:
lilconfig: 2.0.6 lilconfig: 2.0.6
postcss: 8.4.14 postcss: 8.4.14
yaml: 1.10.2 yaml: 1.10.2
dev: true
/postcss-nested/5.0.6_postcss@8.4.14: /postcss-nested/5.0.6_postcss@8.4.14:
resolution: {integrity: sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==} resolution: {integrity: sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==}
@ -4854,7 +4854,6 @@ packages:
dependencies: dependencies:
postcss: 8.4.14 postcss: 8.4.14
postcss-selector-parser: 6.0.10 postcss-selector-parser: 6.0.10
dev: true
/postcss-selector-parser/6.0.10: /postcss-selector-parser/6.0.10:
resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
@ -4862,11 +4861,9 @@ packages:
dependencies: dependencies:
cssesc: 3.0.0 cssesc: 3.0.0
util-deprecate: 1.0.2 util-deprecate: 1.0.2
dev: true
/postcss-value-parser/4.2.0: /postcss-value-parser/4.2.0:
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
dev: true
/postcss/8.4.14: /postcss/8.4.14:
resolution: {integrity: sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==} resolution: {integrity: sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==}
@ -4875,7 +4872,6 @@ packages:
nanoid: 3.3.4 nanoid: 3.3.4
picocolors: 1.0.0 picocolors: 1.0.0
source-map-js: 1.0.2 source-map-js: 1.0.2
dev: true
/prelude-ls/1.2.1: /prelude-ls/1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
@ -4905,13 +4901,13 @@ packages:
hasBin: true hasBin: true
dev: true dev: true
/prisma/4.1.0: /prisma/3.15.2:
resolution: {integrity: sha512-iwqpAT6In1uvMSwQAM3PqmaBdhh2OaQ/2t+n3RjpW4vAKP3R7E1T34FZUU4zGOWtMWm5dt0sPThQkT/h87r6gw==} resolution: {integrity: sha512-nMNSMZvtwrvoEQ/mui8L/aiCLZRCj5t6L3yujKpcDhIPk7garp8tL4nMx2+oYsN0FWBacevJhazfXAbV1kfBzA==}
engines: {node: '>=14.17'} engines: {node: '>=12.6'}
hasBin: true hasBin: true
requiresBuild: true requiresBuild: true
dependencies: dependencies:
'@prisma/engines': 4.1.0 '@prisma/engines': 3.15.1-1.461d6a05159055555eb7dfb337c9fb271cbd4d7e
/private/0.1.8: /private/0.1.8:
resolution: {integrity: sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==} resolution: {integrity: sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==}
@ -5003,7 +4999,6 @@ packages:
resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
dependencies: dependencies:
pify: 2.3.0 pify: 2.3.0
dev: true
/read-pkg-up/7.0.1: /read-pkg-up/7.0.1:
resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==}
@ -5054,7 +5049,6 @@ packages:
engines: {node: '>=8.10.0'} engines: {node: '>=8.10.0'}
dependencies: dependencies:
picomatch: 2.3.1 picomatch: 2.3.1
dev: true
/real-require/0.1.0: /real-require/0.1.0:
resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==}
@ -5154,7 +5148,6 @@ packages:
is-core-module: 2.9.0 is-core-module: 2.9.0
path-parse: 1.0.7 path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0 supports-preserve-symlinks-flag: 1.0.0
dev: true
/responselike/2.0.0: /responselike/2.0.0:
resolution: {integrity: sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==} resolution: {integrity: sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==}
@ -5214,7 +5207,6 @@ packages:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
dependencies: dependencies:
queue-microtask: 1.2.3 queue-microtask: 1.2.3
dev: true
/rxjs/6.6.7: /rxjs/6.6.7:
resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==}
@ -5355,6 +5347,12 @@ packages:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
dev: true dev: true
/simple-swizzle/0.2.2:
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
dependencies:
is-arrayish: 0.3.2
dev: false
/simple-update-notifier/1.0.7: /simple-update-notifier/1.0.7:
resolution: {integrity: sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==} resolution: {integrity: sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==}
engines: {node: '>=8.10.0'} engines: {node: '>=8.10.0'}
@ -5391,7 +5389,6 @@ packages:
/source-map-js/1.0.2: /source-map-js/1.0.2:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true
/source-map-support/0.4.18: /source-map-support/0.4.18:
resolution: {integrity: sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==} resolution: {integrity: sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==}
@ -5744,7 +5741,6 @@ packages:
resolve: 1.22.1 resolve: 1.22.1
transitivePeerDependencies: transitivePeerDependencies:
- ts-node - ts-node
dev: true
/tar-fs/2.0.1: /tar-fs/2.0.1:
resolution: {integrity: sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==} resolution: {integrity: sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==}
@ -5816,7 +5812,6 @@ packages:
engines: {node: '>=8.0'} engines: {node: '>=8.0'}
dependencies: dependencies:
is-number: 7.0.0 is-number: 7.0.0
dev: true
/toidentifier/1.0.1: /toidentifier/1.0.1:
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
@ -5964,7 +5959,6 @@ packages:
browserslist: 4.21.2 browserslist: 4.21.2
escalade: 3.1.1 escalade: 3.1.1
picocolors: 1.0.0 picocolors: 1.0.0
dev: true
/uri-js/4.4.1: /uri-js/4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
@ -6073,7 +6067,6 @@ packages:
/yaml/1.10.2: /yaml/1.10.2:
resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
dev: true
/yn/3.1.1: /yn/3.1.1:
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}