chore: lint all the files

This commit is contained in:
Alexis
2021-09-02 17:30:33 +09:30
parent c93799a014
commit 4ef387b5bb
74 changed files with 404 additions and 368 deletions
+5 -5
View File
@@ -3,7 +3,7 @@
* Written by: Alexis Tyler
*/
import path from 'path';
import path from 'node:path';
import packageJson from 'package-json';
import dlTgz from 'dl-tgz';
import observableToPromise from 'observable-to-promise';
@@ -35,19 +35,19 @@ export const addPlugin = async (context: Context): Promise<CoreResult> => {
// Validation
const missingFields = hasFields(context.data, ['name']);
if (missingFields.length !== 0) {
if (missingFields.length > 0) {
// Log first error.
throw new FieldMissingError(missingFields[0]);
}
// Get package metadata
const { name, version } = context.data;
const pkg = await packageJson(name, {
const package_ = await packageJson(name, {
allVersions: Boolean(version)
});
// Plugin tgz url
const latest = pkg.versions[version];
const latest = package_.versions[version];
const url = latest.dist.tarball;
const pluginCwd = paths.get('plugins')!;
@@ -63,7 +63,7 @@ export const addPlugin = async (context: Context): Promise<CoreResult> => {
return {
text: 'Plugin added successfully.',
json: {
pkg
pkg: package_
}
};
};
+1 -1
View File
@@ -37,7 +37,7 @@ export const addUser = async (context: Context): Promise<CoreResult> => {
const { name, description = '', password } = data;
const missingFields = hasFields(data, ['name', 'password']);
if (missingFields.length !== 0) {
if (missingFields.length > 0) {
// Only log first error.
throw new FieldMissingError(missingFields[0]);
}
+1 -1
View File
@@ -22,7 +22,7 @@ export const addDiskToArray = async function (context: CoreContext): Promise<Cor
});
const missingFields = hasFields(data, ['id']);
if (missingFields.length !== 0) {
if (missingFields.length > 0) {
// Just log first error
throw new FieldMissingError(missingFields[0]);
}
@@ -31,7 +31,7 @@ export const removeDiskFromArray = async (context: Context): Promise<CoreResult>
const missingFields = hasFields(data, ['id']);
if (missingFields.length !== 0) {
if (missingFields.length > 0) {
// Only log first error
throw new FieldMissingError(missingFields[0]);
}
+3 -3
View File
@@ -5,7 +5,7 @@
import { CoreContext, CoreResult } from '../../types';
import { hasFields, ensurePermission, emcmd, arrayIsRunning, uppercaseFirstChar } from '../../utils';
import { AppError, FieldMissingError, ParamInvalidError } from '../../errors';
import { AppError, FieldMissingError, ParameterInvalidError } from '../../errors';
import { getArray } from '..';
// @TODO: Fix this not working across node apps
@@ -25,7 +25,7 @@ export const updateArray = async (context: CoreContext): Promise<CoreResult> =>
const missingFields = hasFields(data, ['state']);
if (missingFields.length !== 0) {
if (missingFields.length > 0) {
// Only log first error
throw new FieldMissingError(missingFields[0]);
}
@@ -35,7 +35,7 @@ export const updateArray = async (context: CoreContext): Promise<CoreResult> =>
const pendingState = nextState === 'stop' ? 'stopping' : 'starting';
if (!['start', 'stop'].includes(nextState)) {
throw new ParamInvalidError('state', nextState);
throw new ParameterInvalidError('state', nextState);
}
// Prevent this running multiple times at once
@@ -4,7 +4,7 @@
*/
import { CoreContext, CoreResult } from '../../types';
import { FieldMissingError, ParamInvalidError } from '../../errors';
import { FieldMissingError, ParameterInvalidError } from '../../errors';
import { emcmd, ensurePermission } from '../../utils';
import { varState } from '../../states';
@@ -36,7 +36,7 @@ export const updateParityCheck = async (context: Context): Promise<CoreResult> =
throw new FieldMissingError('state');
}
const { state: wantedState } = data;
const { state: wantedState, correct } = data;
const running = varState?.data?.mdResync !== 0;
const states = {
pause: {
@@ -62,11 +62,11 @@ export const updateParityCheck = async (context: Context): Promise<CoreResult> =
// Only allow states from states object
if (!allowedStates.includes(wantedState)) {
throw new ParamInvalidError('state', wantedState);
throw new ParameterInvalidError('state', wantedState);
}
// Should we write correction to the parity during the check
const writeCorrectionsToParity = wantedState === 'start' && data.correct;
const writeCorrectionsToParity = wantedState === 'start' && correct;
await emcmd({
startState: 'STARTED',
@@ -3,7 +3,7 @@
* Written by: Alexis Tyler
*/
import fs from 'fs';
import fs from 'node:fs';
import camelCaseKeys from 'camelcase-keys';
import { paths } from '../../paths';
import { docker, catchHandlers, ensurePermission } from '../../utils';
+3 -3
View File
@@ -3,7 +3,7 @@
* Written by: Alexis Tyler
*/
import { promises as fs } from 'fs';
import { promises as fs } from 'node:fs';
import { CoreResult, CoreContext } from '../types';
import { paths } from '../paths';
import { FileMissingError } from '../errors';
@@ -47,7 +47,7 @@ export const getParityHistory = async (context: CoreContext): Promise<CoreResult
head: ['Date', 'Duration', 'Speed', 'Status', 'Errors']
});
// Update raw values with strings
parityChecks.forEach(check => {
for (const check of parityChecks) {
const array = Object.values({
...check,
speed: check.speed ? check.speed : 'Unavailable',
@@ -55,7 +55,7 @@ export const getParityHistory = async (context: CoreContext): Promise<CoreResult
status: check.status === '-4' ? 'Cancelled' : 'OK'
});
table.push(array);
});
}
return {
text: table.toString(),
+3 -5
View File
@@ -31,18 +31,16 @@ export const getPermissions = async function (context: CoreContext): Promise<Cor
}));
// Get all roles and their scopes
const grants = Object.entries(ac.getGrants())
const grants = Object.fromEntries(Object.entries(ac.getGrants())
.map(([name, grant]) => {
// @ts-expect-error
const { $extend, ...grants } = grant;
return [name, grants];
})
.reduce((object, {
.map(({
0: key,
1: value
}) => Object.assign(object, {
[key.toString()]: value
}), {});
}) => [key.toString(), value]));
return {
text: `Scopes: ${JSON.stringify(scopes, null, 2)}`,
+2 -2
View File
@@ -4,7 +4,7 @@
*/
import { CoreContext, CoreResult } from '../types';
import { ParamInvalidError } from '../errors';
import { ParameterInvalidError } from '../errors';
import { Plugin, pluginManager } from '../plugin-manager';
import { ensurePermission } from '../utils';
@@ -32,7 +32,7 @@ export const getPlugins = (context: Readonly<Context>): Result => {
const { filter = 'all' } = query;
if (!['all', 'active', 'inactive'].includes(filter)) {
throw new ParamInvalidError('filter', filter);
throw new ParameterInvalidError('filter', filter);
}
const plugins = pluginManager.getAllPlugins().map(plugin => {
+35 -21
View File
@@ -3,10 +3,9 @@
* Written by: Alexis Tyler
*/
import { getEmhttpdService, getUnraidApiService } from './services';
import { getEmhttpService, getUnraidApiService } from './services';
import { coreLogger } from '../log';
import { envs } from '../environments';
import { NodeService } from '../utils';
import { environmentVariables } from '../environments';
import { CoreResult, CoreContext } from '../types';
const devNames = [
@@ -18,7 +17,19 @@ const coreNames = [
'unraid-api'
];
interface ServiceResult extends CoreResult {
interface Uptime {
timestamp: string;
seconds?: number;
}
interface NodeService {
name: string;
online?: boolean;
uptime: Uptime;
version?: string;
}
interface ServiceResult extends CoreResult<NodeService> {
json: NodeService;
}
@@ -27,33 +38,36 @@ interface NodeServiceWithName extends NodeService {
}
/**
* Add name to services.
* Add name to results.
*
* @param services
* @param results
* @param names
*/
const addNameToService = (services: ServiceResult[], names: string[]): NodeServiceWithName[] => {
return services.map((service, index) => ({
name: names[index],
...service.json
}));
const addNameToResult = (results: Array<Result | ServiceResult>, names: string[]): NodeServiceWithName[] => {
return results.map((result, index) => {
const { name: _name, ...ResultData } = result.json;
return ({
name: names[index],
...ResultData
});
});
};
interface Result extends CoreResult {
interface Result extends CoreResult<NodeServiceWithName[]> {
json: NodeServiceWithName[];
}
const logErrorAndReturnEmptyArray = (error: Error) => {
coreLogger.error(error);
return [];
};
/**
* Get all services.
*/
export const getServices = async (context: CoreContext): Promise<Result> => {
const logErrorAndReturnEmptyArray = (error: Error) => {
coreLogger.error(error);
return [];
};
const devServices = envs.NODE_ENV === 'development' ? await Promise.all([
getEmhttpdService(context)
const devServices = environmentVariables.NODE_ENV === 'development' ? await Promise.all([
getEmhttpService(context)
]).catch(logErrorAndReturnEmptyArray) : [];
const coreServices = await Promise.all([
@@ -61,8 +75,8 @@ export const getServices = async (context: CoreContext): Promise<Result> => {
]).catch(logErrorAndReturnEmptyArray);
const result = [
...addNameToService(devServices, devNames),
...addNameToService(coreServices, coreNames)
...addNameToResult(devServices, devNames),
...addNameToResult(coreServices, coreNames)
];
return {
+52 -52
View File
@@ -89,7 +89,7 @@ const systemPciDevices = async (): Promise<PciDevice[]> => {
const processedDevices = await filterDevices(filteredDevices).then(async devices => {
return Promise.all(devices
// @ts-expect-error
.map(addDeviceClass)
.map(device => addDeviceClass(device))
.map(async device => {
// Attempt to get the current kernel-bound driver for this pci device
await isSymlink(`${basePath}${device.id}/driver`).then(symlink => {
@@ -136,6 +136,48 @@ const systemAudioDevices = systemPciDevices().then(devices => {
return devices.filter(device => device.class === 'audio' && !device.allowed);
});
const parseUsbDevices = (stdout: string) => stdout.split('\n').map(line => {
const regex = new RegExp(/^.+: ID (?<id>\S+)(?<name>.*)$/);
const result = regex.exec(line);
return (result!.groups as unknown as PciDevice);
}) || [];
// Remove boot drive
const filterBootDrive = (device: Readonly<PciDevice>): boolean => varState?.data?.flashGuid !== device.guid;
// Clean up the name
const sanitizeVendorName = (device: Readonly<PciDevice>) => {
const vendorname = sanitizeVendor(device.vendorname || '');
return {
...device,
vendorname
};
};
const parseDeviceLine = (line?: Readonly<string>): { value: string; string: string } => {
const emptyLine = { value: '', string: '' };
// If the line is blank return nothing
if (!line) {
return emptyLine;
}
// Parse the line
const [, _] = line.split(/[\t ]{2,}/).filter(Boolean);
// eslint-disable-next-line @typescript-eslint/prefer-regexp-exec
const match = _.match(/^(\S+)\s(.*)/)?.slice(1);
// If there's no match return nothing
if (!match) {
return emptyLine;
}
return {
value: match[0],
string: match[1]
};
};
/**
* System usb devices.
* @returns Array of USB devices.
@@ -150,46 +192,10 @@ const getSystemUSBDevices = async (): Promise<any[]> => {
});
}).catch(() => []);
// Remove boot drive
const filterBootDrive = (device: Readonly<PciDevice>): boolean => varState?.data?.flashGuid !== device.guid;
// Remove usb hubs
// @ts-expect-error
const filterUsbHubs = (device: Readonly<PciDevice>): boolean => !usbHubs.includes(device.id);
// Clean up the name
const sanitizeVendorName = (device: Readonly<PciDevice>) => {
const vendorname = sanitizeVendor(device.vendorname || '');
return {
...device,
vendorname
};
};
const parseDeviceLine = (line: Readonly<string>): { value: string; string: string } => {
const emptyLine = { value: '', string: '' };
// If the line is blank return nothing
if (!line) {
return emptyLine;
}
// Parse the line
const [, _] = line.split(/[ \t]{2,}/).filter(Boolean);
// eslint-disable-next-line @typescript-eslint/prefer-regexp-exec
const match = _.match(/^(\S+)\s(.*)/)?.slice(1);
// If there's no match return nothing
if (!match) {
return emptyLine;
}
return {
value: match[0],
string: match[1]
};
};
// Add extra fields to device
const parseDevice = (device: Readonly<PciDevice>) => {
const modifiedDevice: PciDevice = {
@@ -197,11 +203,11 @@ const getSystemUSBDevices = async (): Promise<any[]> => {
};
const info = execa.commandSync(`lsusb -d ${device.id} -v`).stdout.split('\n');
const deviceName = device.name.trim();
const iSerial = parseDeviceLine(info.filter(line => line.includes('iSerial'))[0]);
const iProduct = parseDeviceLine(info.filter(line => line.includes('iProduct'))[0]);
const iManufacturer = parseDeviceLine(info.filter(line => line.includes('iManufacturer'))[0]);
const idProduct = parseDeviceLine(info.filter(line => line.includes('idProduct'))[0]);
const idVendor = parseDeviceLine(info.filter(line => line.includes('idVendor'))[0]);
const iSerial = parseDeviceLine(info.find(line => line.includes('iSerial')));
const iProduct = parseDeviceLine(info.find(line => line.includes('iProduct')));
const iManufacturer = parseDeviceLine(info.find(line => line.includes('iManufacturer')));
const idProduct = parseDeviceLine(info.find(line => line.includes('idProduct')));
const idVendor = parseDeviceLine(info.find(line => line.includes('idVendor')));
const serial = `${iSerial.string.slice(8).slice(0, 4)}-${iSerial.string.slice(8).slice(4)}`;
const guid = `${idVendor.value.slice(2)}-${idProduct.value.slice(2)}-${serial}`;
@@ -226,19 +232,13 @@ const getSystemUSBDevices = async (): Promise<any[]> => {
return modifiedDevice;
};
const parseUsbDevices = (stdout: string) => stdout.split('\n').map(line => {
const regex = new RegExp(/^.+: ID (?<id>\S+)(?<name>.*)$/);
const result = regex.exec(line);
return (result!.groups as unknown as PciDevice);
}) || [];
// Get all usb devices
const usbDevices = await execa('lsusb').then(async ({ stdout }) => {
return parseUsbDevices(stdout)
.map(parseDevice)
.filter(filterBootDrive)
.filter(filterUsbHubs)
.map(sanitizeVendorName);
.map(device => parseDevice(device))
.filter(device => filterBootDrive(device))
.filter(device => filterUsbHubs(device))
.map(device => sanitizeVendorName(device));
});
return usbDevices;
+2 -2
View File
@@ -3,13 +3,13 @@
* Written by: Alexis Tyler
*/
import { uptime } from 'os';
import { uptime } from 'node:os';
import si from 'systeminformation';
import { CoreContext, CoreResult } from '../../types';
import { ensurePermission } from '../../utils';
// Get uptime on boot and convert to date
const bootTimestamp = new Date(new Date().getTime() - (uptime() * 1000));
const bootTimestamp = new Date(Date.now() - (uptime() * 1000));
/**
* Get OS info
+1 -1
View File
@@ -3,7 +3,7 @@
* Written by: Alexis Tyler
*/
import fs from 'fs';
import fs from 'node:fs';
import semver from 'semver';
import { paths } from '../../paths';
import { CacheManager } from '../../cache-manager';
+7 -3
View File
@@ -37,8 +37,12 @@ export const getVmsCount = async function (context: CoreContext): Promise<Result
try {
const hypervisor = await getHypervisor();
const activeDomains = await hypervisor.connectListAllDomains(ConnectListAllDomainsFlags.ACTIVE) as [];
const inactiveDomains = await hypervisor.connectListAllDomains(ConnectListAllDomainsFlags.INACTIVE) as [];
if (!hypervisor) {
throw new Error('No Hypervisor');
}
const activeDomains = await hypervisor.connectListAllDomains(ConnectListAllDomainsFlags.ACTIVE) as string[];
const inactiveDomains = await hypervisor.connectListAllDomains(ConnectListAllDomainsFlags.INACTIVE) as string[];
const installed = activeDomains.length + inactiveDomains.length;
const started = activeDomains.length;
@@ -58,6 +62,6 @@ export const getVmsCount = async function (context: CoreContext): Promise<Result
installed,
started
}
}
};
}
};
@@ -15,9 +15,9 @@ interface Result extends CoreResult {
}
/**
* Get emhttpd service info.
* Get emhttp service info.
*/
export const getEmhttpdService = async (context: CoreContext): Promise<Result> => {
export const getEmhttpService = async (context: CoreContext): Promise<Result> => {
const { user } = context;
// Check permissions
+1 -1
View File
@@ -1,4 +1,4 @@
// Created from 'create-ts-index'
export * from './get-emhttpd';
export * from './get-emhttp';
export * from './get-unraid-api';
+1 -1
View File
@@ -38,7 +38,7 @@ export const getShare = async function (context: Context): Promise<Result> {
const share = [
userShare,
diskShare
].filter(_ => _)[0];
].find(_ => _);
if (!share) {
throw new AppError('No share found with that name.', 404);
+1 -1
View File
@@ -32,7 +32,7 @@ export const addRole = async (context: Context): Promise<CoreResult> => {
const { name } = params;
const missingFields = hasFields(params, ['name']);
if (missingFields.length !== 0) {
if (missingFields.length > 0) {
throw new FieldMissingError(missingFields[0]);
}
+1 -1
View File
@@ -30,7 +30,7 @@ export const deleteUser = async (context: Context): Promise<CoreResult> => {
const { name } = params;
const missingFields = hasFields(params, ['name']);
if (missingFields.length !== 0) {
if (missingFields.length > 0) {
// Just throw the first error
throw new FieldMissingError(missingFields[0]);
}
+1 -1
View File
@@ -59,7 +59,7 @@ export const getDomains = async (context: CoreContext): Promise<CoreResult> => {
text: `Defined domains: ${JSON.stringify(activeDomainNames, null, 2)}\nActive domains: ${JSON.stringify(inactiveDomainNames, null, 2)}`,
json: resolvedDomains
};
} catch (error: unknown) {
} catch {
// If we hit an error expect libvirt to be offline
return {
text: `Defined domains: ${JSON.stringify([], null, 2)}\nActive domains: ${JSON.stringify([], null, 2)}`,