Merge pull request #15143 from Budibase/eslint-strict-1

Enable a variety of useful looking lints.
This commit is contained in:
Sam Rose 2024-12-09 21:33:16 +00:00 committed by GitHub
commit 40d7324328
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
56 changed files with 121 additions and 200 deletions

View File

@ -51,8 +51,23 @@ export default [
},
rules: {
"no-self-assign": "off",
"prefer-const": "off",
"no-self-compare": "error",
"no-template-curly-in-string": "error",
"no-unmodified-loop-condition": "error",
"no-unreachable-loop": "error",
"no-implied-eval": "error",
"no-extend-native": "error",
"no-labels": "error",
"no-lone-blocks": "error",
"no-new-wrappers": "error",
"no-octal-escape": "error",
"no-return-assign": "error",
"no-useless-concat": "error",
"no-useless-constructor": "error",
"no-useless-rename": "error",
"no-var": "error",
"no-void": "error",
"no-unused-vars": [
"error",
{
@ -65,64 +80,69 @@ export default [
],
},
},
...eslintPluginSvelte.configs["flat/recommended"].map(config => {
return {
...config,
files: ["**/*.svelte"],
...eslintPluginSvelte.configs["flat/recommended"].map(config => ({
...config,
files: ["**/*.svelte"],
languageOptions: {
parser: svelteParser,
ecmaVersion: 2019,
sourceType: "script",
languageOptions: {
parser: svelteParser,
ecmaVersion: 2019,
sourceType: "script",
parserOptions: {
parser: "@typescript-eslint/parser",
allowImportExportEverywhere: true,
parserOptions: {
parser: "@typescript-eslint/parser",
allowImportExportEverywhere: true,
},
},
})),
...tseslint.configs.strict.map(config => ({
...config,
files: ["**/*.ts"],
languageOptions: {
globals: {
NodeJS: true,
},
parser: tsParser,
},
rules: {
"local-rules/no-barrel-imports": "error",
"local-rules/no-budibase-imports": "error",
"local-rules/no-console-error": "error",
"@typescript-eslint/no-inferrable-types": "error",
"@typescript-eslint/adjacent-overload-signatures": "error",
"@typescript-eslint/class-literal-property-style": "error",
"@typescript-eslint/no-confusing-non-null-assertion": "error",
"@typescript-eslint/no-unnecessary-parameter-property-assignment":
"error",
"@typescript-eslint/no-useless-empty-export": "error",
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{
varsIgnorePattern: "^_",
argsIgnorePattern: "^_",
destructuredArrayIgnorePattern: "^_",
ignoreRestSiblings: true,
caughtErrors: "none",
},
},
}
}),
...tseslint.configs.recommended.map(config => {
return {
...config,
files: ["**/*.ts"],
],
languageOptions: {
globals: {
NodeJS: true,
},
"no-redeclare": "off",
"@typescript-eslint/no-redeclare": "error",
parser: tsParser,
},
// @typescript-eslint/no-dupe-class-members supersedes no-dupe-class-members
"no-dupe-class-members": "off",
"@typescript-eslint/no-dupe-class-members": "error",
rules: {
"local-rules/no-barrel-imports": "error",
"local-rules/no-budibase-imports": "error",
"local-rules/no-console-error": "error",
// @typscript-eslint/no-unused-vars supersedes no-unused-vars
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{
varsIgnorePattern: "^_",
argsIgnorePattern: "^_",
destructuredArrayIgnorePattern: "^_",
ignoreRestSiblings: true,
caughtErrors: "none",
},
],
// @typescript-eslint/no-redeclare supersedes no-redeclare
"no-redeclare": "off",
"@typescript-eslint/no-redeclare": "error",
// @typescript-eslint/no-dupe-class-members supersedes no-dupe-class-members
"no-dupe-class-members": "off",
"@typescript-eslint/no-dupe-class-members": "error",
},
}
}),
"no-useless-constructor": "off",
"@typescript-eslint/no-useless-constructor": "error",
},
})),
{
files: ["**/*.spec.ts", "**/*.spec.js"],

View File

@ -289,7 +289,7 @@ export class DatabaseImpl implements Database {
return
}
let errorFound = false
let errorMessage: string = "Unable to bulk remove documents: "
let errorMessage = "Unable to bulk remove documents: "
for (let res of response) {
if (res.error) {
errorFound = true

View File

@ -4,7 +4,7 @@ import { checkSlashesInUrl } from "../../helpers"
export async function directCouchCall(
path: string,
method: string = "GET",
method = "GET",
body?: any
) {
let { url, cookie } = getCouchInfo()
@ -43,7 +43,7 @@ export async function directCouchUrlCall({
export async function directCouchQuery(
path: string,
method: string = "GET",
method = "GET",
body?: any
) {
const response = await directCouchCall(path, method, body)

View File

@ -279,7 +279,7 @@ export class QueryBuilder<T> {
let query = allOr ? "" : "*:*"
let allFiltersEmpty = true
const allPreProcessingOpts = { escape: true, lowercase: true, wrap: true }
let tableId: string = ""
let tableId = ""
if (this.#query.equal!.tableId) {
tableId = this.#query.equal!.tableId
delete this.#query.equal!.tableId

View File

@ -2,7 +2,7 @@ import { Event, Identity, Group } from "@budibase/types"
import { EventProcessor } from "./types"
export default class Processor implements EventProcessor {
initialised: boolean = false
initialised = false
processors: EventProcessor[] = []
constructor(processors: EventProcessor[]) {

View File

@ -137,9 +137,9 @@ export default function (
}
const tenantId = getHeader(ctx, Header.TENANT_ID)
let authenticated: boolean = false,
let authenticated = false,
user: User | { tenantId: string } | undefined = undefined,
internal: boolean = false,
internal = false,
loginMethod: LoginMethod | undefined = undefined
if (authCookie && !apiKey) {
const sessionId = authCookie.sessionId

View File

@ -20,7 +20,7 @@ export const ssoSaveUserNoOp: SaveSSOUserFunction = (user: SSOUser) =>
*/
export async function authenticate(
details: SSOAuthDetails,
requireLocalAccount: boolean = true,
requireLocalAccount = true,
done: any,
saveUserFn: SaveSSOUserFunction
) {

View File

@ -334,7 +334,7 @@ export async function listAllObjects(bucketName: string, path: string) {
export function getPresignedUrl(
bucketName: string,
key: string,
durationSeconds: number = 3600
durationSeconds = 3600
) {
const objectStore = ObjectStore(bucketName, { presigning: true })
const params = {

View File

@ -92,7 +92,7 @@ function getLockName(opts: LockOptions) {
// determine lock name
// by default use the tenantId for uniqueness, unless using a system lock
const prefix = opts.systemLock ? "system" : context.getTenantId()
let name: string = `lock:${prefix}_${opts.name}`
let name = `lock:${prefix}_${opts.name}`
// add additional unique name if required
if (opts.resource) {
name = name + `_${opts.resource}`

View File

@ -1,6 +1,6 @@
import { MonthlyQuotaName, QuotaUsage } from "@budibase/types"
export const usage = (users: number = 0, creators: number = 0): QuotaUsage => {
export const usage = (users = 0, creators = 0): QuotaUsage => {
return {
_id: "usage_quota",
quotaReset: new Date().toISOString(),

View File

@ -85,7 +85,7 @@
}
const getPos = e => {
var rect = canvasRef.getBoundingClientRect()
let rect = canvasRef.getBoundingClientRect()
const canvasX = e.offsetX || e.targetTouches?.[0].pageX - rect.left
const canvasY = e.offsetY || e.targetTouches?.[0].pageY - rect.top

View File

@ -24,9 +24,9 @@
const j = 32 // Outer radius strength (higher is stronger)
// Calculate unit vector
var dx = x1 - x2
var dy = y1 - y2
var len = Math.sqrt(dx * dx + dy * dy)
let dx = x1 - x2
let dy = y1 - y2
let len = Math.sqrt(dx * dx + dy * dy)
dx = dx / len
dy = dy / len

View File

@ -30,7 +30,7 @@ const FullScreenControl = L.Control.extend({
fullScreenTitle: "Enter Fullscreen",
},
onAdd: function () {
var fullScreenClassName = "leaflet-control-fullscreen",
let fullScreenClassName = "leaflet-control-fullscreen",
container = L.DomUtil.create("div", fullScreenClassName + " leaflet-bar"),
options = this.options
@ -45,7 +45,7 @@ const FullScreenControl = L.Control.extend({
return container
},
_fullScreen: function () {
var map = this._map
let map = this._map
if (screenfull.isEnabled) {
screenfull.toggle(map.getContainer())
}
@ -80,7 +80,7 @@ const LocationControl = L.Control.extend({
locationTitle: "Show Your Location",
},
onAdd: function () {
var locationClassName = "leaflet-control-location",
let locationClassName = "leaflet-control-location",
container = L.DomUtil.create("div", locationClassName + " leaflet-bar"),
options = this.options
@ -136,7 +136,7 @@ const LocationControl = L.Control.extend({
})
},
_getPosition: function () {
var options = {
let options = {
enableHighAccuracy: false,
timeout: 5000,
maximumAge: 30000,

View File

@ -1,3 +1,4 @@
/* eslint-disable no-useless-concat */
import { derived } from "svelte/store"
import { appStore } from "./app"
import { builderStore } from "./builder"

View File

@ -22,7 +22,7 @@ import {
async function redirect(
ctx: any,
method: "GET" | "POST" | "DELETE",
path: string = "global"
path = "global"
) {
const { devPath } = ctx.params
const queryString = ctx.originalUrl.split("?")[1] || ""

View File

@ -378,7 +378,7 @@ export class ExternalRequest<T extends Operation> {
}
// many to one
else {
const thisKey: string = "id"
const thisKey = "id"
// @ts-ignore
const otherKey: string = field.fieldName
for (const relationship of row[key]) {

View File

@ -45,7 +45,7 @@ export function getInternalRowId(row: Row, table: Table): string {
export function generateIdForRow(
row: Row | undefined,
table: Table,
isLinked: boolean = false
isLinked = false
): string {
const primary = table.primary
if (!row || !primary) {

View File

@ -16,7 +16,7 @@ function escapeCsvString(str: string) {
export function csv(
headers: string[],
rows: Row[],
delimiter: string = ",",
delimiter = ",",
customHeaders: { [key: string]: string } = {}
) {
let csvRows = [getHeaders(headers, customHeaders)]

View File

@ -2133,7 +2133,7 @@ if (descriptions.length) {
// repeat the search many times to check the first row is always the same
let bookmark: string | number | undefined,
hasNextPage: boolean | undefined = true,
rowCount: number = 0
rowCount = 0
do {
const response = await config.api.row.search(
tableOrViewId,

View File

@ -263,7 +263,7 @@ class AutomationBuilder extends BaseStepBuilder {
private automationConfig: Automation
private config: TestConfiguration
private triggerOutputs: any
private triggerSet: boolean = false
private triggerSet = false
constructor(
options: { name?: string; appId?: string; config?: TestConfiguration } = {}

View File

@ -223,7 +223,7 @@ const COLUMN_DEFINITION_METADATA: Record<string, ColumnDefinitionMetadata> = {
class SqlServerIntegration extends Sql implements DatasourcePlus {
private readonly config: MSSQLConfig
private index: number = 0
private index = 0
private client?: sqlServer.ConnectionPool
MASTER_TABLES = [

View File

@ -116,7 +116,7 @@ const OracleContraintTypes = {
class OracleIntegration extends Sql implements DatasourcePlus {
private readonly config: OracleConfig
private index: number = 1
private index = 1
private static readonly COLUMNS_SQL = `
SELECT

View File

@ -149,7 +149,7 @@ const SCHEMA: Integration = {
class PostgresIntegration extends Sql implements DatasourcePlus {
private readonly client: Client
private readonly config: PostgresConfig
private index: number = 1
private index = 1
private open: boolean
PRIMARY_KEYS_SQL = () => `
@ -252,7 +252,7 @@ class PostgresIntegration extends Sql implements DatasourcePlus {
})
}
async internalQuery(query: SqlQuery, close: boolean = true) {
async internalQuery(query: SqlQuery, close = true) {
if (!this.open) {
await this.openConnection()
}

View File

@ -171,7 +171,7 @@ export class RestIntegration implements IntegrationBase {
path.basename(parse(contentDisposition).parameters?.filename) || ""
}
let triedParsing: boolean = false,
let triedParsing = false,
responseTxt: string | undefined
try {
if (filename) {

View File

@ -245,7 +245,7 @@ describe("Captures of real examples", () => {
tableNames.push(generator.guid())
}
const aliasing = new AliasTables(tableNames)
let alias: string = ""
let alias = ""
for (let table of tableNames) {
alias = aliasing.getAlias(table)
}

View File

@ -59,9 +59,7 @@ async function updateAppUpdatedAt(ctx: UserCtx) {
await setDebounce(appId, DEBOUNCE_TIME_SEC)
} catch (err: any) {
// if a 409 occurs, then multiple clients connected at the same time - ignore
if (err?.status === 409) {
return
} else {
if (err && err.status !== 409) {
throw err
}
}

View File

@ -104,8 +104,6 @@ export async function getDependantResources(
return p
}, {} as Record<string, number>)
}
return
}
export async function updatePermissionOnRole(

View File

@ -437,7 +437,7 @@ export async function search(
)
// check for pagination final row
let nextRow: boolean = false
let nextRow = false
if (paginate && params.limit && rows.length > params.limit) {
// remove the extra row that confirmed if there is another row to move to
nextRow = true

View File

@ -535,7 +535,7 @@ export function basicRow(tableId: string) {
export function basicLinkedRow(
tableId: string,
linkedRowId: string,
linkField: string = "link"
linkField = "link"
) {
// this is based on the basic linked tables you get from the test configuration
return {
@ -586,14 +586,14 @@ export function basicUser(role: string) {
}
}
export function basicScreen(route: string = "/") {
export function basicScreen(route = "/") {
return createHomeScreen({
roleId: BUILTIN_ROLE_IDS.BASIC,
route,
})
}
export function powerScreen(route: string = "/") {
export function powerScreen(route = "/") {
return createHomeScreen({
roleId: BUILTIN_ROLE_IDS.POWER,
route,

View File

@ -1,6 +1,6 @@
export async function retry<T extends (...arg0: any[]) => any>(
fn: T,
maxTry: number = 5,
maxTry = 5,
retryCount = 1
): Promise<Awaited<ReturnType<T>>> {
const currRetry = typeof retryCount === "number" ? retryCount : 1

View File

@ -33,7 +33,7 @@ export class BaseSocket {
constructor(
app: Koa,
server: http.Server,
path: string = "/",
path = "/",
additionalMiddlewares?: any[]
) {
this.app = app

View File

@ -33,7 +33,7 @@ function improveErrors(errors: string[]): string[] {
export function getNextExecutionDates(
cronExpression: string,
limit: number = 4
limit = 4
): string[] {
const parsed = cronParser.parseExpression(cronExpression)
const nextRuns = []

View File

@ -1,3 +1,4 @@
/* eslint-disable no-template-curly-in-string */
import { convertToJS } from "../src/index"
function checkLines(response: string, lines: string[]) {

View File

@ -11,7 +11,7 @@ function tryParseJson(str: string) {
try {
return JSON.parse(str.replace(/'/g, '"'))
} catch (e) {
return
// do nothing
}
}

View File

@ -128,13 +128,13 @@ export interface Database {
name: string
exists(): Promise<boolean>
exists(docId: string): Promise<boolean>
/**
* @deprecated the plan is to get everything using `tryGet` instead, then rename
* `tryGet` to `get`.
*/
get<T extends Document>(id?: string): Promise<T>
tryGet<T extends Document>(id?: string): Promise<T | undefined>
exists(docId: string): Promise<boolean>
getMultiple<T extends Document>(
ids: string[],
opts?: { allowMissing?: boolean; excludeDocs?: boolean }

View File

@ -40,10 +40,7 @@ export const getMetadata = async (
try {
return await db.get(accountId)
} catch (e: any) {
if (e.status === 404) {
// do nothing
return
} else {
if (e.status !== 404) {
throw e
}
}

View File

@ -1,12 +1,7 @@
import { Account, AccountMetadata } from "@budibase/types"
import TestConfiguration from "../TestConfiguration"
import { TestAPI } from "./base"
export class AccountAPI extends TestAPI {
constructor(config: TestConfiguration) {
super(config)
}
saveMetadata = async (account: Account) => {
const res = await this.request
.put(`/api/system/accounts/${account.accountId}/metadata`)

View File

@ -1,12 +1,7 @@
import { AuditLogSearchParams, SearchAuditLogsResponse } from "@budibase/types"
import TestConfiguration from "../TestConfiguration"
import { TestAPI } from "./base"
export class AuditLogAPI extends TestAPI {
constructor(config: TestConfiguration) {
super(config)
}
search = async (search: AuditLogSearchParams) => {
const res = await this.request
.post("/api/global/auditlogs/search")

View File

@ -1,11 +1,6 @@
import TestConfiguration from "../TestConfiguration"
import { TestAPI, TestAPIOpts } from "./base"
export class AuthAPI extends TestAPI {
constructor(config: TestConfiguration) {
super(config)
}
updatePassword = (
resetCode: string,
password: string,

View File

@ -10,7 +10,7 @@ export abstract class TestAPI {
config: TestConfiguration
request: SuperTest<Test>
protected constructor(config: TestConfiguration) {
constructor(config: TestConfiguration) {
this.config = config
this.request = config.request
}

View File

@ -1,11 +1,6 @@
import TestConfiguration from "../TestConfiguration"
import { TestAPI } from "./base"
export class ConfigAPI extends TestAPI {
constructor(config: TestConfiguration) {
super(config)
}
getConfigChecklist = () => {
return this.request
.get(`/api/global/configs/checklist`)

View File

@ -1,12 +1,7 @@
import { EmailAttachment } from "@budibase/types"
import TestConfiguration from "../TestConfiguration"
import { TestAPI } from "./base"
export class EmailAPI extends TestAPI {
constructor(config: TestConfiguration) {
super(config)
}
sendEmail = (purpose: string, attachments?: EmailAttachment[]) => {
return this.request
.post(`/api/global/email/send`)

View File

@ -1,11 +1,6 @@
import TestConfiguration from "../TestConfiguration"
import { TestAPI } from "./base"
export class EnvironmentAPI extends TestAPI {
constructor(config: TestConfiguration) {
super(config)
}
getEnvironment = () => {
return this.request
.get(`/api/system/environment`)

View File

@ -1,12 +1,7 @@
import { UserGroup } from "@budibase/types"
import TestConfiguration from "../TestConfiguration"
import { TestAPI } from "./base"
export class GroupsAPI extends TestAPI {
constructor(config: TestConfiguration) {
super(config)
}
saveGroup = (
group: UserGroup,
{ expect }: { expect: number | object } = { expect: 200 }

View File

@ -1,4 +1,3 @@
import TestConfiguration from "../TestConfiguration"
import { TestAPI } from "./base"
import {
ActivateLicenseKeyRequest,
@ -6,10 +5,6 @@ import {
} from "@budibase/types"
export class LicenseAPI extends TestAPI {
constructor(config: TestConfiguration) {
super(config)
}
refresh = async () => {
return this.request
.post("/api/global/license/refresh")

View File

@ -1,11 +1,6 @@
import TestConfiguration from "../TestConfiguration"
import { TestAPI, TestAPIOpts } from "./base"
export class MigrationAPI extends TestAPI {
constructor(config: TestConfiguration) {
super(config)
}
runMigrations = (opts?: TestAPIOpts) => {
return this.request
.post(`/api/system/migrations/run`)

View File

@ -1,11 +1,6 @@
import TestConfiguration from "../TestConfiguration"
import { TestAPI, TestAPIOpts } from "./base"
export class RestoreAPI extends TestAPI {
constructor(config: TestConfiguration) {
super(config)
}
restored = (opts?: TestAPIOpts) => {
return this.request
.post(`/api/system/restored`)

View File

@ -1,11 +1,6 @@
import TestConfiguration from "../TestConfiguration"
import { TestAPI, TestAPIOpts } from "./base"
export class RolesAPI extends TestAPI {
constructor(config: TestConfiguration) {
super(config)
}
get = (opts?: TestAPIOpts) => {
return this.request
.get(`/api/global/roles`)

View File

@ -4,14 +4,9 @@ import {
ScimGroupResponse,
ScimUpdateRequest,
} from "@budibase/types"
import TestConfiguration from "../../TestConfiguration"
import { RequestSettings, ScimTestAPI } from "./shared"
export class ScimGroupsAPI extends ScimTestAPI {
constructor(config: TestConfiguration) {
super(config)
}
get = async (
requestSettings?: Partial<RequestSettings> & {
params?: {

View File

@ -1,4 +1,3 @@
import TestConfiguration from "../../TestConfiguration"
import { TestAPI } from "../base"
const defaultConfig: RequestSettings = {
@ -14,10 +13,6 @@ export type RequestSettings = {
}
export abstract class ScimTestAPI extends TestAPI {
constructor(config: TestConfiguration) {
super(config)
}
call = (
url: string,
method: "get" | "post" | "patch" | "delete",

View File

@ -4,14 +4,9 @@ import {
ScimUserResponse,
ScimUpdateRequest,
} from "@budibase/types"
import TestConfiguration from "../../TestConfiguration"
import { RequestSettings, ScimTestAPI } from "./shared"
export class ScimUsersAPI extends ScimTestAPI {
constructor(config: TestConfiguration) {
super(config)
}
get = async (
requestSettings?: Partial<RequestSettings> & {
params?: {

View File

@ -1,12 +1,7 @@
import TestConfiguration from "../TestConfiguration"
import { User } from "@budibase/types"
import { TestAPI } from "./base"
export class SelfAPI extends TestAPI {
constructor(config: TestConfiguration) {
super(config)
}
updateSelf = (user: User, update: any) => {
return this.request
.post(`/api/global/self`)

View File

@ -1,11 +1,6 @@
import TestConfiguration from "../TestConfiguration"
import { TestAPI } from "./base"
export class StatusAPI extends TestAPI {
constructor(config: TestConfiguration) {
super(config)
}
getStatus = () => {
return this.request.get(`/api/system/status`).expect(200)
}

View File

@ -1,11 +1,6 @@
import TestConfiguration from "../TestConfiguration"
import { TestAPI, TestAPIOpts } from "./base"
export class TemplatesAPI extends TestAPI {
constructor(config: TestConfiguration) {
super(config)
}
definitions = (opts?: TestAPIOpts) => {
return this.request
.get(`/api/global/template/definitions`)

View File

@ -9,14 +9,9 @@ import {
} from "@budibase/types"
import structures from "../structures"
import { generator } from "@budibase/backend-core/tests"
import TestConfiguration from "../TestConfiguration"
import { TestAPI, TestAPIOpts } from "./base"
export class UserAPI extends TestAPI {
constructor(config: TestConfiguration) {
super(config)
}
// INVITE
sendUserInvite = async (sendMailMock: any, email: string, status = 200) => {
@ -178,11 +173,7 @@ export class UserAPI extends TestAPI {
.expect(opts?.status ? opts.status : 200)
}
grantBuilderToApp = (
userId: string,
appId: string,
statusCode: number = 200
) => {
grantBuilderToApp = (userId: string, appId: string, statusCode = 200) => {
return this.request
.post(`/api/global/users/${userId}/app/${appId}/builder`)
.set(this.config.defaultHeaders())

View File

@ -42,7 +42,7 @@ const svelteCompilePlugin = {
},
}
var { argv } = require("yargs")
let { argv } = require("yargs")
async function runBuild(entry, outfile) {
const isDev = process.env.NODE_ENV !== "production"