yaml validation

This commit is contained in:
Ben Phelps 2022-09-18 16:41:01 +03:00
parent b5065673ab
commit 17f54da524
11 changed files with 83 additions and 32 deletions

View file

@ -22,12 +22,6 @@ function resolveIcon(icon) {
} }
export default function Item({ service }) { export default function Item({ service }) {
const handleOnClick = () => {
if (service.href && service.href !== "#") {
window.open(service.href, "_blank").focus();
}
};
const hasLink = service.href && service.href !== "#"; const hasLink = service.href && service.href !== "#";
return ( return (
@ -41,13 +35,9 @@ export default function Item({ service }) {
<div className="flex select-none"> <div className="flex select-none">
{service.icon && {service.icon &&
(hasLink ? ( (hasLink ? (
<button <a type="button" href={service.href} className="flex-shrink-0 flex items-center justify-center w-12 ">
type="button"
onClick={handleOnClick}
className="flex-shrink-0 flex items-center justify-center w-12 "
>
<Image src={resolveIcon(service.icon)} width={32} height={32} alt="logo" /> <Image src={resolveIcon(service.icon)} width={32} height={32} alt="logo" />
</button> </a>
) : ( ) : (
<div className="flex-shrink-0 flex items-center justify-center w-12 "> <div className="flex-shrink-0 flex items-center justify-center w-12 ">
<Image src={resolveIcon(service.icon)} width={32} height={32} alt="logo" /> <Image src={resolveIcon(service.icon)} width={32} height={32} alt="logo" />
@ -57,7 +47,7 @@ export default function Item({ service }) {
{hasLink ? ( {hasLink ? (
<button <button
type="button" type="button"
onClick={handleOnClick} href={service.href}
className="flex-1 flex items-center justify-between rounded-r-md " className="flex-1 flex items-center justify-between rounded-r-md "
> >
<div className="flex-1 px-2 py-2 text-sm text-left"> <div className="flex-1 px-2 py-2 text-sm text-left">

View file

@ -0,0 +1,9 @@
import checkAndCopyConfig from "utils/config";
const configs = ["docker.yaml", "settings.yaml", "services.yaml", "bookmarks.yaml"];
export default async function handler(req, res) {
const errors = configs.map((config) => checkAndCopyConfig(config)).filter((status) => status !== true);
res.send(errors);
}

View file

@ -14,7 +14,7 @@ export default async function handler(req, res) {
} }
if (!apiKey && provider) { if (!apiKey && provider) {
const settings = await getSettings(); const settings = getSettings();
apiKey = settings?.providers?.openweathermap; apiKey = settings?.providers?.openweathermap;
} }

View file

@ -14,7 +14,7 @@ export default async function handler(req, res) {
} }
if (!apiKey && provider) { if (!apiKey && provider) {
const settings = await getSettings(); const settings = getSettings();
apiKey = settings?.providers?.weatherapi; apiKey = settings?.providers?.weatherapi;
} }

View file

@ -4,6 +4,7 @@ import Head from "next/head";
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useEffect, useContext } from "react"; import { useEffect, useContext } from "react";
import { BiError } from "react-icons/bi";
import ServicesGroup from "components/services/group"; import ServicesGroup from "components/services/group";
import BookmarksGroup from "components/bookmarks/group"; import BookmarksGroup from "components/bookmarks/group";
@ -23,17 +24,54 @@ const ColorToggle = dynamic(() => import("components/color-toggle"), {
const rightAlignedWidgets = ["weatherapi", "openweathermap", "weather", "search", "datetime"]; const rightAlignedWidgets = ["weatherapi", "openweathermap", "weather", "search", "datetime"];
export async function getStaticProps() { export function getStaticProps() {
const settings = await getSettings(); try {
const settings = getSettings();
return { return {
props: { props: {
settings, settings,
}, },
}; };
} catch (e) {
return {
props: {
settings: {},
},
};
}
} }
export default function Home({ settings }) { export default function Index({ settings }) {
const { data: errorsData } = useSWR("/api/validate");
if (errorsData && errorsData.length > 0) {
return (
<div className="w-full container m-auto justify-center p-10">
<div className="flex flex-col">
{errorsData.map((error, i) => (
<div
className="basis-1/2 bg-theme-500 dark:bg-theme-600 text-theme-600 dark:text-theme-300 m-2 rounded-md font-mono shadow-md border-4 border-transparent"
key={i}
>
<div className="bg-amber-200 text-amber-800 dark:text-amber-200 dark:bg-amber-800 p-2 rounded-md font-bold">
<BiError className="float-right w-6 h-6" />
{error.config}
</div>
<div className="p-2 text-theme-100 dark:text-theme-200">
<pre className="opacity-50 font-bold pb-2">{error.reason}</pre>
<pre className="text-sm">{error.mark.snippet}</pre>
</div>
</div>
))}
</div>
</div>
);
}
return <Home settings={settings} />;
}
function Home({ settings }) {
const { i18n } = useTranslation(); const { i18n } = useTranslation();
const { theme, setTheme } = useContext(ThemeContext); const { theme, setTheme } = useContext(ThemeContext);
const { color, setColor } = useContext(ColorContext); const { color, setColor } = useContext(ColorContext);

View file

@ -1,3 +1,4 @@
---
# For configuration options and examples, please see: # For configuration options and examples, please see:
# https://github.com/benphelps/homepage/wiki/Bookmarks # https://github.com/benphelps/homepage/wiki/Bookmarks

View file

@ -1,9 +1,10 @@
---
# For configuration options and examples, please see: # For configuration options and examples, please see:
# https://github.com/benphelps/homepage/wiki/Docker-Integration # https://github.com/benphelps/homepage/wiki/Docker-Integration
my-docker: # my-docker:
host: 127.0.0.1 # host: 127.0.0.1
port: 2375 # port: 2375
other-docker: # my-docker:
socket: /var/run/docker.sock # socket: /var/run/docker.sock

View file

@ -1,3 +1,4 @@
---
# For configuration options and examples, please see: # For configuration options and examples, please see:
# https://github.com/benphelps/homepage/wiki/Services # https://github.com/benphelps/homepage/wiki/Services

View file

@ -1,3 +1,4 @@
---
# For configuration options and examples, please see: # For configuration options and examples, please see:
# https://github.com/benphelps/homepage/wiki/Settings # https://github.com/benphelps/homepage/wiki/Settings

View file

@ -1,3 +1,4 @@
---
# For configuration options and examples, please see: # For configuration options and examples, please see:
# https://github.com/benphelps/homepage/wiki/Information-Widgets # https://github.com/benphelps/homepage/wiki/Information-Widgets

View file

@ -1,6 +1,6 @@
/* eslint-disable no-console */ /* eslint-disable no-console */
import { join } from "path"; import { join } from "path";
import { existsSync, copyFile, promises as fs } from "fs"; import { existsSync, copyFile, readFileSync } from "fs";
import yaml from "js-yaml"; import yaml from "js-yaml";
@ -15,13 +15,22 @@ export default function checkAndCopyConfig(config) {
} }
console.info("%s was copied to the config folder", config); console.info("%s was copied to the config folder", config);
}); });
return true;
}
try {
yaml.load(readFileSync(configYaml, "utf8"));
return true;
} catch (e) {
return { ...e, config };
} }
} }
export async function getSettings() { export function getSettings() {
checkAndCopyConfig("settings.yaml"); checkAndCopyConfig("settings.yaml");
const settingsYaml = join(process.cwd(), "config", "settings.yaml"); const settingsYaml = join(process.cwd(), "config", "settings.yaml");
const fileContents = await fs.readFile(settingsYaml, "utf8"); const fileContents = readFileSync(settingsYaml, "utf8");
return yaml.load(fileContents); return yaml.load(fileContents);
} }