mirror of
https://github.com/gethomepage/homepage.git
synced 2025-12-07 09:35:54 -08:00
Run pre-commit hooks over existing codebase
Co-Authored-By: Ben Phelps <ben@phelps.io>
This commit is contained in:
@@ -9,7 +9,7 @@ import {
|
||||
servicesFromConfig,
|
||||
servicesFromDocker,
|
||||
cleanServiceGroups,
|
||||
servicesFromKubernetes
|
||||
servicesFromKubernetes,
|
||||
} from "utils/config/service-helpers";
|
||||
import { cleanWidgetGroups, widgetsFromConfig } from "utils/config/widget-helpers";
|
||||
|
||||
@@ -59,7 +59,7 @@ export async function bookmarksResponse() {
|
||||
|
||||
bookmarksArray.forEach((group) => {
|
||||
if (definedLayouts) {
|
||||
const layoutIndex = definedLayouts.findIndex(layout => layout === group.name);
|
||||
const layoutIndex = definedLayouts.findIndex((layout) => layout === group.name);
|
||||
if (layoutIndex > -1) sortedGroups[layoutIndex] = group;
|
||||
else unsortedGroups.push(group);
|
||||
} else {
|
||||
@@ -67,7 +67,7 @@ export async function bookmarksResponse() {
|
||||
}
|
||||
});
|
||||
|
||||
return [...sortedGroups.filter(g => g), ...unsortedGroups];
|
||||
return [...sortedGroups.filter((g) => g), ...unsortedGroups];
|
||||
}
|
||||
|
||||
export async function widgetsResponse() {
|
||||
@@ -126,11 +126,13 @@ export async function servicesResponse() {
|
||||
}
|
||||
|
||||
const mergedGroupsNames = [
|
||||
...new Set([
|
||||
discoveredDockerServices.map((group) => group.name),
|
||||
discoveredKubernetesServices.map((group) => group.name),
|
||||
configuredServices.map((group) => group.name),
|
||||
].flat()),
|
||||
...new Set(
|
||||
[
|
||||
discoveredDockerServices.map((group) => group.name),
|
||||
discoveredKubernetesServices.map((group) => group.name),
|
||||
configuredServices.map((group) => group.name),
|
||||
].flat(),
|
||||
),
|
||||
];
|
||||
|
||||
const sortedGroups = [];
|
||||
@@ -138,22 +140,23 @@ export async function servicesResponse() {
|
||||
const definedLayouts = initialSettings.layout ? Object.keys(initialSettings.layout) : null;
|
||||
|
||||
mergedGroupsNames.forEach((groupName) => {
|
||||
const discoveredDockerGroup = discoveredDockerServices.find((group) => group.name === groupName) || { services: [] };
|
||||
const discoveredKubernetesGroup = discoveredKubernetesServices.find((group) => group.name === groupName) || { services: [] };
|
||||
const discoveredDockerGroup = discoveredDockerServices.find((group) => group.name === groupName) || {
|
||||
services: [],
|
||||
};
|
||||
const discoveredKubernetesGroup = discoveredKubernetesServices.find((group) => group.name === groupName) || {
|
||||
services: [],
|
||||
};
|
||||
const configuredGroup = configuredServices.find((group) => group.name === groupName) || { services: [] };
|
||||
|
||||
const mergedGroup = {
|
||||
name: groupName,
|
||||
services: [
|
||||
...discoveredDockerGroup.services,
|
||||
...discoveredKubernetesGroup.services,
|
||||
...configuredGroup.services
|
||||
].filter((service) => service)
|
||||
services: [...discoveredDockerGroup.services, ...discoveredKubernetesGroup.services, ...configuredGroup.services]
|
||||
.filter((service) => service)
|
||||
.sort(compareServices),
|
||||
};
|
||||
|
||||
if (definedLayouts) {
|
||||
const layoutIndex = definedLayouts.findIndex(layout => layout === mergedGroup.name);
|
||||
const layoutIndex = definedLayouts.findIndex((layout) => layout === mergedGroup.name);
|
||||
if (layoutIndex > -1) sortedGroups[layoutIndex] = mergedGroup;
|
||||
else unsortedGroups.push(mergedGroup);
|
||||
} else {
|
||||
@@ -161,5 +164,5 @@ export async function servicesResponse() {
|
||||
}
|
||||
});
|
||||
|
||||
return [...sortedGroups.filter(g => g), ...unsortedGroups];
|
||||
return [...sortedGroups.filter((g) => g), ...unsortedGroups];
|
||||
}
|
||||
|
||||
@@ -9,22 +9,24 @@ const cacheKey = "homepageEnvironmentVariables";
|
||||
const homepageVarPrefix = "HOMEPAGE_VAR_";
|
||||
const homepageFilePrefix = "HOMEPAGE_FILE_";
|
||||
|
||||
export const CONF_DIR = process.env.HOMEPAGE_CONFIG_DIR ? process.env.HOMEPAGE_CONFIG_DIR : join(process.cwd(), "config");
|
||||
export const CONF_DIR = process.env.HOMEPAGE_CONFIG_DIR
|
||||
? process.env.HOMEPAGE_CONFIG_DIR
|
||||
: join(process.cwd(), "config");
|
||||
|
||||
export default function checkAndCopyConfig(config) {
|
||||
if (!existsSync(CONF_DIR)) {
|
||||
mkdirSync(CONF_DIR, { recursive: true });
|
||||
mkdirSync(CONF_DIR, { recursive: true });
|
||||
}
|
||||
|
||||
const configYaml = join(CONF_DIR, config);
|
||||
if (!existsSync(configYaml)) {
|
||||
const configSkeleton = join(process.cwd(), "src", "skeleton", config);
|
||||
try {
|
||||
copyFileSync(configSkeleton, configYaml)
|
||||
copyFileSync(configSkeleton, configYaml);
|
||||
console.info("%s was copied to the config folder", config);
|
||||
} catch (err) {
|
||||
console.error("error copying config", err);
|
||||
throw err;
|
||||
console.error("error copying config", err);
|
||||
throw err;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -42,7 +44,9 @@ function getCachedEnvironmentVars() {
|
||||
let cachedVars = cache.get(cacheKey);
|
||||
if (!cachedVars) {
|
||||
// initialize cache
|
||||
cachedVars = Object.entries(process.env).filter(([key, ]) => key.includes(homepageVarPrefix) || key.includes(homepageFilePrefix));
|
||||
cachedVars = Object.entries(process.env).filter(
|
||||
([key]) => key.includes(homepageVarPrefix) || key.includes(homepageFilePrefix),
|
||||
);
|
||||
cache.put(cacheKey, cachedVars);
|
||||
}
|
||||
return cachedVars;
|
||||
@@ -50,7 +54,8 @@ function getCachedEnvironmentVars() {
|
||||
|
||||
export function substituteEnvironmentVars(str) {
|
||||
let result = str;
|
||||
if (result.includes('{{')) { // crude check if we have vars to replace
|
||||
if (result.includes("{{")) {
|
||||
// crude check if we have vars to replace
|
||||
const cachedVars = getCachedEnvironmentVars();
|
||||
cachedVars.forEach(([key, value]) => {
|
||||
if (key.startsWith(homepageVarPrefix)) {
|
||||
@@ -77,13 +82,13 @@ export function getSettings() {
|
||||
// support yaml list but old spec was object so convert to that
|
||||
// see https://github.com/gethomepage/homepage/issues/1546
|
||||
if (Array.isArray(initialSettings.layout)) {
|
||||
const layoutItems = initialSettings.layout
|
||||
initialSettings.layout = {}
|
||||
layoutItems.forEach(i => {
|
||||
const name = Object.keys(i)[0]
|
||||
initialSettings.layout[name] = i[name]
|
||||
})
|
||||
const layoutItems = initialSettings.layout;
|
||||
initialSettings.layout = {};
|
||||
layoutItems.forEach((i) => {
|
||||
const name = Object.keys(i)[0];
|
||||
initialSettings.layout[name] = i[name];
|
||||
});
|
||||
}
|
||||
}
|
||||
return initialSettings
|
||||
return initialSettings;
|
||||
}
|
||||
|
||||
@@ -27,16 +27,16 @@ export default function getDockerArguments(server) {
|
||||
}
|
||||
|
||||
if (servers[server].host) {
|
||||
const res ={
|
||||
const res = {
|
||||
conn: { host: servers[server].host },
|
||||
swarm: !!servers[server].swarm,
|
||||
}
|
||||
};
|
||||
|
||||
if (servers[server].port){
|
||||
if (servers[server].port) {
|
||||
res.conn.port = servers[server].port;
|
||||
}
|
||||
|
||||
if (servers[server].tls){
|
||||
if (servers[server].tls) {
|
||||
res.conn.ca = readFileSync(path.join(CONF_DIR, servers[server].tls.caFile));
|
||||
res.conn.cert = readFileSync(path.join(CONF_DIR, servers[server].tls.certFile));
|
||||
res.conn.key = readFileSync(path.join(CONF_DIR, servers[server].tls.keyFile));
|
||||
|
||||
@@ -16,13 +16,13 @@ export default function getKubeConfig() {
|
||||
const kc = new KubeConfig();
|
||||
|
||||
switch (config?.mode) {
|
||||
case 'cluster':
|
||||
case "cluster":
|
||||
kc.loadFromCluster();
|
||||
break;
|
||||
case 'default':
|
||||
case "default":
|
||||
kc.loadFromDefault();
|
||||
break;
|
||||
case 'disabled':
|
||||
case "disabled":
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ export async function servicesFromDocker() {
|
||||
shvl.set(
|
||||
constructedService,
|
||||
label.replace("homepage.", ""),
|
||||
substituteEnvironmentVars(containerLabels[label])
|
||||
substituteEnvironmentVars(containerLabels[label]),
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -105,7 +105,7 @@ export async function servicesFromDocker() {
|
||||
// a server failed, but others may succeed
|
||||
return { server: serverName, services: [] };
|
||||
}
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
const mappedServiceGroups = [];
|
||||
@@ -152,13 +152,13 @@ export async function checkCRD(kc, name) {
|
||||
"Error checking if CRD %s exists. Make sure to add the following permission to your RBAC: %d %s %s",
|
||||
name,
|
||||
error.statusCode,
|
||||
error.body.message
|
||||
error.body.message,
|
||||
);
|
||||
}
|
||||
return false
|
||||
return false;
|
||||
});
|
||||
|
||||
return exist
|
||||
return exist;
|
||||
}
|
||||
|
||||
export async function servicesFromKubernetes() {
|
||||
@@ -195,7 +195,7 @@ export async function servicesFromKubernetes() {
|
||||
"Error getting traefik ingresses from traefik.containo.us: %d %s %s",
|
||||
error.statusCode,
|
||||
error.body,
|
||||
error.response
|
||||
error.response,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -211,18 +211,18 @@ export async function servicesFromKubernetes() {
|
||||
"Error getting traefik ingresses from traefik.io: %d %s %s",
|
||||
error.statusCode,
|
||||
error.body,
|
||||
error.response
|
||||
error.response,
|
||||
);
|
||||
}
|
||||
|
||||
return [];
|
||||
});
|
||||
|
||||
const traefikIngressList = [...traefikIngressListContaino?.items ?? [], ...traefikIngressListIo?.items ?? []];
|
||||
const traefikIngressList = [...(traefikIngressListContaino?.items ?? []), ...(traefikIngressListIo?.items ?? [])];
|
||||
|
||||
if (traefikIngressList.length > 0) {
|
||||
const traefikServices = traefikIngressList.filter(
|
||||
(ingress) => ingress.metadata.annotations && ingress.metadata.annotations[`${ANNOTATION_BASE}/href`]
|
||||
(ingress) => ingress.metadata.annotations && ingress.metadata.annotations[`${ANNOTATION_BASE}/href`],
|
||||
);
|
||||
ingressList.items.push(...traefikServices);
|
||||
}
|
||||
@@ -233,7 +233,7 @@ export async function servicesFromKubernetes() {
|
||||
const services = ingressList.items
|
||||
.filter(
|
||||
(ingress) =>
|
||||
ingress.metadata.annotations && ingress.metadata.annotations[`${ANNOTATION_BASE}/enabled`] === "true"
|
||||
ingress.metadata.annotations && ingress.metadata.annotations[`${ANNOTATION_BASE}/enabled`] === "true",
|
||||
)
|
||||
.map((ingress) => {
|
||||
let constructedService = {
|
||||
@@ -266,7 +266,7 @@ export async function servicesFromKubernetes() {
|
||||
shvl.set(
|
||||
constructedService,
|
||||
annotation.replace(`${ANNOTATION_BASE}/`, ""),
|
||||
ingress.metadata.annotations[annotation]
|
||||
ingress.metadata.annotations[annotation],
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -27,16 +27,14 @@ SOFTWARE.
|
||||
*/
|
||||
|
||||
export function get(object, path, def) {
|
||||
return (
|
||||
// Split the path into keys and reduce the object to the target value
|
||||
object = path.split(/[.[\]]+/).reduce(function (obj, p) {
|
||||
// Check each nested object to see if the key exists
|
||||
return obj && obj[p] !== undefined ? obj[p] : undefined;
|
||||
}, object)
|
||||
) === undefined
|
||||
// If the final value is undefined, return the default value
|
||||
? def
|
||||
: object; // Otherwise, return the value found
|
||||
// Split the path into keys and reduce the object to the target value
|
||||
return (object = path.split(/[.[\]]+/).reduce(function (obj, p) {
|
||||
// Check each nested object to see if the key exists
|
||||
return obj && obj[p] !== undefined ? obj[p] : undefined;
|
||||
}, object)) === undefined
|
||||
? // If the final value is undefined, return the default value
|
||||
def
|
||||
: object; // Otherwise, return the value found
|
||||
}
|
||||
|
||||
export function set(obj, path, val) {
|
||||
@@ -58,13 +56,11 @@ export function set(obj, path, val) {
|
||||
const isIndex = /^\d+$/.test(keys[i + 1]);
|
||||
|
||||
// If current key doesn't exist, initialise it as an array or object
|
||||
acc[key] = Array.isArray(acc[key])
|
||||
? acc[key]
|
||||
: (isIndex ? [] : acc[key] || {});
|
||||
acc[key] = Array.isArray(acc[key]) ? acc[key] : isIndex ? [] : acc[key] || {};
|
||||
|
||||
// Return nested object for next iteration
|
||||
return acc[key];
|
||||
}, obj)[lastKey] = val; // Finally set the value
|
||||
}, obj)[lastKey] = val; // Finally set the value
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
@@ -6,76 +6,72 @@ import yaml from "js-yaml";
|
||||
import checkAndCopyConfig, { CONF_DIR, substituteEnvironmentVars } from "utils/config/config";
|
||||
|
||||
export async function widgetsFromConfig() {
|
||||
checkAndCopyConfig("widgets.yaml");
|
||||
checkAndCopyConfig("widgets.yaml");
|
||||
|
||||
const widgetsYaml = path.join(CONF_DIR, "widgets.yaml");
|
||||
const rawFileContents = await fs.readFile(widgetsYaml, "utf8");
|
||||
const fileContents = substituteEnvironmentVars(rawFileContents);
|
||||
const widgets = yaml.load(fileContents);
|
||||
const widgetsYaml = path.join(CONF_DIR, "widgets.yaml");
|
||||
const rawFileContents = await fs.readFile(widgetsYaml, "utf8");
|
||||
const fileContents = substituteEnvironmentVars(rawFileContents);
|
||||
const widgets = yaml.load(fileContents);
|
||||
|
||||
if (!widgets) return [];
|
||||
if (!widgets) return [];
|
||||
|
||||
// map easy to write YAML objects into easy to consume JS arrays
|
||||
const widgetsArray = widgets.map((group, index) => ({
|
||||
type: Object.keys(group)[0],
|
||||
options: {
|
||||
index,
|
||||
...group[Object.keys(group)[0]]
|
||||
},
|
||||
}));
|
||||
return widgetsArray;
|
||||
// map easy to write YAML objects into easy to consume JS arrays
|
||||
const widgetsArray = widgets.map((group, index) => ({
|
||||
type: Object.keys(group)[0],
|
||||
options: {
|
||||
index,
|
||||
...group[Object.keys(group)[0]],
|
||||
},
|
||||
}));
|
||||
return widgetsArray;
|
||||
}
|
||||
|
||||
export async function cleanWidgetGroups(widgets) {
|
||||
return widgets.map((widget, index) => {
|
||||
const sanitizedOptions = widget.options;
|
||||
const optionKeys = Object.keys(sanitizedOptions);
|
||||
|
||||
// delete private options from the sanitized options
|
||||
["username", "password", "key"].forEach((pO) => {
|
||||
if (optionKeys.includes(pO)) {
|
||||
delete sanitizedOptions[pO];
|
||||
}
|
||||
});
|
||||
|
||||
// delete url from the sanitized options if the widget is not a search or glances widgeth
|
||||
if (widget.type !== "search" && widget.type !== "glances" && optionKeys.includes("url")) {
|
||||
delete sanitizedOptions.url;
|
||||
}
|
||||
return widgets.map((widget, index) => {
|
||||
const sanitizedOptions = widget.options;
|
||||
const optionKeys = Object.keys(sanitizedOptions);
|
||||
|
||||
return {
|
||||
type: widget.type,
|
||||
options: {
|
||||
index,
|
||||
...sanitizedOptions
|
||||
},
|
||||
}
|
||||
// delete private options from the sanitized options
|
||||
["username", "password", "key"].forEach((pO) => {
|
||||
if (optionKeys.includes(pO)) {
|
||||
delete sanitizedOptions[pO];
|
||||
}
|
||||
});
|
||||
|
||||
// delete url from the sanitized options if the widget is not a search or glances widgeth
|
||||
if (widget.type !== "search" && widget.type !== "glances" && optionKeys.includes("url")) {
|
||||
delete sanitizedOptions.url;
|
||||
}
|
||||
|
||||
return {
|
||||
type: widget.type,
|
||||
options: {
|
||||
index,
|
||||
...sanitizedOptions,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export async function getPrivateWidgetOptions(type, widgetIndex) {
|
||||
const widgets = await widgetsFromConfig();
|
||||
|
||||
const privateOptions = widgets.map((widget) => {
|
||||
const {
|
||||
index,
|
||||
url,
|
||||
username,
|
||||
password,
|
||||
key
|
||||
} = widget.options;
|
||||
const widgets = await widgetsFromConfig();
|
||||
|
||||
return {
|
||||
type: widget.type,
|
||||
options: {
|
||||
index,
|
||||
url,
|
||||
username,
|
||||
password,
|
||||
key
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
return (type !== undefined && widgetIndex !== undefined) ? privateOptions.find(o => o.type === type && o.options.index === parseInt(widgetIndex, 10))?.options : privateOptions;
|
||||
const privateOptions = widgets.map((widget) => {
|
||||
const { index, url, username, password, key } = widget.options;
|
||||
|
||||
return {
|
||||
type: widget.type,
|
||||
options: {
|
||||
index,
|
||||
url,
|
||||
username,
|
||||
password,
|
||||
key,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return type !== undefined && widgetIndex !== undefined
|
||||
? privateOptions.find((o) => o.type === type && o.options.index === parseInt(widgetIndex, 10))?.options
|
||||
: privateOptions;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user