mirror of
https://github.com/unraid/api.git
synced 2026-05-01 12:39:22 -05:00
fix: eslint config
This commit is contained in:
@@ -1,47 +0,0 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
root: true,
|
||||
plugins: [
|
||||
'@typescript-eslint/eslint-plugin',
|
||||
'unused-imports',
|
||||
'eslint-plugin-unicorn',
|
||||
],
|
||||
ignorePatterns: ['src/graphql/generated/**/*.ts', '*.test.ts', 'tsup.config.ts', 'vite.config.ts'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
rules: {
|
||||
'@typescript-eslint/no-redundant-type-constituents': 'off',
|
||||
'@typescript-eslint/no-unsafe-call': 'off',
|
||||
'@typescript-eslint/naming-convention': 'off',
|
||||
'@typescript-eslint/no-unsafe-assignment': 'off',
|
||||
'@typescript-eslint/no-unsafe-return': 'off',
|
||||
'@typescript-eslint/ban-types': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/consistent-type-imports': [
|
||||
'warn',
|
||||
{ fixStyle: 'inline-type-imports' },
|
||||
],
|
||||
'unicorn/numeric-separators-style': [
|
||||
'error',
|
||||
{ number: { minimumDigits: 0, groupLength: 3 } },
|
||||
],
|
||||
'import/no-cycle': 'off', // Change this to "error" to find circular imports
|
||||
'@typescript-eslint/no-use-before-define': ['error'],
|
||||
'no-multiple-empty-lines': ['error', { max: 1, maxBOF: 0, maxEOF: 1 }],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.ts'],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
],
|
||||
parserOptions: {
|
||||
project: true,
|
||||
tsconfigRootDir: __dirname,
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
import type { Linter } from 'eslint';
|
||||
import eslint from '@eslint/js';
|
||||
import tseslint from 'typescript-eslint';
|
||||
|
||||
export default tseslint.config(eslint.configs.recommended, ...tseslint.configs.recommended, {
|
||||
rules: {
|
||||
'@typescript-eslint/no-redundant-type-constituents': 'off',
|
||||
'@typescript-eslint/no-unsafe-call': 'off',
|
||||
'@typescript-eslint/naming-convention': 'off',
|
||||
'@typescript-eslint/no-unsafe-assignment': 'off',
|
||||
'@typescript-eslint/no-unsafe-return': 'off',
|
||||
'@typescript-eslint/ban-types': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-empty-object-type': 'off',
|
||||
'no-use-before-define': ['off'],
|
||||
'no-multiple-empty-lines': ['error', { max: 1, maxBOF: 0, maxEOF: 1 }],
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-unused-expressions': 'off',
|
||||
},
|
||||
});
|
||||
Generated
+473
-3196
File diff suppressed because it is too large
Load Diff
+10
-11
@@ -32,8 +32,8 @@
|
||||
"codegen:watch": "DOTENV_CONFIG_PATH='./.env.staging' graphql-codegen --config codegen.yml --watch -r dotenv/config",
|
||||
"codegen:local": "NODE_TLS_REJECT_UNAUTHORIZED=0 MOTHERSHIP_GRAPHQL_LINK='https://mothership.localhost/ws' graphql-codegen-esm --config codegen.yml --watch",
|
||||
"tsc": "tsc --noEmit",
|
||||
"lint": "DEBUG=eslint:cli-engine eslint . --config .eslintrc.cjs",
|
||||
"lint:fix": "DEBUG=eslint:cli-engine eslint . --fix --config .eslintrc.cjs",
|
||||
"lint": "eslint --flag unstable_ts_config --config .eslintrc.ts src/",
|
||||
"lint:fix": "eslint --flag unstable_ts_config --fix --config .eslintrc.ts src/",
|
||||
"test:watch": "vitest --pool=forks",
|
||||
"test": "vitest run --pool=forks",
|
||||
"coverage": "vitest run --coverage",
|
||||
@@ -178,24 +178,17 @@
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@types/ws": "^8.5.10",
|
||||
"@types/wtfnode": "^0.7.3",
|
||||
"@typescript-eslint/eslint-plugin": "^7.9.0",
|
||||
"@typescript-eslint/parser": "^7.9.0",
|
||||
"@unraid/eslint-config": "github:unraid/eslint-config",
|
||||
"@vitest/coverage-v8": "^2.1.1",
|
||||
"@vitest/ui": "^2.1.1",
|
||||
"camelcase-keys": "^8.0.2",
|
||||
"cz-conventional-changelog": "3.3.0",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.1",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"eslint-plugin-unicorn": "^53.0.0",
|
||||
"eslint-plugin-unused-imports": "^3.2.0",
|
||||
"eslint": "^9.12.0",
|
||||
"execa": "^7.1.1",
|
||||
"filter-obj": "^5.1.0",
|
||||
"got": "^13",
|
||||
"graphql-codegen-typescript-validation-schema": "^0.14.1",
|
||||
"ip-regex": "^5.0.0",
|
||||
"jiti": "^2.3.3",
|
||||
"json-difference": "^1.16.1",
|
||||
"map-obj": "^5.0.2",
|
||||
"p-props": "^5.0.0",
|
||||
@@ -205,6 +198,7 @@
|
||||
"pretty-ms": "^8.0.0",
|
||||
"standard-version": "^9.5.0",
|
||||
"typescript": "^5.4.5",
|
||||
"typescript-eslint": "^8.10.0",
|
||||
"typesync": "^0.12.1",
|
||||
"vite-tsconfig-paths": "^4.3.2",
|
||||
"vitest": "^2.1.1",
|
||||
@@ -217,5 +211,10 @@
|
||||
"commitizen": {
|
||||
"path": "./node_modules/cz-conventional-changelog"
|
||||
}
|
||||
},
|
||||
"overrides": {
|
||||
"eslint": {
|
||||
"jiti": "2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import * as apiKeyValidator from '@app/mothership/api-key/validate-api-key-with-
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import { type RecursivePartial } from '@app/types/index';
|
||||
import { type RootState } from '@app/store/index';
|
||||
import { logoutUser } from '@app/store/modules/config';
|
||||
|
||||
describe('apiKeyCheckJob Tests', () => {
|
||||
it('API Check Job (with success)', async () => {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/* eslint-disable */
|
||||
process.title = 'unraid-api';
|
||||
|
||||
setInterval(() => {
|
||||
console.log('I NEED TO DIE');
|
||||
}, 5_000);
|
||||
@@ -0,0 +1,10 @@
|
||||
/* eslint-disable */
|
||||
process.title = 'unraid-api';
|
||||
setInterval(() => {
|
||||
console.log('I NEED TO DIE (but i am very hard to kill)');
|
||||
}, 5_000);
|
||||
|
||||
process.on('SIGTERM', () => {
|
||||
// Do nothing
|
||||
console.log('you cant kill me haha');
|
||||
});
|
||||
@@ -258,8 +258,7 @@ const getVerbosity = (argv: string[]): Verbosity => {
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
|
||||
export const report = async (...argv: string[]) => {
|
||||
// Check if the user has raw output enabled
|
||||
const rawOutput = argv.includes('--raw');
|
||||
|
||||
@@ -4,7 +4,7 @@ import { AppError } from '@app/core/errors/app-error';
|
||||
* API key error.
|
||||
*/
|
||||
export class ApiKeyError extends AppError {
|
||||
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
|
||||
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ export const getPermissions = async function (context: CoreContext): Promise<Cor
|
||||
const grants = Object.entries(ac.getGrants())
|
||||
.map(([name, grant]) => {
|
||||
// @ts-expect-error - $extend and grants are any
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
|
||||
const { $extend: _, ...grants } = grant;
|
||||
return [name, grants];
|
||||
})
|
||||
|
||||
@@ -78,7 +78,7 @@ export const updateDisk = async (context: Context): Promise<Result> => {
|
||||
7: '7 hours',
|
||||
8: '8 hours',
|
||||
9: '9 hours',
|
||||
/* eslint-enable @typescript-eslint/naming-convention */
|
||||
|
||||
});
|
||||
|
||||
// Defines the type of partition layout to create when formatting hard drives 2TB in size and smaller **only**. (All devices larger then 2TB are always set up with GPT partition tables.)
|
||||
@@ -89,7 +89,7 @@ export const updateDisk = async (context: Context): Promise<Result> => {
|
||||
|
||||
1: 'MBR: unaligned',
|
||||
2: 'MBR: 4K-aligned',
|
||||
/* eslint-enable @typescript-eslint/naming-convention */
|
||||
|
||||
});
|
||||
|
||||
// Selects the method to employ when writing to enabled disk in parity protected array.
|
||||
@@ -98,7 +98,7 @@ export const updateDisk = async (context: Context): Promise<Result> => {
|
||||
|
||||
0: 'read/modify/write',
|
||||
1: 'reconstruct write',
|
||||
/* eslint-enable @typescript-eslint/naming-convention */
|
||||
|
||||
});
|
||||
|
||||
// Defines the default file system type to create when an * unmountable * array device is formatted.
|
||||
@@ -111,7 +111,7 @@ export const updateDisk = async (context: Context): Promise<Result> => {
|
||||
'luks:xfs': 'xfs - encrypted',
|
||||
'luks:btrfs': 'btrfs - encrypted',
|
||||
'luks:reiserfs': 'reiserfs - encrypted',
|
||||
/* eslint-enable @typescript-eslint/naming-convention */
|
||||
|
||||
});
|
||||
|
||||
const {
|
||||
|
||||
@@ -8,8 +8,7 @@ export type Options = NotifierOptions
|
||||
*/
|
||||
export class HttpNotifier extends Notifier {
|
||||
readonly $http = got;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
|
||||
|
||||
constructor(options: Options) {
|
||||
super(options);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ type ConfigObject<T> = T extends 'flash'
|
||||
* @param mode 'flash' or 'memory', changes what fields are included in the writeable payload
|
||||
* @returns
|
||||
*/
|
||||
// eslint-disable-next-line complexity
|
||||
|
||||
export const getWriteableConfig = <T extends ConfigType>(
|
||||
config: ConfigSliceState,
|
||||
mode: T
|
||||
@@ -32,7 +32,7 @@ export const getWriteableConfig = <T extends ConfigType>(
|
||||
const { api, local, notifier, remote, upc, connectionStatus } = config;
|
||||
|
||||
// Create new state
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
|
||||
const newState: ConfigObject<T> = {
|
||||
api: {
|
||||
version: api?.version ?? initialState.api.version,
|
||||
|
||||
@@ -43,7 +43,7 @@ const fixObjectArrays = (object: Record<string, any>) => {
|
||||
|
||||
// An object without any array items
|
||||
const filteredObject = includeKeys(object, (key, value) => {
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-regexp-exec
|
||||
|
||||
const [, name, index] = [...((key).match(/(.*):(\d+$)/) ?? [])];
|
||||
if (!name || !index) {
|
||||
return true;
|
||||
|
||||
@@ -8,6 +8,6 @@ export const getPermissions = (role: string): Record<string, Record<string, stri
|
||||
const grants: Record<string, Record<string, string[]>> = ac.getGrants();
|
||||
const { $extend, ...roles } = grants[role] ?? {};
|
||||
const inheritedRoles = Array.isArray($extend) ? $extend.map(role => getPermissions(role))[0] : {};
|
||||
// eslint-disable-next-line prefer-object-spread
|
||||
|
||||
return Object.assign({}, roles, inheritedRoles);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import { getters } from '@app/store';
|
||||
import type { DiskShare, Share, UserShare } from '@app/core/types/states/share';
|
||||
import { type ArrayDisk } from '@app/graphql/generated/api/types';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable */
|
||||
import * as types from './graphql.js';
|
||||
import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable */
|
||||
import { z } from 'zod'
|
||||
import { AccessUrlInput, ArrayCapacityBytesInput, ArrayCapacityInput, ClientType, ConfigErrorState, DashboardAppsInput, DashboardArrayInput, DashboardCaseInput, DashboardConfigInput, DashboardDisplayInput, DashboardInput, DashboardOsInput, DashboardServiceInput, DashboardServiceUptimeInput, DashboardTwoFactorInput, DashboardTwoFactorLocalInput, DashboardTwoFactorRemoteInput, DashboardVarsInput, DashboardVersionsInput, DashboardVmsInput, EventType, Importance, NetworkInput, NotificationInput, NotificationStatus, PingEventSource, RegistrationState, RemoteAccessEventActionType, RemoteAccessInput, RemoteGraphQLClientInput, RemoteGraphQLEventType, RemoteGraphQLServerInput, ServerStatus, URL_TYPE, UpdateType } from '@app/graphql/generated/client/graphql'
|
||||
|
||||
|
||||
@@ -281,7 +281,7 @@ export const generateDevices = async (): Promise<Devices> => {
|
||||
const usbHubs = await execa('cat /sys/bus/usb/drivers/hub/*/modalias', { shell: true })
|
||||
.then(({ stdout }) =>
|
||||
stdout.split('\n').map((line) => {
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-regexp-exec
|
||||
|
||||
const [, id] = line.match(/usb:v(\w{9})/) ?? [];
|
||||
return id.replace('p', ':');
|
||||
})
|
||||
@@ -316,7 +316,7 @@ export const generateDevices = async (): Promise<Devices> => {
|
||||
|
||||
// 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
|
||||
|
||||
@@ -128,8 +128,7 @@ const getUrlTypeFromFqdn = (fqdnType: string): URL_TYPE => {
|
||||
return URL_TYPE.WIREGUARD;
|
||||
}
|
||||
};
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
|
||||
export const getServerIps = (
|
||||
state: RootState = store.getState()
|
||||
): { urls: AccessUrl[]; errors: Error[] } => {
|
||||
|
||||
@@ -32,8 +32,6 @@ export const getWsConnectionCount = () => Object.values(subscriptions).filter(su
|
||||
*/
|
||||
export const getWsConnectionCountInChannel = (channel: string) => Object.values(subscriptions).filter(subscription => subscription.channels.includes(channel)).length;
|
||||
|
||||
|
||||
|
||||
export const hasSubscribedToChannel = (id: string, channel: string) => {
|
||||
|
||||
graphqlLogger.debug('Subscribing to %s', channel);
|
||||
@@ -51,7 +49,6 @@ export const hasSubscribedToChannel = (id: string, channel: string) => {
|
||||
subscriptions[id].channels.push(channel);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create a pubsub subscription.
|
||||
* @param channel The pubsub channel to subscribe to.
|
||||
@@ -74,8 +71,7 @@ export const createSubscription = (channel: string, resource?: string) => ({
|
||||
return pubsub.asyncIterator(channel);
|
||||
},
|
||||
});
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export const getLocalServer = (getState = store.getState): Array<Server> => {
|
||||
const { emhttp, config, minigraph } = getState();
|
||||
const guid = emhttp.var.regGuid;
|
||||
|
||||
@@ -56,12 +56,11 @@ export const isAPIStateDataFullyLoaded = (state = store.getState()) => {
|
||||
Boolean(emhttp.var.version)
|
||||
);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
||||
|
||||
export class GraphQLClient {
|
||||
public static instance: ApolloClient<NormalizedCacheObject> | null = null;
|
||||
public static client: Client | null = null;
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
|
||||
private constructor() {}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable max-depth */
|
||||
import { minigraphLogger, mothershipLogger } from '@app/core/log';
|
||||
import { GraphQLClient } from './graphql-client';
|
||||
import { store } from '@app/store';
|
||||
|
||||
@@ -11,12 +11,12 @@ export function buildDelayFunction(
|
||||
const baseDelay = jitter ? initial : initial / 2;
|
||||
|
||||
return (count: number) => {
|
||||
// eslint-disable-next-line no-mixed-operators
|
||||
|
||||
let delay = Math.min(max, baseDelay * 2 ** count);
|
||||
if (jitter) {
|
||||
// We opt for a full jitter approach for a mostly uniform distribution,
|
||||
// but bound it within initialDelay and delay for everyone's sanity.
|
||||
// eslint-disable-next-line operator-assignment
|
||||
|
||||
delay = Math.random() * delay;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,7 @@ export class RemoteAccessController implements IRemoteAccessController {
|
||||
static _instance: RemoteAccessController | null = null;
|
||||
activeRemoteAccess: UpnpRemoteAccess | StaticRemoteAccess | null = null;
|
||||
notifier: UnraidLocalNotifier = new UnraidLocalNotifier({ level: 'info' });
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-useless-constructor, @typescript-eslint/no-empty-function
|
||||
|
||||
constructor() {}
|
||||
|
||||
public static get instance(): RemoteAccessController {
|
||||
|
||||
@@ -114,7 +114,7 @@ describe.sequential('NotificationsService', () => {
|
||||
}
|
||||
|
||||
// currently unused b/c of difficulty implementing NotificationOverview tests
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
|
||||
async function forAllTypesAndImportances(
|
||||
action: (type: NotificationType, importance: Importance) => Promise<void>
|
||||
) {
|
||||
@@ -134,7 +134,7 @@ describe.sequential('NotificationsService', () => {
|
||||
}
|
||||
|
||||
// currently unused b/c of difficulty implementing NotificationOverview tests
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
|
||||
function diffOverview(current: NotificationOverview, previous: NotificationOverview) {
|
||||
return Object.fromEntries(
|
||||
Object.entries(current).map(([key]) => {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Cron, Expression, Initializer } from '@reflet/cron';
|
||||
import { store } from '@app/store';
|
||||
import { enableUpnp } from '@app/store/modules/upnp';
|
||||
import { upnpLogger } from '@app/core/log';
|
||||
|
||||
export class UPNPJobManager extends Initializer<typeof UPNPJobManager> {
|
||||
@Cron.PreventOverlap
|
||||
@Cron(Expression.EVERY_30_MINUTES)
|
||||
async renewUpnpLeaseJob() {
|
||||
upnpLogger.trace('Running UPNP Renewal Job');
|
||||
await store.dispatch(enableUpnp());
|
||||
}
|
||||
}
|
||||
|
||||
export const initUpnpJobs = (): boolean => {
|
||||
if (!upnpJobs) {
|
||||
upnpJobs = UPNPJobManager.init();
|
||||
}
|
||||
|
||||
upnpJobs.get('renewUpnpLeaseJob').start();
|
||||
return upnpJobs.get('renewUpnpLeaseJob').running ?? false;
|
||||
};
|
||||
|
||||
export const stopUpnpJobs = (): boolean => {
|
||||
upnpLogger.debug('Stopping UPNP Jobs');
|
||||
upnpJobs?.get('renewUpnpLeaseJob').stop();
|
||||
return upnpJobs?.get('renewUpnpLeaseJob').running ?? false;
|
||||
};
|
||||
|
||||
let upnpJobs: ReturnType<typeof UPNPJobManager.init<UPNPJobManager>> | null = null;
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"include": [
|
||||
"src/**/*",
|
||||
".eslintrc.cjs",
|
||||
".eslintrc.ts",
|
||||
"vite.config.ts"
|
||||
],
|
||||
"exclude": [
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
import { execSync } from 'child_process';
|
||||
import 'dotenv/config';
|
||||
import { defineConfig } from 'tsup';
|
||||
import { version } from './package.json';
|
||||
import getTags from './scripts/get-tags.mjs'
|
||||
|
||||
|
||||
|
||||
export default defineConfig({
|
||||
name: 'tsup',
|
||||
target: 'node18',
|
||||
entry: {
|
||||
'unraid-api': 'src/cli.ts',
|
||||
index: 'src/index.ts',
|
||||
},
|
||||
metafile: true,
|
||||
splitting: false,
|
||||
sourcemap: true,
|
||||
clean: true,
|
||||
external: ['@vmngr/libvirt'],
|
||||
esbuildOptions(options) {
|
||||
if (!options.define) options.define = {};
|
||||
|
||||
const tags = getTags(process.env);
|
||||
|
||||
options.define['process.env.VERSION'] = tags.isTagged
|
||||
? `"${version}"`
|
||||
: `"${version}+${tags.shortSha}"`;
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user