From 9ef6cbd566a817a541590fb73534d6b902898103 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Tue, 3 Dec 2024 16:39:53 +0000 Subject: [PATCH 01/22] basic 3.0 metrics --- .../backend-core/src/events/publishers/index.ts | 1 + .../backend-core/src/events/publishers/rowAction.ts | 13 +++++++++++++ packages/backend-core/src/events/publishers/view.ts | 7 ++++--- .../server/src/api/controllers/rowAction/crud.ts | 3 +++ packages/server/src/api/controllers/view/viewsV2.ts | 4 ++++ packages/types/src/sdk/events/index.ts | 1 + packages/types/src/sdk/events/rowAction.ts | 6 ++++++ packages/types/src/sdk/events/view.ts | 7 +++++-- 8 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 packages/backend-core/src/events/publishers/rowAction.ts create mode 100644 packages/types/src/sdk/events/rowAction.ts diff --git a/packages/backend-core/src/events/publishers/index.ts b/packages/backend-core/src/events/publishers/index.ts index 9c92b80499..aaec62f979 100644 --- a/packages/backend-core/src/events/publishers/index.ts +++ b/packages/backend-core/src/events/publishers/index.ts @@ -23,3 +23,4 @@ export { default as plugin } from "./plugin" export { default as backup } from "./backup" export { default as environmentVariable } from "./environmentVariable" export { default as auditLog } from "./auditLog" +export { default as rowAction } from "./rowAction" diff --git a/packages/backend-core/src/events/publishers/rowAction.ts b/packages/backend-core/src/events/publishers/rowAction.ts new file mode 100644 index 0000000000..5adfd22d2d --- /dev/null +++ b/packages/backend-core/src/events/publishers/rowAction.ts @@ -0,0 +1,13 @@ +import { publishEvent } from "../events" +import { Event, RowActionCreatedEvent } from "@budibase/types" + +async function created( + rowAction: RowActionCreatedEvent, + timestamp?: string | number +) { + await publishEvent(Event.TABLE_CREATED, rowAction, timestamp) +} + +export default { + created, +} diff --git a/packages/backend-core/src/events/publishers/view.ts b/packages/backend-core/src/events/publishers/view.ts index ccbf960b04..0ec8f67485 100644 --- a/packages/backend-core/src/events/publishers/view.ts +++ b/packages/backend-core/src/events/publishers/view.ts @@ -11,7 +11,7 @@ import { ViewFilterDeletedEvent, ViewFilterUpdatedEvent, ViewUpdatedEvent, - View, + ViewV2, ViewCalculation, Table, TableExportFormat, @@ -19,9 +19,10 @@ import { /* eslint-disable */ -async function created(view: View, timestamp?: string | number) { +async function created(view: Partial, timestamp?: string | number) { const properties: ViewCreatedEvent = { - tableId: view.tableId, + name: view.name, + type: view.type, } await publishEvent(Event.VIEW_CREATED, properties, timestamp) } diff --git a/packages/server/src/api/controllers/rowAction/crud.ts b/packages/server/src/api/controllers/rowAction/crud.ts index 3baaff6fcc..525fcabcfc 100644 --- a/packages/server/src/api/controllers/rowAction/crud.ts +++ b/packages/server/src/api/controllers/rowAction/crud.ts @@ -6,6 +6,7 @@ import { RowActionResponse, RowActionsResponse, } from "@budibase/types" +import { events } from "@budibase/backend-core" import sdk from "../../../sdk" async function getTable(ctx: Ctx) { @@ -59,6 +60,8 @@ export async function create( name: ctx.request.body.name, }) + await events.rowAction.created(createdAction) + ctx.body = { tableId, id: createdAction.id, diff --git a/packages/server/src/api/controllers/view/viewsV2.ts b/packages/server/src/api/controllers/view/viewsV2.ts index 986764a697..46c44ed577 100644 --- a/packages/server/src/api/controllers/view/viewsV2.ts +++ b/packages/server/src/api/controllers/view/viewsV2.ts @@ -16,6 +16,7 @@ import { CountDistinctCalculationFieldMetadata, CountCalculationFieldMetadata, } from "@budibase/types" +import { events } from "@budibase/backend-core" import { builderSocket, gridSocket } from "../../../websockets" import { helpers } from "@budibase/shared-core" @@ -149,6 +150,9 @@ export async function create(ctx: Ctx) { primaryDisplay: view.primaryDisplay, } const result = await sdk.views.create(tableId, parsedView) + + await events.view.created(view) + ctx.status = 201 ctx.body = { data: result, diff --git a/packages/types/src/sdk/events/index.ts b/packages/types/src/sdk/events/index.ts index 043e62faa4..7a067fd202 100644 --- a/packages/types/src/sdk/events/index.ts +++ b/packages/types/src/sdk/events/index.ts @@ -24,3 +24,4 @@ export * from "./plugin" export * from "./backup" export * from "./environmentVariable" export * from "./auditLog" +export * from "./rowAction" diff --git a/packages/types/src/sdk/events/rowAction.ts b/packages/types/src/sdk/events/rowAction.ts new file mode 100644 index 0000000000..924f11cf76 --- /dev/null +++ b/packages/types/src/sdk/events/rowAction.ts @@ -0,0 +1,6 @@ +import { BaseEvent } from "./event" + +export interface RowActionCreatedEvent extends BaseEvent { + name: string + automationId: string +} diff --git a/packages/types/src/sdk/events/view.ts b/packages/types/src/sdk/events/view.ts index 452094d2f4..84fcb0facc 100644 --- a/packages/types/src/sdk/events/view.ts +++ b/packages/types/src/sdk/events/view.ts @@ -1,8 +1,11 @@ -import { ViewCalculation } from "../../documents" +import { ViewCalculation, ViewV2Schema, ViewV2Type } from "../../documents" import { BaseEvent, TableExportFormat } from "./event" +import { LegacyFilter, SortOrder, SortType, UISearchFilter } from "../../api" +import { SearchFilters } from "../search" export interface ViewCreatedEvent extends BaseEvent { - tableId: string + name: string + type?: ViewV2Type } export interface ViewUpdatedEvent extends BaseEvent { From 8f20b3853b177713a262834ad01042a314290399 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Thu, 5 Dec 2024 16:39:25 +0000 Subject: [PATCH 02/22] wip --- .eslintignore | 13 - .eslintrc.json | 129 ---------- eslint.config.mjs | 212 ++++++++++++++++ package.json | 20 +- yarn.lock | 634 +++++++++++++++++++++++++++++++--------------- 5 files changed, 649 insertions(+), 359 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc.json create mode 100644 eslint.config.mjs diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 2bc00912d2..0000000000 --- a/.eslintignore +++ /dev/null @@ -1,13 +0,0 @@ -node_modules -public -dist -packages/server/builder -packages/server/coverage -packages/worker/coverage -packages/backend-core/coverage -packages/server/client -packages/server/coverage -packages/builder/.routify -packages/sdk/sdk -**/*.ivm.bundle.js -packages/server/build/oldClientVersions/**/** diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 4e6a169dae..0000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "root": true, - "env": { - "browser": true, - "es6": true, - "jest": true, - "node": true - }, - "parser": "@babel/eslint-parser", - "parserOptions": { - "ecmaVersion": 2019, - "sourceType": "module", - "allowImportExportEverywhere": true - }, - "ignorePatterns": [ - "node_modules", - "dist", - "public", - "*.spec.js", - "bundle.js" - ], - "extends": ["eslint:recommended"], - "plugins": ["import", "eslint-plugin-local-rules"], - "overrides": [ - { - "files": ["**/*.svelte"], - "extends": "plugin:svelte/recommended", - "parser": "svelte-eslint-parser", - "parserOptions": { - "parser": "@typescript-eslint/parser", - "ecmaVersion": 2019, - "allowImportExportEverywhere": true - } - }, - { - "files": ["**/*.ts"], - "parser": "@typescript-eslint/parser", - "plugins": ["@typescript-eslint"], - "extends": ["eslint:recommended"], - "globals": { - "NodeJS": true - }, - "rules": { - "no-unused-vars": "off", - "local-rules/no-barrel-imports": "error", - "local-rules/no-budibase-imports": "error", - "local-rules/no-console-error": "error", - "@typescript-eslint/no-unused-vars": [ - "error", - { - "varsIgnorePattern": "^_", - "argsIgnorePattern": "^_", - "destructuredArrayIgnorePattern": "^_", - "ignoreRestSiblings": true - } - ], - "no-redeclare": "off", - "@typescript-eslint/no-redeclare": "error", - // have to turn this off to allow function overloading in typescript - "no-dupe-class-members": "off" - } - }, - { - "files": ["**/*.spec.ts"], - "parser": "@typescript-eslint/parser", - "plugins": ["jest", "@typescript-eslint"], - "extends": ["eslint:recommended", "plugin:jest/recommended"], - "env": { - "jest/globals": true - }, - "globals": { - "NodeJS": true - }, - "rules": { - "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": [ - "error", - { - "varsIgnorePattern": "^_", - "argsIgnorePattern": "^_", - "destructuredArrayIgnorePattern": "^_", - "ignoreRestSiblings": true - } - ], - "local-rules/no-test-com": "error", - "local-rules/email-domain-example-com": "error", - "no-console": "warn", - // We have a lot of tests that don't have assertions, they use our test - // API client that does the assertions for them - "jest/expect-expect": "off", - // We do this in some tests where the behaviour of internal tables - // differs to external, but the API is broadly the same - "jest/no-conditional-expect": "off", - // have to turn this off to allow function overloading in typescript - "no-dupe-class-members": "off", - "no-redeclare": "off" - } - }, - { - "files": [ - "packages/builder/**/*", - "packages/client/**/*", - "packages/frontend-core/**/*" - ], - "rules": { - "no-console": ["error", { "allow": ["warn", "error", "debug"] }] - } - } - ], - "rules": { - "no-self-assign": "off", - "no-unused-vars": [ - "error", - { - "varsIgnorePattern": "^_", - "argsIgnorePattern": "^_", - "destructuredArrayIgnorePattern": "^_", - "ignoreRestSiblings": true - } - ], - "import/no-relative-packages": "error", - "import/export": "error", - "import/no-duplicates": "error", - "import/newline-after-import": "error" - }, - "globals": { - "GeolocationPositionError": true - } -} diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000000..4a063737b4 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,212 @@ +import _import from "eslint-plugin-import" +import localRules from "eslint-plugin-local-rules" +import { fixupPluginRules } from "@eslint/compat" +import globals from "globals" +import babelParser from "@babel/eslint-parser" +import parser from "svelte-eslint-parser" +import typescriptEslint from "@typescript-eslint/eslint-plugin" +import tsParser from "@typescript-eslint/parser" +import jest from "eslint-plugin-jest" +import path from "node:path" +import { fileURLToPath } from "node:url" +import js from "@eslint/js" +import { FlatCompat } from "@eslint/eslintrc" + +import eslint from "@eslint/js" +import tseslint from "typescript-eslint" + +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}) + +export default [ + { + ignores: [ + "**/node_modules", + "**/dist", + "**/public", + "**/*.spec.js", + "**/bundle.js", + "**/node_modules", + "**/public", + "**/dist", + "packages/server/builder", + "packages/server/coverage", + "packages/worker/coverage", + "packages/backend-core/coverage", + "packages/server/client", + "packages/server/coverage", + "packages/builder/.routify", + "packages/sdk/sdk", + "**/*.ivm.bundle.js", + "packages/server/build/oldClientVersions/**/**/*", + ], + }, + tseslint.configs.recommended, + eslint.configs.recommended, + { + plugins: { + import: fixupPluginRules(_import), + "local-rules": localRules, + }, + + languageOptions: { + globals: { + ...globals.browser, + ...globals.jest, + ...globals.node, + // GeolocationPositionError: true, + }, + + parser: babelParser, + ecmaVersion: 2019, + sourceType: "module", + + parserOptions: { + allowImportExportEverywhere: true, + }, + }, + + rules: { + "no-self-assign": "off", + + "no-unused-vars": [ + "error", + { + varsIgnorePattern: "^_", + argsIgnorePattern: "^_", + destructuredArrayIgnorePattern: "^_", + ignoreRestSiblings: true, + }, + ], + + "import/no-relative-packages": "error", + "import/export": "error", + "import/no-duplicates": "error", + "import/newline-after-import": "error", + }, + }, + ...compat.extends("plugin:svelte/recommended").map(config => ({ + ...config, + files: ["**/*.svelte"], + })), + { + files: ["**/*.svelte"], + + languageOptions: { + parser: parser, + ecmaVersion: 2019, + sourceType: "script", + + parserOptions: { + parser: "@typescript-eslint/parser", + allowImportExportEverywhere: true, + }, + }, + }, + ...compat.extends("eslint:recommended").map(config => ({ + ...config, + files: ["**/*.ts"], + })), + { + files: ["**/*.ts"], + + plugins: { + "@typescript-eslint": typescriptEslint, + }, + + languageOptions: { + globals: { + NodeJS: true, + }, + + parser: tsParser, + }, + + rules: { + "no-unused-vars": "off", + "local-rules/no-barrel-imports": "error", + "local-rules/no-budibase-imports": "error", + "local-rules/no-console-error": "error", + + "@typescript-eslint/no-unused-vars": [ + "error", + { + varsIgnorePattern: "^_", + argsIgnorePattern: "^_", + destructuredArrayIgnorePattern: "^_", + ignoreRestSiblings: true, + }, + ], + + "no-redeclare": "off", + "@typescript-eslint/no-redeclare": "error", + "no-dupe-class-members": "off", + }, + }, + ...compat + .extends("eslint:recommended", "plugin:jest/recommended") + .map(config => ({ + ...config, + files: ["**/*.spec.ts"], + })), + { + files: ["**/*.spec.ts"], + + plugins: { + jest, + "@typescript-eslint": typescriptEslint, + }, + + languageOptions: { + globals: { + ...jest.environments.globals.globals, + NodeJS: true, + }, + + parser: tsParser, + }, + + rules: { + "no-unused-vars": "off", + + "@typescript-eslint/no-unused-vars": [ + "error", + { + varsIgnorePattern: "^_", + argsIgnorePattern: "^_", + destructuredArrayIgnorePattern: "^_", + ignoreRestSiblings: true, + }, + ], + + "local-rules/no-test-com": "error", + "local-rules/email-domain-example-com": "error", + "no-console": "warn", + "jest/expect-expect": "off", + "jest/no-conditional-expect": "off", + "no-dupe-class-members": "off", + "no-redeclare": "off", + }, + }, + { + files: [ + "packages/builder/**/*", + "packages/client/**/*", + "packages/frontend-core/**/*", + ], + + rules: { + "no-console": [ + "error", + { + allow: ["warn", "error", "debug"], + }, + ], + }, + }, +] diff --git a/package.json b/package.json index 69eeaaa681..ece57f9cba 100644 --- a/package.json +++ b/package.json @@ -3,21 +3,22 @@ "private": true, "devDependencies": { "@babel/core": "^7.22.5", - "@babel/eslint-parser": "^7.22.5", + "@babel/eslint-parser": "7.25.9", "@babel/preset-env": "^7.22.5", "@esbuild-plugins/tsconfig-paths": "^0.1.2", + "@eslint/compat": "^1.2.4", "@types/node": "20.10.0", "@types/proper-lockfile": "^4.1.4", - "@typescript-eslint/parser": "6.9.0", + "@typescript-eslint/parser": "8.17.0", "cross-spawn": "7.0.6", "depcheck": "^1.4.7", "esbuild": "^0.18.17", "esbuild-node-externals": "^1.14.0", - "eslint": "^8.52.0", - "eslint-plugin-import": "^2.29.0", - "eslint-plugin-jest": "^27.9.0", - "eslint-plugin-local-rules": "^2.0.0", - "eslint-plugin-svelte": "^2.34.0", + "eslint": "9.16.0", + "eslint-plugin-import": "2.31.0", + "eslint-plugin-jest": "28.9.0", + "eslint-plugin-local-rules": "3.0.2", + "eslint-plugin-svelte": "2.46.1", "husky": "^8.0.3", "kill-port": "^1.6.1", "lerna": "7.4.2", @@ -29,7 +30,7 @@ "svelte": "4.2.19", "svelte-eslint-parser": "^0.33.1", "typescript": "5.7.2", - "typescript-eslint": "^7.3.1", + "typescript-eslint": "8.17.0", "yargs": "^17.7.2" }, "scripts": { @@ -115,7 +116,8 @@ "passport": "0.6.0", "fast-xml-parser": "4.4.1", "@azure/identity": "4.2.1", - "kind-of": "6.0.3" + "kind-of": "6.0.3", + "globals": "15.13.0" }, "engines": { "node": ">=20.0.0 <21.0.0" diff --git a/yarn.lock b/yarn.lock index b23894b464..4988e5237d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -964,10 +964,10 @@ json5 "^2.2.2" semver "^6.3.0" -"@babel/eslint-parser@^7.22.5": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.23.3.tgz#7bf0db1c53b54da0c8a12627373554a0828479ca" - integrity sha512-9bTuNlyx7oSstodm1cR1bECj4fkiknsDa1YniISkJemMY3DGhJNYBECbe6QD/q54mp2J8VO66jW3/7uP//iFCw== +"@babel/eslint-parser@7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.25.9.tgz#603c68a63078796527bc9d0833f5e52dd5f9224c" + integrity sha512-5UXfgpK0j0Xr/xIdgdLEhOFxaDZ0bRPWJJchRpqOSur/3rZoPbqqki5mm0p4NE2cs28krBEiSM2MB7//afRSQQ== dependencies: "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" eslint-visitor-keys "^2.1.0" @@ -2670,6 +2670,32 @@ resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.0.tgz#b0ffd0312b4a3fd2d6f77237e7248a5ad3a680ae" integrity sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A== +"@eslint-community/regexpp@^4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" + integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== + +"@eslint/compat@^1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@eslint/compat/-/compat-1.2.4.tgz#b69b0d76ce73fe66d7f8633c406acea151f5c559" + integrity sha512-S8ZdQj/N69YAtuqFt7653jwcvuUj131+6qGLUyDqfDg1OIoBQ66OCuXC473YQfO2AaxITTutiRQiDwoo7ZLYyg== + +"@eslint/config-array@^0.19.0": + version "0.19.1" + resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.1.tgz#734aaea2c40be22bbb1f2a9dac687c57a6a4c984" + integrity sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA== + dependencies: + "@eslint/object-schema" "^2.1.5" + debug "^4.3.1" + minimatch "^3.1.2" + +"@eslint/core@^0.9.0": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.9.1.tgz#31763847308ef6b7084a4505573ac9402c51f9d1" + integrity sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q== + dependencies: + "@types/json-schema" "^7.0.15" + "@eslint/eslintrc@^2.1.4": version "2.1.4" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" @@ -2685,11 +2711,43 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" +"@eslint/eslintrc@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.2.0.tgz#57470ac4e2e283a6bf76044d63281196e370542c" + integrity sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^10.0.1" + globals "^14.0.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + "@eslint/js@8.57.0": version "8.57.0" resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f" integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g== +"@eslint/js@9.16.0": + version "9.16.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.16.0.tgz#3df2b2dd3b9163056616886c86e4082f45dbf3f4" + integrity sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg== + +"@eslint/object-schema@^2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.5.tgz#8670a8f6258a2be5b2c620ff314a1d984c23eb2e" + integrity sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ== + +"@eslint/plugin-kit@^0.2.3": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz#2b78e7bb3755784bb13faa8932a1d994d6537792" + integrity sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg== + dependencies: + levn "^0.4.1" + "@fastify/busboy@^2.0.0": version "2.1.1" resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d" @@ -2810,6 +2868,19 @@ dependencies: "@hapi/hoek" "^9.0.0" +"@humanfs/core@^0.19.1": + version "0.19.1" + resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77" + integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== + +"@humanfs/node@^0.16.6": + version "0.16.6" + resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.6.tgz#ee2a10eaabd1131987bf0488fd9b820174cd765e" + integrity sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw== + dependencies: + "@humanfs/core" "^0.19.1" + "@humanwhocodes/retry" "^0.3.0" + "@humanwhocodes/config-array@^0.11.14": version "0.11.14" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" @@ -2829,6 +2900,16 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== +"@humanwhocodes/retry@^0.3.0": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a" + integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA== + +"@humanwhocodes/retry@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.1.tgz#9a96ce501bc62df46c4031fbd970e3cc6b10f07b" + integrity sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA== + "@hutson/parse-repository-url@^3.0.0": version "3.0.2" resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" @@ -4232,6 +4313,11 @@ node-fetch "^2.6.0" utf-8-validate "^5.0.2" +"@rtsao/scc@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" + integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g== + "@shopify/jest-koa-mocks@5.1.1": version "5.1.1" resolved "https://registry.yarnpkg.com/@shopify/jest-koa-mocks/-/jest-koa-mocks-5.1.1.tgz#d615815b0cf0ec9823d054da68c419508b3c3193" @@ -5512,6 +5598,11 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== +"@types/estree@^1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== + "@types/express-serve-static-core@^4.17.33": version "4.17.33" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz#de35d30a9d637dc1450ad18dd583d75d5733d543" @@ -5594,7 +5685,7 @@ expect "^29.0.0" pretty-format "^29.0.0" -"@types/json-schema@^7.0.6", "@types/json-schema@^7.0.9": +"@types/json-schema@^7.0.15", "@types/json-schema@^7.0.6": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -6047,11 +6138,6 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.7.tgz#b9eb89d7dfa70d5d1ce525bc1411a35347f533a3" integrity sha512-4g1jrL98mdOIwSOUh6LTlB0Cs9I0dQPwINUhBg7C6pN4HLr8GS8xsksJxilW6S6dQHVi2K/o+lQuQcg7LroCnw== -"@types/semver@^7.3.12": - version "7.5.8" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" - integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== - "@types/serve-static@*": version "1.15.1" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.1.tgz#86b1753f0be4f9a1bee68d459fcda5be4ea52b5d" @@ -6218,74 +6304,47 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz#b16d3cf3ee76bf572fdf511e79c248bdec619ea3" - integrity sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw== +"@typescript-eslint/eslint-plugin@8.17.0": + version "8.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.17.0.tgz#2ee073c421f4e81e02d10e731241664b6253b23c" + integrity sha512-HU1KAdW3Tt8zQkdvNoIijfWDMvdSweFYm4hWh+KwhPstv+sCmWb89hCIP8msFm9N1R/ooh9honpSuvqKWlYy3w== dependencies: "@eslint-community/regexpp" "^4.10.0" - "@typescript-eslint/scope-manager" "7.18.0" - "@typescript-eslint/type-utils" "7.18.0" - "@typescript-eslint/utils" "7.18.0" - "@typescript-eslint/visitor-keys" "7.18.0" + "@typescript-eslint/scope-manager" "8.17.0" + "@typescript-eslint/type-utils" "8.17.0" + "@typescript-eslint/utils" "8.17.0" + "@typescript-eslint/visitor-keys" "8.17.0" graphemer "^1.4.0" ignore "^5.3.1" natural-compare "^1.4.0" ts-api-utils "^1.3.0" -"@typescript-eslint/parser@6.9.0": - version "6.9.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.9.0.tgz#2b402cadeadd3f211c25820e5433413347b27391" - integrity sha512-GZmjMh4AJ/5gaH4XF2eXA8tMnHWP+Pm1mjQR2QN4Iz+j/zO04b9TOvJYOX2sCNIQHtRStKTxRY1FX7LhpJT4Gw== +"@typescript-eslint/parser@8.17.0": + version "8.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.17.0.tgz#2ee972bb12fa69ac625b85813dc8d9a5a053ff52" + integrity sha512-Drp39TXuUlD49F7ilHHCG7TTg8IkA+hxCuULdmzWYICxGXvDXmDmWEjJYZQYgf6l/TFfYNE167m7isnc3xlIEg== dependencies: - "@typescript-eslint/scope-manager" "6.9.0" - "@typescript-eslint/types" "6.9.0" - "@typescript-eslint/typescript-estree" "6.9.0" - "@typescript-eslint/visitor-keys" "6.9.0" + "@typescript-eslint/scope-manager" "8.17.0" + "@typescript-eslint/types" "8.17.0" + "@typescript-eslint/typescript-estree" "8.17.0" + "@typescript-eslint/visitor-keys" "8.17.0" debug "^4.3.4" -"@typescript-eslint/parser@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.18.0.tgz#83928d0f1b7f4afa974098c64b5ce6f9051f96a0" - integrity sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg== +"@typescript-eslint/scope-manager@8.17.0": + version "8.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.17.0.tgz#a3f49bf3d4d27ff8d6b2ea099ba465ef4dbcaa3a" + integrity sha512-/ewp4XjvnxaREtqsZjF4Mfn078RD/9GmiEAtTeLQ7yFdKnqwTOgRMSvFz4et9U5RiJQ15WTGXPLj89zGusvxBg== dependencies: - "@typescript-eslint/scope-manager" "7.18.0" - "@typescript-eslint/types" "7.18.0" - "@typescript-eslint/typescript-estree" "7.18.0" - "@typescript-eslint/visitor-keys" "7.18.0" - debug "^4.3.4" + "@typescript-eslint/types" "8.17.0" + "@typescript-eslint/visitor-keys" "8.17.0" -"@typescript-eslint/scope-manager@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" - integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== +"@typescript-eslint/type-utils@8.17.0": + version "8.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.17.0.tgz#d326569f498cdd0edf58d5bb6030b4ad914e63d3" + integrity sha512-q38llWJYPd63rRnJ6wY/ZQqIzPrBCkPdpIsaCfkR3Q4t3p6sb422zougfad4TFW9+ElIFLVDzWGiGAfbb/v2qw== dependencies: - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/visitor-keys" "5.62.0" - -"@typescript-eslint/scope-manager@6.9.0": - version "6.9.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.9.0.tgz#2626e9a7fe0e004c3e25f3b986c75f584431134e" - integrity sha512-1R8A9Mc39n4pCCz9o79qRO31HGNDvC7UhPhv26TovDsWPBDx+Sg3rOZdCELIA3ZmNoWAuxaMOT7aWtGRSYkQxw== - dependencies: - "@typescript-eslint/types" "6.9.0" - "@typescript-eslint/visitor-keys" "6.9.0" - -"@typescript-eslint/scope-manager@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz#c928e7a9fc2c0b3ed92ab3112c614d6bd9951c83" - integrity sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA== - dependencies: - "@typescript-eslint/types" "7.18.0" - "@typescript-eslint/visitor-keys" "7.18.0" - -"@typescript-eslint/type-utils@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz#2165ffaee00b1fbbdd2d40aa85232dab6998f53b" - integrity sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA== - dependencies: - "@typescript-eslint/typescript-estree" "7.18.0" - "@typescript-eslint/utils" "7.18.0" + "@typescript-eslint/typescript-estree" "8.17.0" + "@typescript-eslint/utils" "8.17.0" debug "^4.3.4" ts-api-utils "^1.3.0" @@ -6299,51 +6358,20 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== -"@typescript-eslint/types@6.9.0": - version "6.9.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.9.0.tgz#86a0cbe7ac46c0761429f928467ff3d92f841098" - integrity sha512-+KB0lbkpxBkBSiVCuQvduqMJy+I1FyDbdwSpM3IoBS7APl4Bu15lStPjgBIdykdRqQNYqYNMa8Kuidax6phaEw== +"@typescript-eslint/types@8.17.0": + version "8.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.17.0.tgz#ef84c709ef8324e766878834970bea9a7e3b72cf" + integrity sha512-gY2TVzeve3z6crqh2Ic7Cr+CAv6pfb0Egee7J5UAVWCpVvDI/F71wNfolIim4FE6hT15EbpZFVUj9j5i38jYXA== -"@typescript-eslint/types@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.18.0.tgz#b90a57ccdea71797ffffa0321e744f379ec838c9" - integrity sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ== - -"@typescript-eslint/typescript-estree@5.62.0", "@typescript-eslint/typescript-estree@^5.13.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" - integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== +"@typescript-eslint/typescript-estree@8.17.0": + version "8.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.17.0.tgz#40b5903bc929b1e8dd9c77db3cb52cfb199a2a34" + integrity sha512-JqkOopc1nRKZpX+opvKqnM3XUlM7LpFMD0lYxTqOTKQfCWAmxw45e3qlOCsEqEB2yuacujivudOFpCnqkBDNMw== dependencies: - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/visitor-keys" "5.62.0" + "@typescript-eslint/types" "8.17.0" + "@typescript-eslint/visitor-keys" "8.17.0" debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/typescript-estree@6.9.0": - version "6.9.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.0.tgz#d0601b245be873d8fe49f3737f93f8662c8693d4" - integrity sha512-NJM2BnJFZBEAbCfBP00zONKXvMqihZCrmwCaik0UhLr0vAgb6oguXxLX1k00oQyD+vZZ+CJn3kocvv2yxm4awQ== - dependencies: - "@typescript-eslint/types" "6.9.0" - "@typescript-eslint/visitor-keys" "6.9.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.5.4" - ts-api-utils "^1.0.1" - -"@typescript-eslint/typescript-estree@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz#b5868d486c51ce8f312309ba79bdb9f331b37931" - integrity sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA== - dependencies: - "@typescript-eslint/types" "7.18.0" - "@typescript-eslint/visitor-keys" "7.18.0" - debug "^4.3.4" - globby "^11.1.0" + fast-glob "^3.3.2" is-glob "^4.0.3" minimatch "^9.0.4" semver "^7.6.0" @@ -6362,29 +6390,28 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/utils@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.18.0.tgz#bca01cde77f95fc6a8d5b0dbcbfb3d6ca4be451f" - integrity sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw== +"@typescript-eslint/typescript-estree@^5.13.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/utils@8.17.0", "@typescript-eslint/utils@^6.0.0 || ^7.0.0 || ^8.0.0": + version "8.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.17.0.tgz#41c05105a2b6ab7592f513d2eeb2c2c0236d8908" + integrity sha512-bQC8BnEkxqG8HBGKwG9wXlZqg37RKSMY7v/X8VEWD8JG2JuTHuNK0VFvMPMUKQcbk6B+tf05k+4AShAEtCtJ/w== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@typescript-eslint/scope-manager" "7.18.0" - "@typescript-eslint/types" "7.18.0" - "@typescript-eslint/typescript-estree" "7.18.0" - -"@typescript-eslint/utils@^5.10.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" - integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.62.0" - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/typescript-estree" "5.62.0" - eslint-scope "^5.1.1" - semver "^7.3.7" + "@typescript-eslint/scope-manager" "8.17.0" + "@typescript-eslint/types" "8.17.0" + "@typescript-eslint/typescript-estree" "8.17.0" "@typescript-eslint/visitor-keys@4.33.0": version "4.33.0" @@ -6402,21 +6429,13 @@ "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" -"@typescript-eslint/visitor-keys@6.9.0": - version "6.9.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.0.tgz#cc69421c10c4ac997ed34f453027245988164e80" - integrity sha512-dGtAfqjV6RFOtIP8I0B4ZTBRrlTT8NHHlZZSchQx3qReaoDeXhYM++M4So2AgFK9ZB0emRPA6JI1HkafzA2Ibg== +"@typescript-eslint/visitor-keys@8.17.0": + version "8.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.17.0.tgz#4dbcd0e28b9bf951f4293805bf34f98df45e1aa8" + integrity sha512-1Hm7THLpO6ww5QU6H/Qp+AusUUl+z/CAm3cNZZ0jQvon9yicgO7Rwd+/WWRpMKLYV6p2UvdbR27c86rzCPpreg== dependencies: - "@typescript-eslint/types" "6.9.0" - eslint-visitor-keys "^3.4.1" - -"@typescript-eslint/visitor-keys@7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz#0564629b6124d67607378d0f0332a0495b25e7d7" - integrity sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg== - dependencies: - "@typescript-eslint/types" "7.18.0" - eslint-visitor-keys "^3.4.3" + "@typescript-eslint/types" "8.17.0" + eslint-visitor-keys "^4.2.0" "@ungap/structured-clone@^1.2.0": version "1.2.0" @@ -6701,6 +6720,11 @@ acorn@^8.1.0, acorn@^8.10.0, acorn@^8.11.0, acorn@^8.11.3, acorn@^8.2.4, acorn@^ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== +acorn@^8.14.0: + version "8.14.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0" + integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== + add-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" @@ -7002,6 +7026,18 @@ array-includes@^3.1.7: get-intrinsic "^1.2.1" is-string "^1.0.7" +array-includes@^3.1.8: + version "3.1.8" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.8.tgz#5e370cbe172fdd5dd6530c1d4aadda25281ba97d" + integrity sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" + get-intrinsic "^1.2.4" + is-string "^1.0.7" + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -7023,6 +7059,18 @@ array.prototype.findlastindex@^1.2.3: es-shim-unscopables "^1.0.0" get-intrinsic "^1.2.1" +array.prototype.findlastindex@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz#8c35a755c72908719453f87145ca011e39334d0d" + integrity sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-shim-unscopables "^1.0.2" + array.prototype.flat@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" @@ -8797,7 +8845,7 @@ cron-validate@1.4.5: dependencies: yup "0.32.9" -cross-spawn@7.0.6: +cross-spawn@7.0.6, cross-spawn@^7.0.5: version "7.0.6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== @@ -10119,7 +10167,7 @@ es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0: unbox-primitive "^1.0.2" which-typed-array "^1.1.15" -es-abstract@^1.23.3: +es-abstract@^1.23.2, es-abstract@^1.23.3: version "1.23.5" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.5.tgz#f4599a4946d57ed467515ed10e4f157289cd52fb" integrity sha512-vlmniQ0WNPwXqA0BnmwV3Ng7HxiGlh6r5U6JcTMNx8OilcAGqVJBHJcPjqOMaczU9fRuRK5Px2BdVyPRnKMMVQ== @@ -10214,7 +10262,7 @@ es-set-tostringtag@^2.0.3: has-tostringtag "^1.0.2" hasown "^2.0.1" -es-shim-unscopables@^1.0.0: +es-shim-unscopables@^1.0.0, es-shim-unscopables@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== @@ -10322,10 +10370,12 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-compat-utils@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz#f45e3b5ced4c746c127cf724fb074cd4e730d653" - integrity sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg== +eslint-compat-utils@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz#7fc92b776d185a70c4070d03fd26fde3d59652e4" + integrity sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q== + dependencies: + semver "^7.5.4" eslint-config-airbnb-base@^15.0.0: version "15.0.0" @@ -10346,6 +10396,13 @@ eslint-import-resolver-node@^0.3.9: is-core-module "^2.13.0" resolve "^1.22.4" +eslint-module-utils@^2.12.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz#fe4cfb948d61f49203d7b08871982b65b9af0b0b" + integrity sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg== + dependencies: + debug "^3.2.7" + eslint-module-utils@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" @@ -10353,7 +10410,32 @@ eslint-module-utils@^2.8.0: dependencies: debug "^3.2.7" -eslint-plugin-import@^2.26.0, eslint-plugin-import@^2.29.0: +eslint-plugin-import@2.31.0: + version "2.31.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz#310ce7e720ca1d9c0bb3f69adfd1c6bdd7d9e0e7" + integrity sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A== + dependencies: + "@rtsao/scc" "^1.1.0" + array-includes "^3.1.8" + array.prototype.findlastindex "^1.2.5" + array.prototype.flat "^1.3.2" + array.prototype.flatmap "^1.3.2" + debug "^3.2.7" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.9" + eslint-module-utils "^2.12.0" + hasown "^2.0.2" + is-core-module "^2.15.1" + is-glob "^4.0.3" + minimatch "^3.1.2" + object.fromentries "^2.0.8" + object.groupby "^1.0.3" + object.values "^1.2.0" + semver "^6.3.1" + string.prototype.trimend "^1.0.8" + tsconfig-paths "^3.15.0" + +eslint-plugin-import@^2.26.0: version "2.29.1" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== @@ -10376,37 +10458,36 @@ eslint-plugin-import@^2.26.0, eslint-plugin-import@^2.29.0: semver "^6.3.1" tsconfig-paths "^3.15.0" -eslint-plugin-jest@^27.9.0: - version "27.9.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-27.9.0.tgz#7c98a33605e1d8b8442ace092b60e9919730000b" - integrity sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug== +eslint-plugin-jest@28.9.0: + version "28.9.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-28.9.0.tgz#19168dfaed124339cd2252c4c4d1ac3688aeb243" + integrity sha512-rLu1s1Wf96TgUUxSw6loVIkNtUjq1Re7A9QdCCHSohnvXEBAjuL420h0T/fMmkQlNsQP2GhQzEUpYHPfxBkvYQ== dependencies: - "@typescript-eslint/utils" "^5.10.0" + "@typescript-eslint/utils" "^6.0.0 || ^7.0.0 || ^8.0.0" -eslint-plugin-local-rules@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-local-rules/-/eslint-plugin-local-rules-2.0.0.tgz#cda95d7616cc0e2609d76c347c187ca2be1e252e" - integrity sha512-sWueme0kUcP0JC1+6OBDQ9edBDVFJR92WJHSRbhiRExlenMEuUisdaVBPR+ItFBFXo2Pdw6FD2UfGZWkz8e93g== +eslint-plugin-local-rules@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-local-rules/-/eslint-plugin-local-rules-3.0.2.tgz#84c02ea1d604ecb00970779ad27f00738ff361ae" + integrity sha512-IWME7GIYHXogTkFsToLdBCQVJ0U4kbSuVyDT+nKoR4UgtnVrrVeNWuAZkdEu1nxkvi9nsPccGehEEF6dgA28IQ== -eslint-plugin-svelte@^2.34.0: - version "2.35.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-svelte/-/eslint-plugin-svelte-2.35.1.tgz#7b1e3c263b09dbc9293c25fe02d03d309725d2b9" - integrity sha512-IF8TpLnROSGy98Z3NrsKXWDSCbNY2ReHDcrYTuXZMbfX7VmESISR78TWgO9zdg4Dht1X8coub5jKwHzP0ExRug== +eslint-plugin-svelte@2.46.1: + version "2.46.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-svelte/-/eslint-plugin-svelte-2.46.1.tgz#22691c8685420cd4eabf0cbaa31a0cfb8395595b" + integrity sha512-7xYr2o4NID/f9OEYMqxsEQsCsj4KaMy4q5sANaKkAb6/QeCjYFxRmDm2S3YC3A3pl1kyPZ/syOx/i7LcWYSbIw== dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - debug "^4.3.1" - eslint-compat-utils "^0.1.2" + "@eslint-community/eslint-utils" "^4.4.0" + "@jridgewell/sourcemap-codec" "^1.4.15" + eslint-compat-utils "^0.5.1" esutils "^2.0.3" - known-css-properties "^0.29.0" - postcss "^8.4.5" + known-css-properties "^0.35.0" + postcss "^8.4.38" postcss-load-config "^3.1.4" postcss-safe-parser "^6.0.0" - postcss-selector-parser "^6.0.11" - semver "^7.5.3" - svelte-eslint-parser ">=0.33.0 <1.0.0" + postcss-selector-parser "^6.1.0" + semver "^7.6.2" + svelte-eslint-parser "^0.43.0" -eslint-scope@5.1.1, eslint-scope@^5.1.1: +eslint-scope@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== @@ -10422,6 +10503,14 @@ eslint-scope@^7.0.0, eslint-scope@^7.2.2: esrecurse "^4.3.0" estraverse "^5.2.0" +eslint-scope@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.2.0.tgz#377aa6f1cb5dc7592cfd0b7f892fd0cf352ce442" + integrity sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" @@ -10432,7 +10521,52 @@ eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4 resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -eslint@^8.52.0, eslint@^8.56.0: +eslint-visitor-keys@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45" + integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== + +eslint@9.16.0: + version "9.16.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.16.0.tgz#66832e66258922ac0a626f803a9273e37747f2a6" + integrity sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.12.1" + "@eslint/config-array" "^0.19.0" + "@eslint/core" "^0.9.0" + "@eslint/eslintrc" "^3.2.0" + "@eslint/js" "9.16.0" + "@eslint/plugin-kit" "^0.2.3" + "@humanfs/node" "^0.16.6" + "@humanwhocodes/module-importer" "^1.0.1" + "@humanwhocodes/retry" "^0.4.1" + "@types/estree" "^1.0.6" + "@types/json-schema" "^7.0.15" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.5" + debug "^4.3.2" + escape-string-regexp "^4.0.0" + eslint-scope "^8.2.0" + eslint-visitor-keys "^4.2.0" + espree "^10.3.0" + esquery "^1.5.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^8.0.0" + find-up "^5.0.0" + glob-parent "^6.0.2" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + json-stable-stringify-without-jsonify "^1.0.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + +eslint@^8.56.0: version "8.57.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.0.tgz#c786a6fd0e0b68941aaf624596fb987089195668" integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ== @@ -10481,6 +10615,15 @@ esm@^3.2.25: resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== +espree@^10.0.1, espree@^10.3.0: + version "10.3.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-10.3.0.tgz#29267cf5b0cb98735b65e64ba07e0ed49d1eed8a" + integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg== + dependencies: + acorn "^8.14.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^4.2.0" + espree@^9.0.0, espree@^9.6.0, espree@^9.6.1: version "9.6.1" resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" @@ -10510,7 +10653,7 @@ esprima@~3.1.0: resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" integrity sha512-AWwVMNxwhN8+NIPQzAQZCm7RkLC4RbM3B1OobMuyp3i+w73X57KCKaVIxaRZb+DYCojq7rspo+fmuQfAboyhFg== -esquery@^1.4.2: +esquery@^1.4.2, esquery@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== @@ -10739,6 +10882,17 @@ fast-glob@^3.2.11, fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" +fast-glob@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-json-patch@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/fast-json-patch/-/fast-json-patch-3.1.1.tgz#85064ea1b1ebf97a3f7ad01e23f9337e72c66947" @@ -10872,6 +11026,13 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" +file-entry-cache@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f" + integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ== + dependencies: + flat-cache "^4.0.0" + file-type@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-11.1.0.tgz#93780f3fed98b599755d846b99a1617a2ad063b8" @@ -11016,6 +11177,14 @@ flat-cache@^3.0.4: flatted "^3.1.0" rimraf "^3.0.2" +flat-cache@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c" + integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw== + dependencies: + flatted "^3.2.9" + keyv "^4.5.4" + flat@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" @@ -11026,6 +11195,11 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== +flatted@^3.2.9: + version "3.3.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.2.tgz#adba1448a9841bec72b42c532ea23dbbedef1a27" + integrity sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA== + flatten@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" @@ -11674,17 +11848,10 @@ global@~4.4.0: min-document "^2.19.0" process "^0.11.10" -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^13.19.0: - version "13.20.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== - dependencies: - type-fest "^0.20.2" +globals@15.13.0, globals@^11.1.0, globals@^13.19.0, globals@^14.0.0: + version "15.13.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-15.13.0.tgz#bbec719d69aafef188ecd67954aae76a696010fc" + integrity sha512-49TewVEz0UxZjr1WYYsWpPrhyC/B/pA8Bq0fUmet2n+eR7yn0IvNzNaoBwnK6mdkzcN+se7Ez9zUgULTz2QH4g== globalthis@^1.0.1, globalthis@^1.0.3: version "1.0.3" @@ -12644,7 +12811,7 @@ is-class-hotfix@~0.0.6: resolved "https://registry.yarnpkg.com/is-class-hotfix/-/is-class-hotfix-0.0.6.tgz#a527d31fb23279281dde5f385c77b5de70a72435" integrity sha512-0n+pzCC6ICtVr/WXnN2f03TK/3BfXY7me4cjCAqT8TYXEl0+JBRoqBo94JJHXcyDSLUeWbNX8Fvy5g5RJdAstQ== -is-core-module@^2.12.0: +is-core-module@^2.12.0, is-core-module@^2.15.1: version "2.15.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37" integrity sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ== @@ -13770,6 +13937,11 @@ json-buffer@3.0.0: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ== +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-format-highlight@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/json-format-highlight/-/json-format-highlight-1.0.4.tgz#2e44277edabcec79a3d2c84e984c62e2258037b9" @@ -13943,6 +14115,13 @@ keyv@^3.0.0: dependencies: json-buffer "3.0.0" +keyv@^4.5.4: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + kill-port@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/kill-port/-/kill-port-1.6.1.tgz#560fe79484583bdf3a5e908557dae614447618aa" @@ -13986,10 +14165,10 @@ knex@2.4.2: tarn "^3.0.2" tildify "2.0.0" -known-css-properties@^0.29.0: - version "0.29.0" - resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.29.0.tgz#e8ba024fb03886f23cb882e806929f32d814158f" - integrity sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ== +known-css-properties@^0.35.0: + version "0.35.0" + resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.35.0.tgz#f6f8e40ab4e5700fa32f5b2ef5218a56bc853bd6" + integrity sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A== koa-body@4.2.0: version "4.2.0" @@ -16159,6 +16338,16 @@ object.fromentries@^2.0.7: define-properties "^1.2.0" es-abstract "^1.22.1" +object.fromentries@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.8.tgz#f7195d8a9b97bd95cbc1999ea939ecd1a2b00c65" + integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" + object.groupby@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" @@ -16169,6 +16358,15 @@ object.groupby@^1.0.1: es-abstract "^1.22.1" get-intrinsic "^1.2.1" +object.groupby@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.3.tgz#9b125c36238129f6f7b61954a1e7176148d5002e" + integrity sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + object.values@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" @@ -16178,6 +16376,15 @@ object.values@^1.1.7: define-properties "^1.2.0" es-abstract "^1.22.1" +object.values@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.0.tgz#65405a9d92cee68ac2d303002e0b8470a4d9ab1b" + integrity sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + octal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/octal/-/octal-1.0.0.tgz#63e7162a68efbeb9e213588d58e989d1e5c4530b" @@ -17129,15 +17336,15 @@ postcss-safe-parser@^6.0.0: resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz#bb4c29894171a94bc5c996b9a30317ef402adaa1" integrity sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ== -postcss-scss@^4.0.8: +postcss-scss@^4.0.8, postcss-scss@^4.0.9: version "4.0.9" resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-4.0.9.tgz#a03c773cd4c9623cb04ce142a52afcec74806685" integrity sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A== -postcss-selector-parser@^6.0.11: - version "6.0.13" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" - integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== +postcss-selector-parser@^6.1.0: + version "6.1.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de" + integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" @@ -17160,7 +17367,7 @@ postcss-values-parser@^6.0.2: is-url-superb "^4.0.0" quote-unquote "^1.0.0" -postcss@^8.1.7, postcss@^8.3.11, postcss@^8.4.12, postcss@^8.4.27, postcss@^8.4.29, postcss@^8.4.5: +postcss@^8.1.7, postcss@^8.3.11, postcss@^8.4.12, postcss@^8.4.27, postcss@^8.4.29: version "8.4.41" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.41.tgz#d6104d3ba272d882fe18fc07d15dc2da62fa2681" integrity sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ== @@ -17169,7 +17376,7 @@ postcss@^8.1.7, postcss@^8.3.11, postcss@^8.4.12, postcss@^8.4.27, postcss@^8.4. picocolors "^1.0.1" source-map-js "^1.2.0" -postcss@^8.4.48: +postcss@^8.4.38, postcss@^8.4.39, postcss@^8.4.48: version "8.4.49" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.49.tgz#4ea479048ab059ab3ae61d082190fabfd994fe19" integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA== @@ -18765,7 +18972,7 @@ semver-diff@^3.1.1: dependencies: semver "^6.3.0" -"semver@2 || 3 || 4 || 5", semver@7.5.3, semver@^5.6.0, semver@^5.7.1, semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0, semver@^6.3.1, semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@~2.3.1: +"semver@2 || 3 || 4 || 5", semver@7.5.3, semver@^5.6.0, semver@^5.7.1, semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0, semver@^6.3.1, semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.2, semver@~2.3.1: version "7.5.3" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== @@ -19753,7 +19960,7 @@ svelte-dnd-action@^0.9.8: resolved "https://registry.yarnpkg.com/svelte-dnd-action/-/svelte-dnd-action-0.9.22.tgz#003eee9dddb31d8c782f6832aec8b1507fff194d" integrity sha512-lOQJsNLM1QWv5mdxIkCVtk6k4lHCtLgfE59y8rs7iOM6erchbLC9hMEFYSveZz7biJV0mpg7yDSs4bj/RT/YkA== -"svelte-eslint-parser@>=0.33.0 <1.0.0", svelte-eslint-parser@^0.33.1: +svelte-eslint-parser@^0.33.1: version "0.33.1" resolved "https://registry.yarnpkg.com/svelte-eslint-parser/-/svelte-eslint-parser-0.33.1.tgz#c64dbed2fad099577429b3c39377f6b8d36e5d97" integrity sha512-vo7xPGTlKBGdLH8T5L64FipvTrqv3OQRx9d2z5X05KKZDlF4rQk8KViZO4flKERY+5BiVdOh7zZ7JGJWo5P0uA== @@ -19764,6 +19971,17 @@ svelte-dnd-action@^0.9.8: postcss "^8.4.29" postcss-scss "^4.0.8" +svelte-eslint-parser@^0.43.0: + version "0.43.0" + resolved "https://registry.yarnpkg.com/svelte-eslint-parser/-/svelte-eslint-parser-0.43.0.tgz#649e80f65183c4c1d1536d03dcb903e0632f4da4" + integrity sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA== + dependencies: + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + postcss "^8.4.39" + postcss-scss "^4.0.9" + svelte-hmr@^0.15.1: version "0.15.3" resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.15.3.tgz#df54ccde9be3f091bf5f18fc4ef7b8eb6405fbe6" @@ -20334,7 +20552,7 @@ triple-beam@^1.3.0: resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.4.1.tgz#6fde70271dc6e5d73ca0c3b24e2d92afb7441984" integrity sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg== -ts-api-utils@^1.0.1, ts-api-utils@^1.3.0: +ts-api-utils@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== @@ -20598,14 +20816,14 @@ typeof@^1.0.0: resolved "https://registry.yarnpkg.com/typeof/-/typeof-1.0.0.tgz#9c84403f2323ae5399167275497638ea1d2f2440" integrity sha512-Pze0mIxYXhaJdpw1ayMzOA7rtGr1OmsTY/Z+FWtRKIqXFz6aoDLjqdbWE/tcIBSC8nhnVXiRrEXujodR/xiFAA== -typescript-eslint@^7.3.1: - version "7.18.0" - resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-7.18.0.tgz#e90d57649b2ad37a7475875fa3e834a6d9f61eb2" - integrity sha512-PonBkP603E3tt05lDkbOMyaxJjvKqQrXsnow72sVeOFINDE/qNmnnd+f9b4N+U7W6MXnnYyrhtmF2t08QWwUbA== +typescript-eslint@8.17.0: + version "8.17.0" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.17.0.tgz#fa4033c26b3b40f778287bc12918d985481b220b" + integrity sha512-409VXvFd/f1br1DCbuKNFqQpXICoTB+V51afcwG1pn1a3Cp92MqAUges3YjwEdQ0cMUoCIodjVDAYzyD8h3SYA== dependencies: - "@typescript-eslint/eslint-plugin" "7.18.0" - "@typescript-eslint/parser" "7.18.0" - "@typescript-eslint/utils" "7.18.0" + "@typescript-eslint/eslint-plugin" "8.17.0" + "@typescript-eslint/parser" "8.17.0" + "@typescript-eslint/utils" "8.17.0" typescript@5.7.2: version "5.7.2" From 3332f2fa228e958f2a2541ed7c9715a3d2544867 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Thu, 5 Dec 2024 17:32:07 +0000 Subject: [PATCH 03/22] metrics for view joins and grouped filters --- .../processors/posthog/PosthogProcessor.ts | 4 +- .../src/events/publishers/table.ts | 33 +++++++++--- .../src/events/publishers/view.ts | 17 ++++-- .../src/api/controllers/table/external.ts | 4 +- .../server/src/api/controllers/table/index.ts | 11 +++- .../src/api/controllers/table/internal.ts | 4 +- .../server/src/api/controllers/view/views.ts | 54 +++++++------------ .../src/api/controllers/view/viewsV2.ts | 11 ++-- .../functions/backfill/app/tables.ts | 2 +- .../src/sdk/app/tables/external/index.ts | 2 +- .../src/sdk/app/tables/internal/index.ts | 2 +- packages/server/src/sdk/app/views/external.ts | 4 +- packages/server/src/sdk/app/views/index.ts | 5 +- packages/server/src/sdk/app/views/internal.ts | 4 +- packages/types/src/sdk/events/table.ts | 3 ++ packages/types/src/sdk/events/view.ts | 7 +-- 16 files changed, 100 insertions(+), 67 deletions(-) diff --git a/packages/backend-core/src/events/processors/posthog/PosthogProcessor.ts b/packages/backend-core/src/events/processors/posthog/PosthogProcessor.ts index 12d2bb7e2c..687fe54256 100644 --- a/packages/backend-core/src/events/processors/posthog/PosthogProcessor.ts +++ b/packages/backend-core/src/events/processors/posthog/PosthogProcessor.ts @@ -13,8 +13,8 @@ const EXCLUDED_EVENTS: Event[] = [ Event.ROLE_UPDATED, Event.DATASOURCE_UPDATED, Event.QUERY_UPDATED, - Event.TABLE_UPDATED, - Event.VIEW_UPDATED, + // Event.TABLE_UPDATED, + // Event.VIEW_UPDATED, Event.VIEW_FILTER_UPDATED, Event.VIEW_CALCULATION_UPDATED, Event.AUTOMATION_TRIGGER_UPDATED, diff --git a/packages/backend-core/src/events/publishers/table.ts b/packages/backend-core/src/events/publishers/table.ts index dc3200291a..de765e2cdd 100644 --- a/packages/backend-core/src/events/publishers/table.ts +++ b/packages/backend-core/src/events/publishers/table.ts @@ -1,13 +1,14 @@ import { publishEvent } from "../events" import { Event, - TableExportFormat, + FieldType, Table, TableCreatedEvent, - TableUpdatedEvent, TableDeletedEvent, TableExportedEvent, + TableExportFormat, TableImportedEvent, + TableUpdatedEvent, } from "@budibase/types" async function created(table: Table, timestamp?: string | number) { @@ -20,14 +21,34 @@ async function created(table: Table, timestamp?: string | number) { await publishEvent(Event.TABLE_CREATED, properties, timestamp) } -async function updated(table: Table) { +async function updated(oldTable: Table, newTable: Table) { + // only publish the event if it has fields we are interested in + let defaultValues, aiColumn + + // check that new fields have been added + for (const key in newTable.schema) { + if (!oldTable.schema[key]) { + const newColumn = newTable.schema[key] + if ("default" in newColumn) { + defaultValues = true + } + if (newColumn.type === FieldType.AI) { + aiColumn = newColumn.operation + } + } + } + const properties: TableUpdatedEvent = { - tableId: table._id as string, + tableId: newTable._id as string, + defaultValues, + aiColumn, audited: { - name: table.name, + name: newTable.name, }, } - await publishEvent(Event.TABLE_UPDATED, properties) + if (defaultValues || aiColumn) { + await publishEvent(Event.TABLE_UPDATED, properties) + } } async function deleted(table: Table) { diff --git a/packages/backend-core/src/events/publishers/view.ts b/packages/backend-core/src/events/publishers/view.ts index 0ec8f67485..6d107d58f3 100644 --- a/packages/backend-core/src/events/publishers/view.ts +++ b/packages/backend-core/src/events/publishers/view.ts @@ -11,6 +11,7 @@ import { ViewFilterDeletedEvent, ViewFilterUpdatedEvent, ViewUpdatedEvent, + View, ViewV2, ViewCalculation, Table, @@ -19,17 +20,27 @@ import { /* eslint-disable */ -async function created(view: Partial, timestamp?: string | number) { +async function created(view: ViewV2, timestamp?: string | number) { const properties: ViewCreatedEvent = { name: view.name, type: view.type, + tableId: view.tableId, } await publishEvent(Event.VIEW_CREATED, properties, timestamp) } -async function updated(view: View) { +async function updated(newView: ViewV2) { + // // check whether any of the fields are different + let viewJoins = 0 + for (const key in newView.schema) { + if (newView.schema[key]?.columns) { + viewJoins += Object.keys(newView.schema[key]?.columns).length + } + } const properties: ViewUpdatedEvent = { - tableId: view.tableId, + tableId: newView.tableId, + groupedFilters: newView.queryUI?.groups?.length || 0, + viewJoins, } await publishEvent(Event.VIEW_UPDATED, properties) } diff --git a/packages/server/src/api/controllers/table/external.ts b/packages/server/src/api/controllers/table/external.ts index 6f09bf4a61..d3f5ef99f6 100644 --- a/packages/server/src/api/controllers/table/external.ts +++ b/packages/server/src/api/controllers/table/external.ts @@ -45,13 +45,13 @@ export async function updateTable( inputs.created = true } try { - const { datasource, table } = await sdk.tables.external.save( + const { datasource, oldTable, table } = await sdk.tables.external.save( datasourceId!, inputs, { tableId, renaming } ) builderSocket?.emitDatasourceUpdate(ctx, datasource) - return table + return { table, oldTable } } catch (err: any) { if (err instanceof Error) { ctx.throw(400, err.message) diff --git a/packages/server/src/api/controllers/table/index.ts b/packages/server/src/api/controllers/table/index.ts index 77c1f3923a..0b0c9531e9 100644 --- a/packages/server/src/api/controllers/table/index.ts +++ b/packages/server/src/api/controllers/table/index.ts @@ -119,8 +119,15 @@ export async function save(ctx: UserCtx) { await events.table.created(savedTable) } else { const api = pickApi({ table }) - savedTable = await api.updateTable(ctx, renaming) - await events.table.updated(savedTable) + const { table: updatedTable, oldTable } = await api.updateTable( + ctx, + renaming + ) + savedTable = updatedTable + + if (oldTable) { + await events.table.updated(oldTable, savedTable) + } } if (renaming) { await sdk.views.renameLinkedViews(savedTable, renaming) diff --git a/packages/server/src/api/controllers/table/internal.ts b/packages/server/src/api/controllers/table/internal.ts index 40ce5e279d..67c4ec100c 100644 --- a/packages/server/src/api/controllers/table/internal.ts +++ b/packages/server/src/api/controllers/table/internal.ts @@ -30,14 +30,14 @@ export async function updateTable( } try { - const { table } = await sdk.tables.internal.save(tableToSave, { + const { table, oldTable } = await sdk.tables.internal.save(tableToSave, { userId: ctx.user._id, rowsToImport: rows, tableId: ctx.request.body._id, renaming, }) - return table + return { table, oldTable } } catch (err: any) { if (err instanceof Error) { ctx.throw(400, err.message) diff --git a/packages/server/src/api/controllers/view/views.ts b/packages/server/src/api/controllers/view/views.ts index b1f1f6c154..f1aa219aca 100644 --- a/packages/server/src/api/controllers/view/views.ts +++ b/packages/server/src/api/controllers/view/views.ts @@ -60,35 +60,31 @@ export async function save(ctx: Ctx) { existingTable.views[viewName] = existingTable.views[originalName] } await db.put(table) - await handleViewEvents( - existingTable.views[viewName] as View, - table.views[viewName] - ) ctx.body = table.views[viewName] builderSocket?.emitTableUpdate(ctx, table) } -export async function calculationEvents(existingView: View, newView: View) { - const existingCalculation = existingView && existingView.calculation - const newCalculation = newView && newView.calculation - - if (existingCalculation && !newCalculation) { - await events.view.calculationDeleted(existingView) - } - - if (!existingCalculation && newCalculation) { - await events.view.calculationCreated(newView) - } - - if ( - existingCalculation && - newCalculation && - existingCalculation !== newCalculation - ) { - await events.view.calculationUpdated(newView) - } -} +// export async function calculationEvents(existingView: View, newView: View) { +// const existingCalculation = existingView && existingView.calculation +// const newCalculation = newView && newView.calculation +// +// if (existingCalculation && !newCalculation) { +// await events.view.calculationDeleted(existingView) +// } +// +// if (!existingCalculation && newCalculation) { +// await events.view.calculationCreated(newView) +// } +// +// if ( +// existingCalculation && +// newCalculation && +// existingCalculation !== newCalculation +// ) { +// await events.view.calculationUpdated(newView) +// } +// } export async function filterEvents(existingView: View, newView: View) { const hasExistingFilters = !!( @@ -115,16 +111,6 @@ export async function filterEvents(existingView: View, newView: View) { } } -async function handleViewEvents(existingView: View, newView: View) { - if (!existingView) { - await events.view.created(newView) - } else { - await events.view.updated(newView) - } - await calculationEvents(existingView, newView) - await filterEvents(existingView, newView) -} - export async function destroy(ctx: Ctx) { const db = context.getAppDB() const viewName = decodeURIComponent(ctx.params.viewName) diff --git a/packages/server/src/api/controllers/view/viewsV2.ts b/packages/server/src/api/controllers/view/viewsV2.ts index 46c44ed577..38983a978e 100644 --- a/packages/server/src/api/controllers/view/viewsV2.ts +++ b/packages/server/src/api/controllers/view/viewsV2.ts @@ -151,7 +151,7 @@ export async function create(ctx: Ctx) { } const result = await sdk.views.create(tableId, parsedView) - await events.view.created(view) + await events.view.created(result) ctx.status = 201 ctx.body = { @@ -190,10 +190,11 @@ export async function update(ctx: Ctx) { primaryDisplay: view.primaryDisplay, } - const result = await sdk.views.update(tableId, parsedView) - ctx.body = { - data: result, - } + const { view: result } = await sdk.views.update(tableId, parsedView) + + await events.view.updated(result) + + ctx.body = { data: result } const table = await sdk.tables.getTable(tableId) builderSocket?.emitTableUpdate(ctx, table) diff --git a/packages/server/src/migrations/functions/backfill/app/tables.ts b/packages/server/src/migrations/functions/backfill/app/tables.ts index 081b81ede5..c6e46173dc 100644 --- a/packages/server/src/migrations/functions/backfill/app/tables.ts +++ b/packages/server/src/migrations/functions/backfill/app/tables.ts @@ -14,7 +14,7 @@ export const backfill = async (appDb: Database, timestamp: string | number) => { continue } - await events.view.created(view, timestamp) + // await events.view.created(view, timestamp) if (view.calculation) { await events.view.calculationCreated(view, timestamp) diff --git a/packages/server/src/sdk/app/tables/external/index.ts b/packages/server/src/sdk/app/tables/external/index.ts index 941d193b94..a7a15cac22 100644 --- a/packages/server/src/sdk/app/tables/external/index.ts +++ b/packages/server/src/sdk/app/tables/external/index.ts @@ -282,7 +282,7 @@ export async function save( tableToSave.sql = true } - return { datasource: updatedDatasource, table: tableToSave } + return { datasource: updatedDatasource, table: tableToSave, oldTable } } export async function destroy(datasourceId: string, table: Table) { diff --git a/packages/server/src/sdk/app/tables/internal/index.ts b/packages/server/src/sdk/app/tables/internal/index.ts index fbcbed03dc..5b9f346e93 100644 --- a/packages/server/src/sdk/app/tables/internal/index.ts +++ b/packages/server/src/sdk/app/tables/internal/index.ts @@ -171,7 +171,7 @@ export async function save( } // has to run after, make sure it has _id await runStaticFormulaChecks(table, { oldTable, deletion: false }) - return { table } + return { table, oldTable } } export async function destroy(table: Table) { diff --git a/packages/server/src/sdk/app/views/external.ts b/packages/server/src/sdk/app/views/external.ts index bee153a910..9016a3bd61 100644 --- a/packages/server/src/sdk/app/views/external.ts +++ b/packages/server/src/sdk/app/views/external.ts @@ -63,7 +63,7 @@ export async function create( export async function update( tableId: string, view: Readonly -): Promise { +): Promise<{ view: ViewV2; existingView: ViewV2 }> { const db = context.getAppDB() const { datasourceId, tableName } = breakExternalTableId(tableId) @@ -87,7 +87,7 @@ export async function update( delete views[existingView.name] views[view.name] = view await db.put(ds) - return view + return { view, existingView } } export async function remove(viewId: string): Promise { diff --git a/packages/server/src/sdk/app/views/index.ts b/packages/server/src/sdk/app/views/index.ts index 58537c96ad..f483ebc0bc 100644 --- a/packages/server/src/sdk/app/views/index.ts +++ b/packages/server/src/sdk/app/views/index.ts @@ -315,7 +315,10 @@ export async function create( return view } -export async function update(tableId: string, view: ViewV2): Promise { +export async function update( + tableId: string, + view: ViewV2 +): Promise<{ view: ViewV2; existingView: ViewV2 }> { await guardViewSchema(tableId, view) return pickApi(tableId).update(tableId, view) diff --git a/packages/server/src/sdk/app/views/internal.ts b/packages/server/src/sdk/app/views/internal.ts index 63807bcfd4..ec152abe54 100644 --- a/packages/server/src/sdk/app/views/internal.ts +++ b/packages/server/src/sdk/app/views/internal.ts @@ -54,7 +54,7 @@ export async function create( export async function update( tableId: string, view: Readonly -): Promise { +): Promise<{ view: ViewV2; existingView: ViewV2 }> { const db = context.getAppDB() const table = await sdk.tables.getTable(tableId) table.views ??= {} @@ -76,7 +76,7 @@ export async function update( delete table.views[existingView.name] table.views[view.name] = view await db.put(table) - return view + return { view, existingView } } export async function remove(viewId: string): Promise { diff --git a/packages/types/src/sdk/events/table.ts b/packages/types/src/sdk/events/table.ts index 8df2a95796..4a5880b1db 100644 --- a/packages/types/src/sdk/events/table.ts +++ b/packages/types/src/sdk/events/table.ts @@ -1,4 +1,5 @@ import { BaseEvent, TableExportFormat } from "./event" +import { AIOperationEnum } from "../ai" export interface TableCreatedEvent extends BaseEvent { tableId: string @@ -9,6 +10,8 @@ export interface TableCreatedEvent extends BaseEvent { export interface TableUpdatedEvent extends BaseEvent { tableId: string + defaultValues: boolean | undefined + aiColumn: AIOperationEnum | undefined audited: { name: string } diff --git a/packages/types/src/sdk/events/view.ts b/packages/types/src/sdk/events/view.ts index 84fcb0facc..c73a591a34 100644 --- a/packages/types/src/sdk/events/view.ts +++ b/packages/types/src/sdk/events/view.ts @@ -1,15 +1,16 @@ -import { ViewCalculation, ViewV2Schema, ViewV2Type } from "../../documents" +import { ViewCalculation, ViewV2Type } from "../../documents" import { BaseEvent, TableExportFormat } from "./event" -import { LegacyFilter, SortOrder, SortType, UISearchFilter } from "../../api" -import { SearchFilters } from "../search" export interface ViewCreatedEvent extends BaseEvent { name: string type?: ViewV2Type + tableId: string } export interface ViewUpdatedEvent extends BaseEvent { tableId: string + groupedFilters: number + viewJoins: number } export interface ViewDeletedEvent extends BaseEvent { From 84927bbb984b20579c629b2ce04ede9004059c9b Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Thu, 5 Dec 2024 18:13:32 +0000 Subject: [PATCH 04/22] Update to latest eslint, including new config file format. --- eslint.config.mjs | 178 +++++++----------- package.json | 4 +- .../src/events/publishers/query.ts | 2 - .../src/events/publishers/rows.ts | 2 - .../src/events/publishers/view.ts | 2 - .../stores/datasourceCreation.test.js | 1 - .../src/components/Updating.svelte | 1 - .../src/api/routes/tests/application.spec.ts | 2 +- .../src/api/routes/tests/search.spec.ts | 10 - .../src/integration-test/postgres.spec.ts | 2 +- packages/server/src/integrations/redis.ts | 2 +- packages/server/src/integrations/rest.ts | 4 +- .../integrations/tests/googlesheets.spec.ts | 1 - .../src/integrations/tests/rest.spec.ts | 1 - .../src/integrations/tests/sqlAlias.spec.ts | 6 +- .../server/src/jsRunner/vm/isolated-vm.ts | 2 +- packages/server/src/middleware/builder.ts | 2 +- .../migrations/functions/usageQuotas/index.ts | 2 +- .../server/src/startup/tests/startup.spec.ts | 2 +- packages/server/src/utilities/global.ts | 2 +- packages/server/src/websockets/builder.ts | 2 +- packages/server/src/websockets/grid.ts | 2 +- packages/server/src/websockets/middleware.ts | 2 +- packages/server/src/websockets/websocket.ts | 2 +- packages/types/src/sdk/migrations.ts | 2 +- .../src/api/routes/global/tests/auth.spec.ts | 4 +- .../src/api/routes/global/tests/users.spec.ts | 2 +- .../worker/src/middleware/handleScimBody.ts | 2 +- packages/worker/src/tests/api/email.ts | 2 +- yarn.lock | 123 +----------- 30 files changed, 105 insertions(+), 266 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 4a063737b4..59c2202e94 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,29 +1,17 @@ -import _import from "eslint-plugin-import" -import localRules from "eslint-plugin-local-rules" -import { fixupPluginRules } from "@eslint/compat" import globals from "globals" import babelParser from "@babel/eslint-parser" -import parser from "svelte-eslint-parser" -import typescriptEslint from "@typescript-eslint/eslint-plugin" +import svelteParser from "svelte-eslint-parser" import tsParser from "@typescript-eslint/parser" -import jest from "eslint-plugin-jest" -import path from "node:path" -import { fileURLToPath } from "node:url" -import js from "@eslint/js" -import { FlatCompat } from "@eslint/eslintrc" + +import eslintPluginJest from "eslint-plugin-jest" +import eslintPluginSvelte from "eslint-plugin-svelte" +import eslintPluginLocalRules from "eslint-plugin-local-rules" import eslint from "@eslint/js" import tseslint from "typescript-eslint" -const __filename = fileURLToPath(import.meta.url) -const __dirname = path.dirname(__filename) -const compat = new FlatCompat({ - baseDirectory: __dirname, - recommendedConfig: js.configs.recommended, - allConfig: js.configs.all, -}) - export default [ + eslint.configs.recommended, { ignores: [ "**/node_modules", @@ -46,12 +34,9 @@ export default [ "packages/server/build/oldClientVersions/**/**/*", ], }, - tseslint.configs.recommended, - eslint.configs.recommended, { plugins: { - import: fixupPluginRules(_import), - "local-rules": localRules, + "local-rules": eslintPluginLocalRules, }, languageOptions: { @@ -59,7 +44,7 @@ export default [ ...globals.browser, ...globals.jest, ...globals.node, - // GeolocationPositionError: true, + GeolocationPositionError: true, }, parser: babelParser, @@ -73,7 +58,7 @@ export default [ rules: { "no-self-assign": "off", - + "prefer-const": "off", "no-unused-vars": [ "error", { @@ -81,90 +66,81 @@ export default [ argsIgnorePattern: "^_", destructuredArrayIgnorePattern: "^_", ignoreRestSiblings: true, + caughtErrors: "none", }, ], - - "import/no-relative-packages": "error", - "import/export": "error", - "import/no-duplicates": "error", - "import/newline-after-import": "error", }, }, - ...compat.extends("plugin:svelte/recommended").map(config => ({ - ...config, - files: ["**/*.svelte"], - })), - { - files: ["**/*.svelte"], - - languageOptions: { - parser: parser, - ecmaVersion: 2019, - sourceType: "script", - - parserOptions: { - parser: "@typescript-eslint/parser", - allowImportExportEverywhere: true, - }, - }, - }, - ...compat.extends("eslint:recommended").map(config => ({ - ...config, - files: ["**/*.ts"], - })), - { - files: ["**/*.ts"], - - plugins: { - "@typescript-eslint": typescriptEslint, - }, - - languageOptions: { - globals: { - NodeJS: true, - }, - - parser: tsParser, - }, - - rules: { - "no-unused-vars": "off", - "local-rules/no-barrel-imports": "error", - "local-rules/no-budibase-imports": "error", - "local-rules/no-console-error": "error", - - "@typescript-eslint/no-unused-vars": [ - "error", - { - varsIgnorePattern: "^_", - argsIgnorePattern: "^_", - destructuredArrayIgnorePattern: "^_", - ignoreRestSiblings: true, - }, - ], - - "no-redeclare": "off", - "@typescript-eslint/no-redeclare": "error", - "no-dupe-class-members": "off", - }, - }, - ...compat - .extends("eslint:recommended", "plugin:jest/recommended") - .map(config => ({ + ...eslintPluginSvelte.configs["flat/recommended"].map(config => { + return { ...config, - files: ["**/*.spec.ts"], - })), + files: ["**/*.svelte"], + + languageOptions: { + parser: svelteParser, + ecmaVersion: 2019, + sourceType: "script", + + parserOptions: { + parser: "@typescript-eslint/parser", + allowImportExportEverywhere: true, + }, + }, + } + }), + ...tseslint.configs.recommended.map(config => { + return { + ...config, + files: ["**/*.ts"], + + languageOptions: { + globals: { + NodeJS: true, + }, + + parser: tsParser, + }, + + rules: { + "prefer-spread": "off", + "no-unused-vars": "off", + "prefer-rest-params": "off", + "local-rules/no-barrel-imports": "error", + "local-rules/no-budibase-imports": "error", + "local-rules/no-console-error": "error", + + "@typescript-eslint/no-this-alias": "off", + "@typescript-eslint/no-unused-expressions": "off", + "@typescript-eslint/no-empty-object-type": "off", + "@typescript-eslint/no-require-imports": "off", + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/no-unused-vars": [ + "error", + { + varsIgnorePattern: "^_", + argsIgnorePattern: "^_", + destructuredArrayIgnorePattern: "^_", + ignoreRestSiblings: true, + caughtErrors: "none", + }, + ], + + "no-redeclare": "off", + "@typescript-eslint/no-redeclare": "error", + "no-dupe-class-members": "off", + }, + } + }), { files: ["**/*.spec.ts"], plugins: { - jest, - "@typescript-eslint": typescriptEslint, + jest: eslintPluginJest, }, languageOptions: { globals: { - ...jest.environments.globals.globals, + ...eslintPluginJest.environments.globals.globals, NodeJS: true, }, @@ -172,18 +148,6 @@ export default [ }, rules: { - "no-unused-vars": "off", - - "@typescript-eslint/no-unused-vars": [ - "error", - { - varsIgnorePattern: "^_", - argsIgnorePattern: "^_", - destructuredArrayIgnorePattern: "^_", - ignoreRestSiblings: true, - }, - ], - "local-rules/no-test-com": "error", "local-rules/email-domain-example-com": "error", "no-console": "warn", diff --git a/package.json b/package.json index ece57f9cba..f95685c6ff 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,6 @@ "@babel/eslint-parser": "7.25.9", "@babel/preset-env": "^7.22.5", "@esbuild-plugins/tsconfig-paths": "^0.1.2", - "@eslint/compat": "^1.2.4", "@types/node": "20.10.0", "@types/proper-lockfile": "^4.1.4", "@typescript-eslint/parser": "8.17.0", @@ -15,7 +14,6 @@ "esbuild": "^0.18.17", "esbuild-node-externals": "^1.14.0", "eslint": "9.16.0", - "eslint-plugin-import": "2.31.0", "eslint-plugin-jest": "28.9.0", "eslint-plugin-local-rules": "3.0.2", "eslint-plugin-svelte": "2.46.1", @@ -28,7 +26,7 @@ "prettier-plugin-svelte": "^2.3.0", "proper-lockfile": "^4.1.2", "svelte": "4.2.19", - "svelte-eslint-parser": "^0.33.1", + "svelte-eslint-parser": "0.43.0", "typescript": "5.7.2", "typescript-eslint": "8.17.0", "yargs": "^17.7.2" diff --git a/packages/backend-core/src/events/publishers/query.ts b/packages/backend-core/src/events/publishers/query.ts index 48603257d2..3bc8ffa5fd 100644 --- a/packages/backend-core/src/events/publishers/query.ts +++ b/packages/backend-core/src/events/publishers/query.ts @@ -12,8 +12,6 @@ import { QueriesRunEvent, } from "@budibase/types" -/* eslint-disable */ - const created = async ( datasource: Datasource, query: Query, diff --git a/packages/backend-core/src/events/publishers/rows.ts b/packages/backend-core/src/events/publishers/rows.ts index 9608613e89..e19681e5fe 100644 --- a/packages/backend-core/src/events/publishers/rows.ts +++ b/packages/backend-core/src/events/publishers/rows.ts @@ -6,8 +6,6 @@ import { Table, } from "@budibase/types" -/* eslint-disable */ - const created = async (count: number, timestamp?: string | number) => { const properties: RowsCreatedEvent = { count, diff --git a/packages/backend-core/src/events/publishers/view.ts b/packages/backend-core/src/events/publishers/view.ts index ccbf960b04..9cc4138ca0 100644 --- a/packages/backend-core/src/events/publishers/view.ts +++ b/packages/backend-core/src/events/publishers/view.ts @@ -17,8 +17,6 @@ import { TableExportFormat, } from "@budibase/types" -/* eslint-disable */ - async function created(view: View, timestamp?: string | number) { const properties: ViewCreatedEvent = { tableId: view.tableId, diff --git a/packages/builder/src/pages/builder/app/[application]/data/_components/CreateExternalDatasourceModal/stores/datasourceCreation.test.js b/packages/builder/src/pages/builder/app/[application]/data/_components/CreateExternalDatasourceModal/stores/datasourceCreation.test.js index 75a3afc2ff..1cb3842c89 100644 --- a/packages/builder/src/pages/builder/app/[application]/data/_components/CreateExternalDatasourceModal/stores/datasourceCreation.test.js +++ b/packages/builder/src/pages/builder/app/[application]/data/_components/CreateExternalDatasourceModal/stores/datasourceCreation.test.js @@ -12,7 +12,6 @@ vi.mock("stores/selectors", () => ({ describe("datasource creation store", () => { beforeEach(ctx => { vi.clearAllMocks() - // eslint-disable-next-line no-import-assign ctx.store = createDatasourceCreationStore() ctx.integration = { data: "integration" } diff --git a/packages/frontend-core/src/components/Updating.svelte b/packages/frontend-core/src/components/Updating.svelte index 97e83e2322..311a6b91c8 100644 --- a/packages/frontend-core/src/components/Updating.svelte +++ b/packages/frontend-core/src/components/Updating.svelte @@ -7,7 +7,6 @@ async function checkMigrationsFinished() { let totalWaitMs = 0 - // eslint-disable-next-line no-constant-condition while (true) { const waitForMs = 5000 + Math.random() * 5000 await new Promise(resolve => setTimeout(resolve, waitForMs)) diff --git a/packages/server/src/api/routes/tests/application.spec.ts b/packages/server/src/api/routes/tests/application.spec.ts index 1511c1aa61..9480593c2a 100644 --- a/packages/server/src/api/routes/tests/application.spec.ts +++ b/packages/server/src/api/routes/tests/application.spec.ts @@ -208,7 +208,7 @@ describe("/applications", () => { it("should reject with a known url", async () => { await config.api.application.create( - { name: "made up", url: app?.url! }, + { name: "made up", url: app!.url! }, { body: { message: "App URL is already in use." }, status: 400 } ) }) diff --git a/packages/server/src/api/routes/tests/search.spec.ts b/packages/server/src/api/routes/tests/search.spec.ts index dd1221d6fb..6aac1d2069 100644 --- a/packages/server/src/api/routes/tests/search.spec.ts +++ b/packages/server/src/api/routes/tests/search.spec.ts @@ -314,9 +314,7 @@ if (descriptions.length) { const cloned = cloneDeep(response) const foundRows = response.rows - // eslint-disable-next-line jest/no-standalone-expect expect(foundRows).toHaveLength(expectedRows.length) - // eslint-disable-next-line jest/no-standalone-expect expect([...foundRows]).toEqual( expectedRows.map((expectedRow: any) => expect.objectContaining(this.popRow(expectedRow, foundRows)) @@ -333,9 +331,7 @@ if (descriptions.length) { const cloned = cloneDeep(response) const foundRows = response.rows - // eslint-disable-next-line jest/no-standalone-expect expect(foundRows).toHaveLength(expectedRows.length) - // eslint-disable-next-line jest/no-standalone-expect expect([...foundRows]).toEqual( expect.arrayContaining( expectedRows.map((expectedRow: any) => @@ -358,10 +354,8 @@ if (descriptions.length) { keyof SearchResponse > for (let key of keys) { - // eslint-disable-next-line jest/no-standalone-expect expect(response[key]).toBeDefined() if (properties[key]) { - // eslint-disable-next-line jest/no-standalone-expect expect(response[key]).toEqual(properties[key]) } } @@ -375,7 +369,6 @@ if (descriptions.length) { const response = await this.performSearch() const cloned = cloneDeep(response) for (let property of properties) { - // eslint-disable-next-line jest/no-standalone-expect expect(response[property]).toBeUndefined() } return cloned @@ -389,7 +382,6 @@ if (descriptions.length) { const cloned = cloneDeep(response) const foundRows = response.rows - // eslint-disable-next-line jest/no-standalone-expect expect([...foundRows]).toEqual( expect.arrayContaining( expectedRows.map((expectedRow: any) => @@ -409,7 +401,6 @@ if (descriptions.length) { async toHaveLength(length: number) { const { rows: foundRows } = await this.performSearch() - // eslint-disable-next-line jest/no-standalone-expect expect(foundRows).toHaveLength(length) } } @@ -2169,7 +2160,6 @@ if (descriptions.length) { let bookmark: string | number = undefined let rows: Row[] = [] - // eslint-disable-next-line no-constant-condition while (true) { const response = await config.api.row.search( tableOrViewId, diff --git a/packages/server/src/integration-test/postgres.spec.ts b/packages/server/src/integration-test/postgres.spec.ts index 4f63579ba1..88250373f8 100644 --- a/packages/server/src/integration-test/postgres.spec.ts +++ b/packages/server/src/integration-test/postgres.spec.ts @@ -107,7 +107,7 @@ if (mainDescriptions.length) { const table = response.datasource.entities?.["binaryTable"] expect(table).toBeDefined() expect(table?.schema.id.externalType).toBe("bytea") - const row = await config.api.row.save(table?._id!, { + const row = await config.api.row.save(table!._id!, { id: "1111", column1: "hello", column2: 222, diff --git a/packages/server/src/integrations/redis.ts b/packages/server/src/integrations/redis.ts index e127cddd56..ff0e1d25c3 100644 --- a/packages/server/src/integrations/redis.ts +++ b/packages/server/src/integrations/redis.ts @@ -129,7 +129,7 @@ class RedisIntegration { return this.client.quit() } - async redisContext(query: Function) { + async redisContext(query: () => Promise) { try { return await query() } catch (err) { diff --git a/packages/server/src/integrations/rest.ts b/packages/server/src/integrations/rest.ts index ce2ec7d545..1b00a18f18 100644 --- a/packages/server/src/integrations/rest.ts +++ b/packages/server/src/integrations/rest.ts @@ -313,7 +313,9 @@ export class RestIntegration implements IntegrationBase { } // Util to add pagination values to a certain body type - const addPaginationToBody = (insertFn: Function) => { + const addPaginationToBody = ( + insertFn: (pageParam: string, page?: string | number) => void + ) => { if (pagination?.location === "body") { if (pagination?.pageParam && paginationValues?.page != null) { insertFn(pagination.pageParam, paginationValues.page) diff --git a/packages/server/src/integrations/tests/googlesheets.spec.ts b/packages/server/src/integrations/tests/googlesheets.spec.ts index 34be1c0c6c..2c0e4dce84 100644 --- a/packages/server/src/integrations/tests/googlesheets.spec.ts +++ b/packages/server/src/integrations/tests/googlesheets.spec.ts @@ -389,7 +389,6 @@ describe("Google Sheets Integration", () => { }) // TODO: this gets the error "Sheet is not large enough to fit 27 columns. Resize the sheet first." - // eslint-disable-next-line jest/no-commented-out-tests // it("should be able to add a new column", async () => { // const updatedTable = await config.api.table.save({ // ...table, diff --git a/packages/server/src/integrations/tests/rest.spec.ts b/packages/server/src/integrations/tests/rest.spec.ts index e869c58875..fac6f58c3b 100644 --- a/packages/server/src/integrations/tests/rest.spec.ts +++ b/packages/server/src/integrations/tests/rest.spec.ts @@ -456,7 +456,6 @@ describe("REST Integration", () => { // node-fetch >=3, and we're not on that because upgrading to it produces errors to // do with ESM that are above my pay grade. - // eslint-disable-next-line jest/no-commented-out-tests // it("doesn't fail when legacyHttpParser is set", async () => { // const server = createServer((req, res) => { // res.writeHead(200, { diff --git a/packages/server/src/integrations/tests/sqlAlias.spec.ts b/packages/server/src/integrations/tests/sqlAlias.spec.ts index 0f43e41755..3d67a7aa41 100644 --- a/packages/server/src/integrations/tests/sqlAlias.spec.ts +++ b/packages/server/src/integrations/tests/sqlAlias.spec.ts @@ -144,10 +144,10 @@ describe("Captures of real examples", () => { queryJson ) const filters = queryJson.filters - const notEqualsValue = Object.values(filters?.notEqual!)[0] + const notEqualsValue = Object.values(filters!.notEqual!)[0] const rangeValue: { high?: string | number; low?: string | number } = - Object.values(filters?.range!)[0] - const equalValue = Object.values(filters?.equal!)[0] + Object.values(filters!.range!)[0] + const equalValue = Object.values(filters!.equal!)[0] expect(query).toEqual({ bindings: [ diff --git a/packages/server/src/jsRunner/vm/isolated-vm.ts b/packages/server/src/jsRunner/vm/isolated-vm.ts index b8ed90aa23..3863be742d 100644 --- a/packages/server/src/jsRunner/vm/isolated-vm.ts +++ b/packages/server/src/jsRunner/vm/isolated-vm.ts @@ -72,7 +72,7 @@ export class IsolatedVM implements VM { this.addToContext({ helpersStripProtocol: new ivm.Callback((str: string) => { - var parsed = url.parse(str) as any + let parsed = url.parse(str) as any parsed.protocol = "" return parsed.format() }), diff --git a/packages/server/src/middleware/builder.ts b/packages/server/src/middleware/builder.ts index 87c7eef51f..bc775991df 100644 --- a/packages/server/src/middleware/builder.ts +++ b/packages/server/src/middleware/builder.ts @@ -50,7 +50,7 @@ async function updateAppUpdatedAt(ctx: UserCtx) { const metadata = await db.get(DocumentType.APP_METADATA) metadata.updatedAt = new Date().toISOString() - metadata.updatedBy = getGlobalIDFromUserMetadataID(ctx.user?.userId!) + metadata.updatedBy = getGlobalIDFromUserMetadataID(ctx.user!.userId!) const response = await db.put(metadata) metadata._rev = response.rev diff --git a/packages/server/src/migrations/functions/usageQuotas/index.ts b/packages/server/src/migrations/functions/usageQuotas/index.ts index ed1a765551..e94e993b21 100644 --- a/packages/server/src/migrations/functions/usageQuotas/index.ts +++ b/packages/server/src/migrations/functions/usageQuotas/index.ts @@ -1,3 +1,3 @@ -export const runQuotaMigration = async (migration: Function) => { +export const runQuotaMigration = async (migration: () => Promise) => { await migration() } diff --git a/packages/server/src/startup/tests/startup.spec.ts b/packages/server/src/startup/tests/startup.spec.ts index 7209033db8..ffc29655e1 100644 --- a/packages/server/src/startup/tests/startup.spec.ts +++ b/packages/server/src/startup/tests/startup.spec.ts @@ -47,7 +47,7 @@ describe("check BB_ADMIN environment variables", () => { }) expect(user).toBeDefined() expect(user?.password).toBeDefined() - expect(await utils.compare(PASSWORD, user?.password!)).toEqual( + expect(await utils.compare(PASSWORD, user!.password!)).toEqual( true ) } diff --git a/packages/server/src/utilities/global.ts b/packages/server/src/utilities/global.ts index c1fcf35634..975dfbded5 100644 --- a/packages/server/src/utilities/global.ts +++ b/packages/server/src/utilities/global.ts @@ -78,7 +78,7 @@ export async function getCachedSelf( // this has to be tenant aware, can't depend on the context to find it out // running some middlewares before the tenancy causes context to break const user = await cache.user.getUser({ - userId: ctx.user?._id!, + userId: ctx.user!._id!, }) return processUser(user, { appId }) } diff --git a/packages/server/src/websockets/builder.ts b/packages/server/src/websockets/builder.ts index cf92d68ef3..c4a8ca2955 100644 --- a/packages/server/src/websockets/builder.ts +++ b/packages/server/src/websockets/builder.ts @@ -92,7 +92,7 @@ export default class BuilderSocket extends BaseSocket { } } - async updateUser(socket: Socket, patch: Object) { + async updateUser(socket: Socket, patch: object) { await super.updateUser(socket, { builderMetadata: { ...socket.data.builderMetadata, diff --git a/packages/server/src/websockets/grid.ts b/packages/server/src/websockets/grid.ts index 3911313cc3..661d47cb6d 100644 --- a/packages/server/src/websockets/grid.ts +++ b/packages/server/src/websockets/grid.ts @@ -70,7 +70,7 @@ export default class GridSocket extends BaseSocket { }) } - async updateUser(socket: Socket, patch: Object) { + async updateUser(socket: Socket, patch: object) { await super.updateUser(socket, { gridMetadata: { ...socket.data.gridMetadata, diff --git a/packages/server/src/websockets/middleware.ts b/packages/server/src/websockets/middleware.ts index 0a52dcbdeb..7962149cd8 100644 --- a/packages/server/src/websockets/middleware.ts +++ b/packages/server/src/websockets/middleware.ts @@ -58,7 +58,7 @@ export const createContext = ( export const runMiddlewares = async ( ctx: any, middlewares: any[], - callback: Function + callback: () => Promise ) => { if (!middlewares[0]) { await callback() diff --git a/packages/server/src/websockets/websocket.ts b/packages/server/src/websockets/websocket.ts index 5dcf8c8f6f..2f031a72d9 100644 --- a/packages/server/src/websockets/websocket.ts +++ b/packages/server/src/websockets/websocket.ts @@ -250,7 +250,7 @@ export class BaseSocket { } // Updates a connected user's metadata, assuming a room change is not required. - async updateUser(socket: Socket, patch: Object) { + async updateUser(socket: Socket, patch: object) { socket.data = { ...socket.data, ...patch, diff --git a/packages/types/src/sdk/migrations.ts b/packages/types/src/sdk/migrations.ts index 0692b27f8e..f2b0ed48e3 100644 --- a/packages/types/src/sdk/migrations.ts +++ b/packages/types/src/sdk/migrations.ts @@ -1,6 +1,6 @@ export interface Migration extends MigrationDefinition { appOpts?: object - fn: Function + fn: () => void silent?: boolean preventRetry?: boolean } diff --git a/packages/worker/src/api/routes/global/tests/auth.spec.ts b/packages/worker/src/api/routes/global/tests/auth.spec.ts index f6bdd7f663..bff959469e 100644 --- a/packages/worker/src/api/routes/global/tests/auth.spec.ts +++ b/packages/worker/src/api/routes/global/tests/auth.spec.ts @@ -54,7 +54,7 @@ describe("/api/global/auth", () => { describe("POST /api/global/auth/:tenantId/login", () => { it("logs in with correct credentials", async () => { const tenantId = config.tenantId! - const email = config.user?.email! + const email = config.user!.email! const password = config.userPassword const response = await config.api.auth.login(tenantId, email, password) @@ -65,7 +65,7 @@ describe("/api/global/auth", () => { it("should return 403 with incorrect credentials", async () => { const tenantId = config.tenantId! - const email = config.user?.email! + const email = config.user!.email! const password = "incorrect123" const response = await config.api.auth.login( diff --git a/packages/worker/src/api/routes/global/tests/users.spec.ts b/packages/worker/src/api/routes/global/tests/users.spec.ts index b6237c7b4b..239877b71a 100644 --- a/packages/worker/src/api/routes/global/tests/users.spec.ts +++ b/packages/worker/src/api/routes/global/tests/users.spec.ts @@ -343,7 +343,7 @@ describe("/api/global/users", () => { }) it("should not allow a user to update their own admin/builder status", async () => { - const user = (await config.api.users.getUser(config.user?._id!)) + const user = (await config.api.users.getUser(config.user!._id!)) .body as User await config.api.users.saveUser({ ...user, diff --git a/packages/worker/src/middleware/handleScimBody.ts b/packages/worker/src/middleware/handleScimBody.ts index bfcd6dfcf2..07e6286b6b 100644 --- a/packages/worker/src/middleware/handleScimBody.ts +++ b/packages/worker/src/middleware/handleScimBody.ts @@ -1,7 +1,7 @@ import { Ctx } from "@budibase/types" export const handleScimBody = (ctx: Ctx, next: any) => { - var type = ctx.req.headers["content-type"] || "" + let type = ctx.req.headers["content-type"] || "" type = type.split(";")[0] if (type === "application/scim+json") { diff --git a/packages/worker/src/tests/api/email.ts b/packages/worker/src/tests/api/email.ts index dc464ba16d..b2f30e6ac1 100644 --- a/packages/worker/src/tests/api/email.ts +++ b/packages/worker/src/tests/api/email.ts @@ -15,7 +15,7 @@ export class EmailAPI extends TestAPI { attachments, purpose, tenantId: this.config.getTenantId(), - userId: this.config.user?._id!, + userId: this.config.user!._id!, }) .set(this.config.defaultHeaders()) .expect("Content-Type", /json/) diff --git a/yarn.lock b/yarn.lock index 4988e5237d..4b4ab5146f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2675,11 +2675,6 @@ resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== -"@eslint/compat@^1.2.4": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@eslint/compat/-/compat-1.2.4.tgz#b69b0d76ce73fe66d7f8633c406acea151f5c559" - integrity sha512-S8ZdQj/N69YAtuqFt7653jwcvuUj131+6qGLUyDqfDg1OIoBQ66OCuXC473YQfO2AaxITTutiRQiDwoo7ZLYyg== - "@eslint/config-array@^0.19.0": version "0.19.1" resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.1.tgz#734aaea2c40be22bbb1f2a9dac687c57a6a4c984" @@ -4313,11 +4308,6 @@ node-fetch "^2.6.0" utf-8-validate "^5.0.2" -"@rtsao/scc@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" - integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g== - "@shopify/jest-koa-mocks@5.1.1": version "5.1.1" resolved "https://registry.yarnpkg.com/@shopify/jest-koa-mocks/-/jest-koa-mocks-5.1.1.tgz#d615815b0cf0ec9823d054da68c419508b3c3193" @@ -7026,18 +7016,6 @@ array-includes@^3.1.7: get-intrinsic "^1.2.1" is-string "^1.0.7" -array-includes@^3.1.8: - version "3.1.8" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.8.tgz#5e370cbe172fdd5dd6530c1d4aadda25281ba97d" - integrity sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.2" - es-object-atoms "^1.0.0" - get-intrinsic "^1.2.4" - is-string "^1.0.7" - array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -7059,18 +7037,6 @@ array.prototype.findlastindex@^1.2.3: es-shim-unscopables "^1.0.0" get-intrinsic "^1.2.1" -array.prototype.findlastindex@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz#8c35a755c72908719453f87145ca011e39334d0d" - integrity sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.2" - es-errors "^1.3.0" - es-object-atoms "^1.0.0" - es-shim-unscopables "^1.0.2" - array.prototype.flat@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" @@ -10167,7 +10133,7 @@ es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0: unbox-primitive "^1.0.2" which-typed-array "^1.1.15" -es-abstract@^1.23.2, es-abstract@^1.23.3: +es-abstract@^1.23.3: version "1.23.5" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.5.tgz#f4599a4946d57ed467515ed10e4f157289cd52fb" integrity sha512-vlmniQ0WNPwXqA0BnmwV3Ng7HxiGlh6r5U6JcTMNx8OilcAGqVJBHJcPjqOMaczU9fRuRK5Px2BdVyPRnKMMVQ== @@ -10262,7 +10228,7 @@ es-set-tostringtag@^2.0.3: has-tostringtag "^1.0.2" hasown "^2.0.1" -es-shim-unscopables@^1.0.0, es-shim-unscopables@^1.0.2: +es-shim-unscopables@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== @@ -10396,13 +10362,6 @@ eslint-import-resolver-node@^0.3.9: is-core-module "^2.13.0" resolve "^1.22.4" -eslint-module-utils@^2.12.0: - version "2.12.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz#fe4cfb948d61f49203d7b08871982b65b9af0b0b" - integrity sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg== - dependencies: - debug "^3.2.7" - eslint-module-utils@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" @@ -10410,31 +10369,6 @@ eslint-module-utils@^2.8.0: dependencies: debug "^3.2.7" -eslint-plugin-import@2.31.0: - version "2.31.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz#310ce7e720ca1d9c0bb3f69adfd1c6bdd7d9e0e7" - integrity sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A== - dependencies: - "@rtsao/scc" "^1.1.0" - array-includes "^3.1.8" - array.prototype.findlastindex "^1.2.5" - array.prototype.flat "^1.3.2" - array.prototype.flatmap "^1.3.2" - debug "^3.2.7" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.9" - eslint-module-utils "^2.12.0" - hasown "^2.0.2" - is-core-module "^2.15.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.fromentries "^2.0.8" - object.groupby "^1.0.3" - object.values "^1.2.0" - semver "^6.3.1" - string.prototype.trimend "^1.0.8" - tsconfig-paths "^3.15.0" - eslint-plugin-import@^2.26.0: version "2.29.1" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" @@ -10495,7 +10429,7 @@ eslint-scope@5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-scope@^7.0.0, eslint-scope@^7.2.2: +eslint-scope@^7.2.2: version "7.2.2" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== @@ -10516,7 +10450,7 @@ eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== @@ -10624,7 +10558,7 @@ espree@^10.0.1, espree@^10.3.0: acorn-jsx "^5.3.2" eslint-visitor-keys "^4.2.0" -espree@^9.0.0, espree@^9.6.0, espree@^9.6.1: +espree@^9.6.0, espree@^9.6.1: version "9.6.1" resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== @@ -12811,7 +12745,7 @@ is-class-hotfix@~0.0.6: resolved "https://registry.yarnpkg.com/is-class-hotfix/-/is-class-hotfix-0.0.6.tgz#a527d31fb23279281dde5f385c77b5de70a72435" integrity sha512-0n+pzCC6ICtVr/WXnN2f03TK/3BfXY7me4cjCAqT8TYXEl0+JBRoqBo94JJHXcyDSLUeWbNX8Fvy5g5RJdAstQ== -is-core-module@^2.12.0, is-core-module@^2.15.1: +is-core-module@^2.12.0: version "2.15.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37" integrity sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ== @@ -16338,16 +16272,6 @@ object.fromentries@^2.0.7: define-properties "^1.2.0" es-abstract "^1.22.1" -object.fromentries@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.8.tgz#f7195d8a9b97bd95cbc1999ea939ecd1a2b00c65" - integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.2" - es-object-atoms "^1.0.0" - object.groupby@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" @@ -16358,15 +16282,6 @@ object.groupby@^1.0.1: es-abstract "^1.22.1" get-intrinsic "^1.2.1" -object.groupby@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.3.tgz#9b125c36238129f6f7b61954a1e7176148d5002e" - integrity sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.2" - object.values@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" @@ -16376,15 +16291,6 @@ object.values@^1.1.7: define-properties "^1.2.0" es-abstract "^1.22.1" -object.values@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.0.tgz#65405a9d92cee68ac2d303002e0b8470a4d9ab1b" - integrity sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-object-atoms "^1.0.0" - octal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/octal/-/octal-1.0.0.tgz#63e7162a68efbeb9e213588d58e989d1e5c4530b" @@ -17336,7 +17242,7 @@ postcss-safe-parser@^6.0.0: resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz#bb4c29894171a94bc5c996b9a30317ef402adaa1" integrity sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ== -postcss-scss@^4.0.8, postcss-scss@^4.0.9: +postcss-scss@^4.0.9: version "4.0.9" resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-4.0.9.tgz#a03c773cd4c9623cb04ce142a52afcec74806685" integrity sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A== @@ -17367,7 +17273,7 @@ postcss-values-parser@^6.0.2: is-url-superb "^4.0.0" quote-unquote "^1.0.0" -postcss@^8.1.7, postcss@^8.3.11, postcss@^8.4.12, postcss@^8.4.27, postcss@^8.4.29: +postcss@^8.1.7, postcss@^8.3.11, postcss@^8.4.12, postcss@^8.4.27: version "8.4.41" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.41.tgz#d6104d3ba272d882fe18fc07d15dc2da62fa2681" integrity sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ== @@ -19960,18 +19866,7 @@ svelte-dnd-action@^0.9.8: resolved "https://registry.yarnpkg.com/svelte-dnd-action/-/svelte-dnd-action-0.9.22.tgz#003eee9dddb31d8c782f6832aec8b1507fff194d" integrity sha512-lOQJsNLM1QWv5mdxIkCVtk6k4lHCtLgfE59y8rs7iOM6erchbLC9hMEFYSveZz7biJV0mpg7yDSs4bj/RT/YkA== -svelte-eslint-parser@^0.33.1: - version "0.33.1" - resolved "https://registry.yarnpkg.com/svelte-eslint-parser/-/svelte-eslint-parser-0.33.1.tgz#c64dbed2fad099577429b3c39377f6b8d36e5d97" - integrity sha512-vo7xPGTlKBGdLH8T5L64FipvTrqv3OQRx9d2z5X05KKZDlF4rQk8KViZO4flKERY+5BiVdOh7zZ7JGJWo5P0uA== - dependencies: - eslint-scope "^7.0.0" - eslint-visitor-keys "^3.0.0" - espree "^9.0.0" - postcss "^8.4.29" - postcss-scss "^4.0.8" - -svelte-eslint-parser@^0.43.0: +svelte-eslint-parser@0.43.0, svelte-eslint-parser@^0.43.0: version "0.43.0" resolved "https://registry.yarnpkg.com/svelte-eslint-parser/-/svelte-eslint-parser-0.43.0.tgz#649e80f65183c4c1d1536d03dcb903e0632f4da4" integrity sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA== From 8f165d5b684c564514f17b4c42cd9a51ada82d4b Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Fri, 6 Dec 2024 17:02:49 +0000 Subject: [PATCH 05/22] types --- .../processors/posthog/PosthogProcessor.ts | 2 -- .../src/events/publishers/view.ts | 1 - .../server/src/api/controllers/view/views.ts | 21 ------------------- .../functions/backfill/app/tables.ts | 18 ---------------- packages/server/src/sdk/app/views/external.ts | 4 ++-- packages/server/src/sdk/app/views/internal.ts | 2 +- 6 files changed, 3 insertions(+), 45 deletions(-) diff --git a/packages/backend-core/src/events/processors/posthog/PosthogProcessor.ts b/packages/backend-core/src/events/processors/posthog/PosthogProcessor.ts index 687fe54256..4700b47be2 100644 --- a/packages/backend-core/src/events/processors/posthog/PosthogProcessor.ts +++ b/packages/backend-core/src/events/processors/posthog/PosthogProcessor.ts @@ -13,8 +13,6 @@ const EXCLUDED_EVENTS: Event[] = [ Event.ROLE_UPDATED, Event.DATASOURCE_UPDATED, Event.QUERY_UPDATED, - // Event.TABLE_UPDATED, - // Event.VIEW_UPDATED, Event.VIEW_FILTER_UPDATED, Event.VIEW_CALCULATION_UPDATED, Event.AUTOMATION_TRIGGER_UPDATED, diff --git a/packages/backend-core/src/events/publishers/view.ts b/packages/backend-core/src/events/publishers/view.ts index 6d107d58f3..3097ae4cfa 100644 --- a/packages/backend-core/src/events/publishers/view.ts +++ b/packages/backend-core/src/events/publishers/view.ts @@ -30,7 +30,6 @@ async function created(view: ViewV2, timestamp?: string | number) { } async function updated(newView: ViewV2) { - // // check whether any of the fields are different let viewJoins = 0 for (const key in newView.schema) { if (newView.schema[key]?.columns) { diff --git a/packages/server/src/api/controllers/view/views.ts b/packages/server/src/api/controllers/view/views.ts index f1aa219aca..9fdd808d38 100644 --- a/packages/server/src/api/controllers/view/views.ts +++ b/packages/server/src/api/controllers/view/views.ts @@ -65,27 +65,6 @@ export async function save(ctx: Ctx) { builderSocket?.emitTableUpdate(ctx, table) } -// export async function calculationEvents(existingView: View, newView: View) { -// const existingCalculation = existingView && existingView.calculation -// const newCalculation = newView && newView.calculation -// -// if (existingCalculation && !newCalculation) { -// await events.view.calculationDeleted(existingView) -// } -// -// if (!existingCalculation && newCalculation) { -// await events.view.calculationCreated(newView) -// } -// -// if ( -// existingCalculation && -// newCalculation && -// existingCalculation !== newCalculation -// ) { -// await events.view.calculationUpdated(newView) -// } -// } - export async function filterEvents(existingView: View, newView: View) { const hasExistingFilters = !!( existingView && diff --git a/packages/server/src/migrations/functions/backfill/app/tables.ts b/packages/server/src/migrations/functions/backfill/app/tables.ts index c6e46173dc..e8437bd529 100644 --- a/packages/server/src/migrations/functions/backfill/app/tables.ts +++ b/packages/server/src/migrations/functions/backfill/app/tables.ts @@ -7,24 +7,6 @@ export const backfill = async (appDb: Database, timestamp: string | number) => { for (const table of tables) { await events.table.created(table, timestamp) - - if (table.views) { - for (const view of Object.values(table.views)) { - if (sdk.views.isV2(view)) { - continue - } - - // await events.view.created(view, timestamp) - - if (view.calculation) { - await events.view.calculationCreated(view, timestamp) - } - - if (view.filters?.length) { - await events.view.filterCreated(view, timestamp) - } - } - } } return tables.length diff --git a/packages/server/src/sdk/app/views/external.ts b/packages/server/src/sdk/app/views/external.ts index 9016a3bd61..65e0ff410d 100644 --- a/packages/server/src/sdk/app/views/external.ts +++ b/packages/server/src/sdk/app/views/external.ts @@ -63,7 +63,7 @@ export async function create( export async function update( tableId: string, view: Readonly -): Promise<{ view: ViewV2; existingView: ViewV2 }> { +): Promise<{ view: Readonly; existingView: ViewV2 }> { const db = context.getAppDB() const { datasourceId, tableName } = breakExternalTableId(tableId) @@ -87,7 +87,7 @@ export async function update( delete views[existingView.name] views[view.name] = view await db.put(ds) - return { view, existingView } + return { view, existingView } as { view: ViewV2; existingView: ViewV2 } } export async function remove(viewId: string): Promise { diff --git a/packages/server/src/sdk/app/views/internal.ts b/packages/server/src/sdk/app/views/internal.ts index ec152abe54..4f7abad357 100644 --- a/packages/server/src/sdk/app/views/internal.ts +++ b/packages/server/src/sdk/app/views/internal.ts @@ -76,7 +76,7 @@ export async function update( delete table.views[existingView.name] table.views[view.name] = view await db.put(table) - return { view, existingView } + return { view, existingView } as { view: ViewV2; existingView: ViewV2 } } export async function remove(viewId: string): Promise { From 492d5a37f28a8ed88eae084f8897d9c50f0baf94 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Fri, 6 Dec 2024 19:44:35 +0000 Subject: [PATCH 06/22] fix table tests --- packages/server/src/api/routes/tests/table.spec.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index 8556a598c6..393fa8260c 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -247,6 +247,8 @@ if (descriptions.length) { }, }, }, + views: {}, + sql: true }) ) @@ -254,9 +256,8 @@ if (descriptions.length) { ...table, name: generator.guid(), }) - expect(events.table.updated).toHaveBeenCalledTimes(1) - expect(events.table.updated).toHaveBeenCalledWith(updatedTable) + expect(events.table.updated).toHaveBeenCalledWith(table, updatedTable) }) it("updates all the row fields for a table when a schema key is renamed", async () => { From fb5f32da23d72857649bb452df6a77920208bf1d Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Fri, 6 Dec 2024 20:08:42 +0000 Subject: [PATCH 07/22] remove view events from v1 tests --- .../server/src/api/routes/tests/view.spec.ts | 51 ------------------- 1 file changed, 51 deletions(-) diff --git a/packages/server/src/api/routes/tests/view.spec.ts b/packages/server/src/api/routes/tests/view.spec.ts index 57b589e79d..2217116f2d 100644 --- a/packages/server/src/api/routes/tests/view.spec.ts +++ b/packages/server/src/api/routes/tests/view.spec.ts @@ -84,14 +84,6 @@ describe("/views", () => { const view = await saveView({ calculation: ViewCalculation.COUNT }) expect(view.tableId).toBe(table._id) - expect(events.view.created).toHaveBeenCalledTimes(1) - expect(events.view.updated).not.toHaveBeenCalled() - expect(events.view.calculationCreated).toHaveBeenCalledTimes(1) - expect(events.view.calculationUpdated).not.toHaveBeenCalled() - expect(events.view.calculationDeleted).not.toHaveBeenCalled() - expect(events.view.filterCreated).not.toHaveBeenCalled() - expect(events.view.filterUpdated).not.toHaveBeenCalled() - expect(events.view.filterDeleted).not.toHaveBeenCalled() }) it("creates a view with a filter", async () => { @@ -109,14 +101,6 @@ describe("/views", () => { }) expect(view.tableId).toBe(table._id) - expect(events.view.created).toHaveBeenCalledTimes(1) - expect(events.view.updated).not.toHaveBeenCalled() - expect(events.view.calculationCreated).not.toHaveBeenCalled() - expect(events.view.calculationUpdated).not.toHaveBeenCalled() - expect(events.view.calculationDeleted).not.toHaveBeenCalled() - expect(events.view.filterCreated).toHaveBeenCalledTimes(1) - expect(events.view.filterUpdated).not.toHaveBeenCalled() - expect(events.view.filterDeleted).not.toHaveBeenCalled() }) it("updates the table row with the new view metadata", async () => { @@ -166,13 +150,6 @@ describe("/views", () => { await saveView() expect(events.view.created).not.toHaveBeenCalled() - expect(events.view.updated).toHaveBeenCalledTimes(1) - expect(events.view.calculationCreated).not.toHaveBeenCalled() - expect(events.view.calculationUpdated).not.toHaveBeenCalled() - expect(events.view.calculationDeleted).not.toHaveBeenCalled() - expect(events.view.filterCreated).not.toHaveBeenCalled() - expect(events.view.filterUpdated).not.toHaveBeenCalled() - expect(events.view.filterDeleted).not.toHaveBeenCalled() }) it("updates a view calculation", async () => { @@ -182,13 +159,6 @@ describe("/views", () => { await saveView({ calculation: ViewCalculation.COUNT }) expect(events.view.created).not.toHaveBeenCalled() - expect(events.view.updated).toHaveBeenCalledTimes(1) - expect(events.view.calculationCreated).not.toHaveBeenCalled() - expect(events.view.calculationUpdated).toHaveBeenCalledTimes(1) - expect(events.view.calculationDeleted).not.toHaveBeenCalled() - expect(events.view.filterCreated).not.toHaveBeenCalled() - expect(events.view.filterUpdated).not.toHaveBeenCalled() - expect(events.view.filterDeleted).not.toHaveBeenCalled() }) it("deletes a view calculation", async () => { @@ -198,13 +168,6 @@ describe("/views", () => { await saveView({ calculation: undefined }) expect(events.view.created).not.toHaveBeenCalled() - expect(events.view.updated).toHaveBeenCalledTimes(1) - expect(events.view.calculationCreated).not.toHaveBeenCalled() - expect(events.view.calculationUpdated).not.toHaveBeenCalled() - expect(events.view.calculationDeleted).toHaveBeenCalledTimes(1) - expect(events.view.filterCreated).not.toHaveBeenCalled() - expect(events.view.filterUpdated).not.toHaveBeenCalled() - expect(events.view.filterDeleted).not.toHaveBeenCalled() }) it("updates a view filter", async () => { @@ -230,13 +193,6 @@ describe("/views", () => { }) expect(events.view.created).not.toHaveBeenCalled() - expect(events.view.updated).toHaveBeenCalledTimes(1) - expect(events.view.calculationCreated).not.toHaveBeenCalled() - expect(events.view.calculationUpdated).not.toHaveBeenCalled() - expect(events.view.calculationDeleted).not.toHaveBeenCalled() - expect(events.view.filterCreated).not.toHaveBeenCalled() - expect(events.view.filterUpdated).toHaveBeenCalledTimes(1) - expect(events.view.filterDeleted).not.toHaveBeenCalled() }) it("deletes a view filter", async () => { @@ -254,13 +210,6 @@ describe("/views", () => { await saveView({ filters: [] }) expect(events.view.created).not.toHaveBeenCalled() - expect(events.view.updated).toHaveBeenCalledTimes(1) - expect(events.view.calculationCreated).not.toHaveBeenCalled() - expect(events.view.calculationUpdated).not.toHaveBeenCalled() - expect(events.view.calculationDeleted).not.toHaveBeenCalled() - expect(events.view.filterCreated).not.toHaveBeenCalled() - expect(events.view.filterUpdated).not.toHaveBeenCalled() - expect(events.view.filterDeleted).toHaveBeenCalledTimes(1) }) }) From 41c1632d60f8551bf8f1638856e42a47cce7f004 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Fri, 6 Dec 2024 20:09:18 +0000 Subject: [PATCH 08/22] lint --- packages/server/src/api/routes/tests/table.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index 393fa8260c..39b6a68eaf 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -248,7 +248,7 @@ if (descriptions.length) { }, }, views: {}, - sql: true + sql: true, }) ) From 917c23529546299a4b519a0d12e3aea2eea764d8 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Sun, 8 Dec 2024 23:18:07 +0000 Subject: [PATCH 09/22] send individual events for view calcs and joins --- .../processors/posthog/PosthogProcessor.ts | 1 + .../src/events/publishers/rowAction.ts | 2 +- .../src/events/publishers/view.ts | 61 ++++++++++++------- .../tests/core/utilities/mocks/events.ts | 1 + .../server/src/api/controllers/view/views.ts | 25 -------- .../src/api/controllers/view/viewsV2.ts | 58 +++++++++++++++++- .../src/api/routes/tests/viewV2.spec.ts | 9 ++- packages/types/src/sdk/events/event.ts | 8 +++ packages/types/src/sdk/events/view.ts | 12 ++-- 9 files changed, 124 insertions(+), 53 deletions(-) diff --git a/packages/backend-core/src/events/processors/posthog/PosthogProcessor.ts b/packages/backend-core/src/events/processors/posthog/PosthogProcessor.ts index 4700b47be2..e8e8f35d6d 100644 --- a/packages/backend-core/src/events/processors/posthog/PosthogProcessor.ts +++ b/packages/backend-core/src/events/processors/posthog/PosthogProcessor.ts @@ -13,6 +13,7 @@ const EXCLUDED_EVENTS: Event[] = [ Event.ROLE_UPDATED, Event.DATASOURCE_UPDATED, Event.QUERY_UPDATED, + Event.VIEW_UPDATED, Event.VIEW_FILTER_UPDATED, Event.VIEW_CALCULATION_UPDATED, Event.AUTOMATION_TRIGGER_UPDATED, diff --git a/packages/backend-core/src/events/publishers/rowAction.ts b/packages/backend-core/src/events/publishers/rowAction.ts index 5adfd22d2d..eac35cc489 100644 --- a/packages/backend-core/src/events/publishers/rowAction.ts +++ b/packages/backend-core/src/events/publishers/rowAction.ts @@ -5,7 +5,7 @@ async function created( rowAction: RowActionCreatedEvent, timestamp?: string | number ) { - await publishEvent(Event.TABLE_CREATED, rowAction, timestamp) + await publishEvent(Event.ROW_ACTION_CREATED, rowAction, timestamp) } export default { diff --git a/packages/backend-core/src/events/publishers/view.ts b/packages/backend-core/src/events/publishers/view.ts index 3097ae4cfa..3ce24e9a0a 100644 --- a/packages/backend-core/src/events/publishers/view.ts +++ b/packages/backend-core/src/events/publishers/view.ts @@ -1,6 +1,11 @@ import { publishEvent } from "../events" import { + CalculationType, Event, + Table, + TableExportFormat, + View, + ViewCalculation, ViewCalculationCreatedEvent, ViewCalculationDeletedEvent, ViewCalculationUpdatedEvent, @@ -11,11 +16,8 @@ import { ViewFilterDeletedEvent, ViewFilterUpdatedEvent, ViewUpdatedEvent, - View, ViewV2, - ViewCalculation, - Table, - TableExportFormat, + ViewJoinCreatedEvent, } from "@budibase/types" /* eslint-disable */ @@ -29,17 +31,9 @@ async function created(view: ViewV2, timestamp?: string | number) { await publishEvent(Event.VIEW_CREATED, properties, timestamp) } -async function updated(newView: ViewV2) { - let viewJoins = 0 - for (const key in newView.schema) { - if (newView.schema[key]?.columns) { - viewJoins += Object.keys(newView.schema[key]?.columns).length - } - } +async function updated(view: ViewV2) { const properties: ViewUpdatedEvent = { - tableId: newView.tableId, - groupedFilters: newView.queryUI?.groups?.length || 0, - viewJoins, + tableId: view.tableId, } await publishEvent(Event.VIEW_UPDATED, properties) } @@ -59,16 +53,27 @@ async function exported(table: Table, format: TableExportFormat) { await publishEvent(Event.VIEW_EXPORTED, properties) } -async function filterCreated(view: View, timestamp?: string | number) { +async function filterCreated( + { tableId, filterGroups }: { tableId: string; filterGroups: number }, + timestamp?: string | number +) { const properties: ViewFilterCreatedEvent = { - tableId: view.tableId, + tableId, + filterGroups, } await publishEvent(Event.VIEW_FILTER_CREATED, properties, timestamp) } -async function filterUpdated(view: View) { +async function filterUpdated({ + tableId, + filterGroups, +}: { + tableId: string + filterGroups: number +}) { const properties: ViewFilterUpdatedEvent = { - tableId: view.tableId, + tableId: tableId, + filterGroups, } await publishEvent(Event.VIEW_FILTER_UPDATED, properties) } @@ -80,10 +85,16 @@ async function filterDeleted(view: View) { await publishEvent(Event.VIEW_FILTER_DELETED, properties) } -async function calculationCreated(view: View, timestamp?: string | number) { +async function calculationCreated( + { + tableId, + calculationType, + }: { tableId: string; calculationType: CalculationType }, + timestamp?: string | number +) { const properties: ViewCalculationCreatedEvent = { - tableId: view.tableId, - calculation: view.calculation as ViewCalculation, + tableId, + calculation: calculationType, } await publishEvent(Event.VIEW_CALCULATION_CREATED, properties, timestamp) } @@ -104,6 +115,13 @@ async function calculationDeleted(existingView: View) { await publishEvent(Event.VIEW_CALCULATION_DELETED, properties) } +async function viewJoinCreated(tableId: any, timestamp?: string | number) { + const properties: ViewJoinCreatedEvent = { + tableId, + } + await publishEvent(Event.VIEW_JOIN_CREATED, properties, timestamp) +} + export default { created, updated, @@ -115,4 +133,5 @@ export default { calculationCreated, calculationUpdated, calculationDeleted, + viewJoinCreated, } diff --git a/packages/backend-core/tests/core/utilities/mocks/events.ts b/packages/backend-core/tests/core/utilities/mocks/events.ts index 96f351de10..433986352e 100644 --- a/packages/backend-core/tests/core/utilities/mocks/events.ts +++ b/packages/backend-core/tests/core/utilities/mocks/events.ts @@ -117,6 +117,7 @@ beforeAll(async () => { jest.spyOn(events.view, "calculationCreated") jest.spyOn(events.view, "calculationUpdated") jest.spyOn(events.view, "calculationDeleted") + jest.spyOn(events.view, "viewJoinCreated") jest.spyOn(events.plugin, "init") jest.spyOn(events.plugin, "imported") diff --git a/packages/server/src/api/controllers/view/views.ts b/packages/server/src/api/controllers/view/views.ts index 9fdd808d38..0626f4e55c 100644 --- a/packages/server/src/api/controllers/view/views.ts +++ b/packages/server/src/api/controllers/view/views.ts @@ -65,31 +65,6 @@ export async function save(ctx: Ctx) { builderSocket?.emitTableUpdate(ctx, table) } -export async function filterEvents(existingView: View, newView: View) { - const hasExistingFilters = !!( - existingView && - existingView.filters && - existingView.filters.length - ) - const hasNewFilters = !!(newView && newView.filters && newView.filters.length) - - if (hasExistingFilters && !hasNewFilters) { - await events.view.filterDeleted(newView) - } - - if (!hasExistingFilters && hasNewFilters) { - await events.view.filterCreated(newView) - } - - if ( - hasExistingFilters && - hasNewFilters && - !isEqual(existingView.filters, newView.filters) - ) { - await events.view.filterUpdated(newView) - } -} - export async function destroy(ctx: Ctx) { const db = context.getAppDB() const viewName = decodeURIComponent(ctx.params.viewName) diff --git a/packages/server/src/api/controllers/view/viewsV2.ts b/packages/server/src/api/controllers/view/viewsV2.ts index 497a880fab..e611df0de3 100644 --- a/packages/server/src/api/controllers/view/viewsV2.ts +++ b/packages/server/src/api/controllers/view/viewsV2.ts @@ -16,10 +16,14 @@ import { CountCalculationFieldMetadata, CreateViewResponse, UpdateViewResponse, + View, + Event, } from "@budibase/types" import { events } from "@budibase/backend-core" import { builderSocket, gridSocket } from "../../../websockets" import { helpers } from "@budibase/shared-core" +import isEqual from "lodash/isEqual" +import { publishEvent } from "@budibase/backend-core/src/events" function stripUnknownFields( field: ViewFieldMetadata @@ -164,6 +168,54 @@ export async function create(ctx: Ctx) { gridSocket?.emitViewUpdate(ctx, result) } +async function handleViewEvents(existingView: ViewV2, view: ViewV2) { + // Grouped filters + if (view.queryUI?.groups) { + const filterGroups = view.queryUI?.groups?.length || 0 + const properties = { filterGroups, tableId: view.tableId } + if (!existingView?.queryUI) { + await publishEvent(Event.VIEW_FILTER_CREATED, properties) + await events.view.filterCreated(properties) + } else { + if ( + filterGroups > + ((existingView && existingView?.queryUI?.groups?.length) || 0) + ) { + await events.view.filterUpdated(properties) + } + } + } + + // if new columns in the view + for (const key in view.schema) { + if (!existingView?.schema?.[key]) { + const newColumn = view.schema[key] + + // view calculations + // @ts-expect-error non calculation types just won't have the calculationType field + const calculationType = newColumn.calculationType + if (calculationType) { + // Send the event + await events.view.calculationCreated({ + calculationType, + tableId: view.tableId, + }) + } + + // view joins + if (newColumn.columns) { + for (const column in newColumn?.columns) { + // if the new column is visible and it wasn't before + if (!existingView?.schema?.[key].columns?.[column].visible) { + // new view join exposing a column + await events.view.viewJoinCreated({ tableId: view.tableId }) + } + } + } + } + } +} + export async function update(ctx: Ctx) { const view = ctx.request.body @@ -191,8 +243,12 @@ export async function update(ctx: Ctx) { primaryDisplay: view.primaryDisplay, } - const { view: result } = await sdk.views.update(tableId, parsedView) + const { view: result, existingView } = await sdk.views.update( + tableId, + parsedView + ) + await handleViewEvents(existingView, result) await events.view.updated(result) ctx.body = { data: result } diff --git a/packages/server/src/api/routes/tests/viewV2.spec.ts b/packages/server/src/api/routes/tests/viewV2.spec.ts index 23ae7c79d3..9dfe565cee 100644 --- a/packages/server/src/api/routes/tests/viewV2.spec.ts +++ b/packages/server/src/api/routes/tests/viewV2.spec.ts @@ -42,7 +42,7 @@ import { } from "../../../integrations/tests/utils" import merge from "lodash/merge" import { quotas } from "@budibase/pro" -import { db, roles, context } from "@budibase/backend-core" +import { db, roles, context, events } from "@budibase/backend-core" const descriptions = datasourceDescribe({ exclude: [DatabaseName.MONGODB] }) @@ -129,6 +129,7 @@ if (descriptions.length) { id: expect.stringMatching(new RegExp(`${table._id!}_`)), version: 2, }) + expect(events.view.created).toHaveBeenCalledTimes(1) }) it("can persist views with all fields", async () => { @@ -195,6 +196,7 @@ if (descriptions.length) { } expect(res).toEqual(expected) + expect(events.view.created).toHaveBeenCalledTimes(1) }) it("can create a view with just a query field, no queryUI, for backwards compatibility", async () => { @@ -224,6 +226,7 @@ if (descriptions.length) { }, } const res = await config.api.viewV2.create(newView) + expect(events.view.created).toHaveBeenCalledTimes(1) const expected: ViewV2 = { ...newView, @@ -283,6 +286,7 @@ if (descriptions.length) { } const createdView = await config.api.viewV2.create(newView) + expect(events.view.created).toHaveBeenCalledTimes(1) expect(createdView).toEqual({ ...newView, @@ -990,6 +994,7 @@ if (descriptions.length) { expect((await config.api.table.get(tableId)).views).toEqual({ [view.name]: expected, }) + expect(events.view.updated).toHaveBeenCalledTimes(1) }) it("can update all fields", async () => { @@ -1621,6 +1626,7 @@ if (descriptions.length) { field: "age", } await config.api.viewV2.update(view) + expect(events.view.calculationCreated).toHaveBeenCalledTimes(1) const { rows } = await config.api.row.search(view.id) expect(rows).toHaveLength(2) @@ -2154,6 +2160,7 @@ if (descriptions.length) { }), }) ) + expect(events.view.viewJoinCreated).not.toBeCalled() }) it("does not rename columns with the same name but from other tables", async () => { diff --git a/packages/types/src/sdk/events/event.ts b/packages/types/src/sdk/events/event.ts index 242b182dec..23c0eb0cbd 100644 --- a/packages/types/src/sdk/events/event.ts +++ b/packages/types/src/sdk/events/event.ts @@ -118,6 +118,7 @@ export enum Event { VIEW_CALCULATION_CREATED = "view:calculation:created", VIEW_CALCULATION_UPDATED = "view:calculation:updated", VIEW_CALCULATION_DELETED = "view:calculation:deleted", + VIEW_JOIN_CREATED = "view:join:created", // ROWS ROWS_CREATED = "rows:created", @@ -192,6 +193,9 @@ export enum Event { // AUDIT LOG AUDIT_LOGS_FILTERED = "audit_log:filtered", AUDIT_LOGS_DOWNLOADED = "audit_log:downloaded", + + // ROW ACTION + ROW_ACTION_CREATED = "row_action:created", } export const UserGroupSyncEvents: Event[] = [ @@ -376,6 +380,7 @@ export const AuditedEventFriendlyName: Record = { [Event.VIEW_CALCULATION_CREATED]: undefined, [Event.VIEW_CALCULATION_UPDATED]: undefined, [Event.VIEW_CALCULATION_DELETED]: undefined, + [Event.VIEW_JOIN_CREATED]: undefined, // SERVED - NOT AUDITED [Event.SERVED_BUILDER]: undefined, @@ -395,6 +400,9 @@ export const AuditedEventFriendlyName: Record = { // AUDIT LOG - NOT AUDITED [Event.AUDIT_LOGS_FILTERED]: undefined, [Event.AUDIT_LOGS_DOWNLOADED]: undefined, + + // ROW ACTIONS - NOT AUDITED + [Event.ROW_ACTION_CREATED]: undefined, } // properties added at the final stage of the event pipeline diff --git a/packages/types/src/sdk/events/view.ts b/packages/types/src/sdk/events/view.ts index c73a591a34..0ea153ad9d 100644 --- a/packages/types/src/sdk/events/view.ts +++ b/packages/types/src/sdk/events/view.ts @@ -1,4 +1,4 @@ -import { ViewCalculation, ViewV2Type } from "../../documents" +import { CalculationType, ViewCalculation, ViewV2Type } from "../../documents" import { BaseEvent, TableExportFormat } from "./event" export interface ViewCreatedEvent extends BaseEvent { @@ -9,8 +9,6 @@ export interface ViewCreatedEvent extends BaseEvent { export interface ViewUpdatedEvent extends BaseEvent { tableId: string - groupedFilters: number - viewJoins: number } export interface ViewDeletedEvent extends BaseEvent { @@ -24,10 +22,12 @@ export interface ViewExportedEvent extends BaseEvent { export interface ViewFilterCreatedEvent extends BaseEvent { tableId: string + filterGroups: number } export interface ViewFilterUpdatedEvent extends BaseEvent { tableId: string + filterGroups: number } export interface ViewFilterDeletedEvent extends BaseEvent { @@ -36,7 +36,7 @@ export interface ViewFilterDeletedEvent extends BaseEvent { export interface ViewCalculationCreatedEvent extends BaseEvent { tableId: string - calculation: ViewCalculation + calculation: CalculationType } export interface ViewCalculationUpdatedEvent extends BaseEvent { @@ -48,3 +48,7 @@ export interface ViewCalculationDeletedEvent extends BaseEvent { tableId: string calculation: ViewCalculation } + +export interface ViewJoinCreatedEvent extends BaseEvent { + tableId: string +} From ec84cf1a56ffe87a6f23fc9a74f3900c52e6ced1 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Sun, 8 Dec 2024 23:50:22 +0000 Subject: [PATCH 10/22] lint --- .../server/src/api/controllers/view/views.ts | 2 - .../src/api/controllers/view/viewsV2.ts | 57 ++++++++------- .../server/src/api/routes/tests/table.spec.ts | 1 + .../src/api/routes/tests/viewV2.spec.ts | 70 ++++++++++++++----- 4 files changed, 80 insertions(+), 50 deletions(-) diff --git a/packages/server/src/api/controllers/view/views.ts b/packages/server/src/api/controllers/view/views.ts index 0626f4e55c..bc734c5657 100644 --- a/packages/server/src/api/controllers/view/views.ts +++ b/packages/server/src/api/controllers/view/views.ts @@ -19,8 +19,6 @@ import { builderSocket } from "../../../websockets" const cloneDeep = require("lodash/cloneDeep") -import isEqual from "lodash/isEqual" - export async function fetch(ctx: Ctx) { ctx.body = await getViews() } diff --git a/packages/server/src/api/controllers/view/viewsV2.ts b/packages/server/src/api/controllers/view/viewsV2.ts index e611df0de3..2751a81234 100644 --- a/packages/server/src/api/controllers/view/viewsV2.ts +++ b/packages/server/src/api/controllers/view/viewsV2.ts @@ -16,14 +16,10 @@ import { CountCalculationFieldMetadata, CreateViewResponse, UpdateViewResponse, - View, - Event, } from "@budibase/types" import { events } from "@budibase/backend-core" import { builderSocket, gridSocket } from "../../../websockets" import { helpers } from "@budibase/shared-core" -import isEqual from "lodash/isEqual" -import { publishEvent } from "@budibase/backend-core/src/events" function stripUnknownFields( field: ViewFieldMetadata @@ -168,48 +164,51 @@ export async function create(ctx: Ctx) { gridSocket?.emitViewUpdate(ctx, result) } +async function handleViewFilterEvents(existingView: ViewV2, view: ViewV2) { + const filterGroups = view.queryUI?.groups?.length || 0 + const properties = { filterGroups, tableId: view.tableId } + if (!existingView?.queryUI) { + await events.view.filterCreated(properties) + } else { + if ( + filterGroups > + ((existingView && existingView?.queryUI?.groups?.length) || 0) + ) { + await events.view.filterUpdated(properties) + } + } +} + async function handleViewEvents(existingView: ViewV2, view: ViewV2) { // Grouped filters if (view.queryUI?.groups) { - const filterGroups = view.queryUI?.groups?.length || 0 - const properties = { filterGroups, tableId: view.tableId } - if (!existingView?.queryUI) { - await publishEvent(Event.VIEW_FILTER_CREATED, properties) - await events.view.filterCreated(properties) - } else { - if ( - filterGroups > - ((existingView && existingView?.queryUI?.groups?.length) || 0) - ) { - await events.view.filterUpdated(properties) - } - } + await handleViewFilterEvents(existingView, view) } // if new columns in the view for (const key in view.schema) { if (!existingView?.schema?.[key]) { - const newColumn = view.schema[key] - // view calculations // @ts-expect-error non calculation types just won't have the calculationType field - const calculationType = newColumn.calculationType + const calculationType = view.schema[key].calculationType if (calculationType) { - // Send the event await events.view.calculationCreated({ calculationType, tableId: view.tableId, }) } + } - // view joins - if (newColumn.columns) { - for (const column in newColumn?.columns) { - // if the new column is visible and it wasn't before - if (!existingView?.schema?.[key].columns?.[column].visible) { - // new view join exposing a column - await events.view.viewJoinCreated({ tableId: view.tableId }) - } + // view joins + if (view.schema[key].columns) { + for (const column in view.schema[key]?.columns) { + // if the new column is visible and it wasn't before + if ( + !existingView?.schema?.[key].columns?.[column].visible && + view.schema?.[key].columns?.[column].visible + ) { + // new view join exposing a column + await events.view.viewJoinCreated({ tableId: view.tableId }) } } } diff --git a/packages/server/src/api/routes/tests/table.spec.ts b/packages/server/src/api/routes/tests/table.spec.ts index 39b6a68eaf..e47181e21f 100644 --- a/packages/server/src/api/routes/tests/table.spec.ts +++ b/packages/server/src/api/routes/tests/table.spec.ts @@ -247,6 +247,7 @@ if (descriptions.length) { }, }, }, + primary: ["_id"], views: {}, sql: true, }) diff --git a/packages/server/src/api/routes/tests/viewV2.spec.ts b/packages/server/src/api/routes/tests/viewV2.spec.ts index 9dfe565cee..739603bb3c 100644 --- a/packages/server/src/api/routes/tests/viewV2.spec.ts +++ b/packages/server/src/api/routes/tests/viewV2.spec.ts @@ -1,39 +1,39 @@ import { + ArrayOperator, + BasicOperator, + BBReferenceFieldSubType, + CalculationType, CreateViewRequest, Datasource, + EmptyFilterOption, FieldSchema, FieldType, INTERNAL_TABLE_SOURCE_ID, + JsonFieldSubType, + JsonTypes, + LegacyFilter, + NumericCalculationFieldMetadata, PermissionLevel, QuotaUsageType, + RelationshipType, + RenameColumn, Row, SaveTableRequest, + SearchFilters, + SearchResponse, + SearchViewRowRequest, SortOrder, SortType, StaticQuotaName, Table, + TableSchema, TableSourceType, + UILogicalOperator, + UISearchFilter, UpdateViewRequest, ViewV2, - SearchResponse, - BasicOperator, - CalculationType, - RelationshipType, - TableSchema, - RenameColumn, - BBReferenceFieldSubType, - NumericCalculationFieldMetadata, ViewV2Schema, ViewV2Type, - JsonTypes, - EmptyFilterOption, - JsonFieldSubType, - UISearchFilter, - LegacyFilter, - SearchViewRowRequest, - ArrayOperator, - UILogicalOperator, - SearchFilters, } from "@budibase/types" import { generator, mocks } from "@budibase/backend-core/tests" import { @@ -42,7 +42,7 @@ import { } from "../../../integrations/tests/utils" import merge from "lodash/merge" import { quotas } from "@budibase/pro" -import { db, roles, context, events } from "@budibase/backend-core" +import { context, db, events, roles } from "@budibase/backend-core" const descriptions = datasourceDescribe({ exclude: [DatabaseName.MONGODB] }) @@ -1360,6 +1360,8 @@ if (descriptions.length) { }, }) + expect(events.view.filterCreated).toHaveBeenCalledTimes(1) + updatedView = await config.api.viewV2.get(view.id) expected = { onEmptyFilter: EmptyFilterOption.RETURN_ALL, @@ -2160,7 +2162,7 @@ if (descriptions.length) { }), }) ) - expect(events.view.viewJoinCreated).not.toBeCalled() + expect(events.view.viewJoinCreated).not.toHaveBeenCalled() }) it("does not rename columns with the same name but from other tables", async () => { @@ -2233,6 +2235,36 @@ if (descriptions.length) { ) }) + it("handles events for changing column visibility from default false", async () => { + let auxTable = await createAuxTable() + let aux2Table = await createAuxTable() + + const table = await createMainTable([ + { name: "aux", tableId: auxTable._id!, fk: "fk_aux" }, + { name: "aux2", tableId: aux2Table._id!, fk: "fk_aux2" }, + ]) + + const view = await createView(table._id!, { + aux: { + visible: true, + columns: { + name: { visible: false, readonly: true }, + }, + }, + aux2: { + visible: true, + columns: { + name: { visible: false, readonly: true }, + }, + }, + }) + + // @ts-expect-error column exists above + view.schema.aux2.columns.name.visible = true + await config.api.viewV2.update(view) + expect(events.view.viewJoinCreated).toHaveBeenCalledTimes(1) + }) + it("updates all views references", async () => { let auxTable = await createAuxTable() From 1d0b7d83e7b8f46e06f7ec77da039ffe32f6a07d Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Mon, 9 Dec 2024 08:45:36 +0000 Subject: [PATCH 11/22] view test --- packages/server/src/api/routes/tests/view.spec.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/server/src/api/routes/tests/view.spec.ts b/packages/server/src/api/routes/tests/view.spec.ts index 2217116f2d..e1968d2899 100644 --- a/packages/server/src/api/routes/tests/view.spec.ts +++ b/packages/server/src/api/routes/tests/view.spec.ts @@ -73,11 +73,6 @@ describe("/views", () => { } describe("create", () => { - it("returns a success message when the view is successfully created", async () => { - await saveView() - expect(events.view.created).toHaveBeenCalledTimes(1) - }) - it("creates a view with a calculation", async () => { jest.clearAllMocks() From 509950d36839d1fe08f15e40477b12a69f1d6b10 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 9 Dec 2024 09:35:01 +0000 Subject: [PATCH 12/22] Fix tests. --- packages/backend-core/src/migrations/migrations.ts | 2 +- packages/pro | 2 +- packages/types/src/sdk/migrations.ts | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/backend-core/src/migrations/migrations.ts b/packages/backend-core/src/migrations/migrations.ts index fe6bc17386..c8320b5724 100644 --- a/packages/backend-core/src/migrations/migrations.ts +++ b/packages/backend-core/src/migrations/migrations.ts @@ -35,7 +35,7 @@ export const backPopulateMigrations = async (opts: MigrationNoOpOptions) => { // filter migrations to the type and populate a no-op migration const migrations: Migration[] = DEFINITIONS.filter( def => def.type === opts.type - ).map(d => ({ ...d, fn: () => {} })) + ).map(d => ({ ...d, fn: async () => {} })) await runMigrations(migrations, { noOp: opts }) } diff --git a/packages/pro b/packages/pro index e49ac51191..b2f2e2b9d4 160000 --- a/packages/pro +++ b/packages/pro @@ -1 +1 @@ -Subproject commit e49ac51191d88787912673366d350d36987354fd +Subproject commit b2f2e2b9d45906744196875b87a121948e8e4c09 diff --git a/packages/types/src/sdk/migrations.ts b/packages/types/src/sdk/migrations.ts index f2b0ed48e3..6db0c85879 100644 --- a/packages/types/src/sdk/migrations.ts +++ b/packages/types/src/sdk/migrations.ts @@ -1,6 +1,8 @@ +import { Database } from "./db" + export interface Migration extends MigrationDefinition { appOpts?: object - fn: () => void + fn: (db: Database) => Promise silent?: boolean preventRetry?: boolean } From bca9bd27dbeb8666dd589d49f387da4455f6ccc8 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Mon, 9 Dec 2024 10:17:17 +0000 Subject: [PATCH 13/22] backfill tests --- packages/server/src/migrations/tests/index.spec.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/server/src/migrations/tests/index.spec.ts b/packages/server/src/migrations/tests/index.spec.ts index 6b3f3314ba..3a23d8f011 100644 --- a/packages/server/src/migrations/tests/index.spec.ts +++ b/packages/server/src/migrations/tests/index.spec.ts @@ -73,16 +73,12 @@ describe("migrations", () => { expect(events.query.created).toHaveBeenCalledTimes(2) expect(events.role.created).toHaveBeenCalledTimes(3) // created roles + admin (created on table creation) expect(events.table.created).toHaveBeenCalledTimes(3) - expect(events.view.created).toHaveBeenCalledTimes(2) - expect(events.view.calculationCreated).toHaveBeenCalledTimes(1) - expect(events.view.filterCreated).toHaveBeenCalledTimes(1) - expect(events.screen.created).toHaveBeenCalledTimes(2) expect(events.backfill.appSucceeded).toHaveBeenCalledTimes(2) // to make sure caching is working as expected expect( events.processors.analyticsProcessor.processEvent - ).toHaveBeenCalledTimes(24) // Addtion of of the events above + ).toHaveBeenCalledTimes(20) // Addition of of the events above }) }) }) From b98571302a0ebfdf498bb8bacfdb3b3895e1f3cf Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 9 Dec 2024 10:56:57 +0000 Subject: [PATCH 14/22] Fix build. --- packages/server/src/websockets/websocket.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/websockets/websocket.ts b/packages/server/src/websockets/websocket.ts index 2f031a72d9..e8cd306fd2 100644 --- a/packages/server/src/websockets/websocket.ts +++ b/packages/server/src/websockets/websocket.ts @@ -57,7 +57,7 @@ export class BaseSocket { const ctx = createContext(this.app, socket) try { - await runMiddlewares(ctx, middlewares, () => { + await runMiddlewares(ctx, middlewares, async () => { // Middlewares are finished // Extract some data from our enriched koa context to persist // as metadata for the socket From 6865052ef0a64e8d5f43299d5d5f98ff8d829ce6 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 9 Dec 2024 11:21:23 +0000 Subject: [PATCH 15/22] Get us much closer to using the recommended set of lints. --- eslint.config.mjs | 43 ++++++++++--------- hosting/scripts/setup.js | 4 +- package.json | 1 + .../tests/core/users/users.spec.js | 4 +- .../query/import/tests/index.spec.js | 4 +- .../src/api/routes/tests/analytics.spec.js | 29 ++++++------- .../server/src/api/routes/tests/dev.spec.js | 8 ++-- .../src/api/routes/tests/layout.spec.js | 4 +- .../integrations/tests/googlesheets.spec.ts | 32 +++++++------- .../src/integrations/tests/rest.spec.ts | 39 +++++++++-------- yarn.lock | 5 +++ 11 files changed, 91 insertions(+), 82 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 59c2202e94..2d2385cbdb 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -6,6 +6,7 @@ import tsParser from "@typescript-eslint/parser" import eslintPluginJest from "eslint-plugin-jest" import eslintPluginSvelte from "eslint-plugin-svelte" import eslintPluginLocalRules from "eslint-plugin-local-rules" +import eslintPluginVitest from "@vitest/eslint-plugin" import eslint from "@eslint/js" import tseslint from "typescript-eslint" @@ -17,17 +18,10 @@ export default [ "**/node_modules", "**/dist", "**/public", - "**/*.spec.js", "**/bundle.js", - "**/node_modules", - "**/public", - "**/dist", + "**/coverage", "packages/server/builder", - "packages/server/coverage", - "packages/worker/coverage", - "packages/backend-core/coverage", "packages/server/client", - "packages/server/coverage", "packages/builder/.routify", "packages/sdk/sdk", "**/*.ivm.bundle.js", @@ -102,18 +96,12 @@ export default [ }, rules: { - "prefer-spread": "off", - "no-unused-vars": "off", - "prefer-rest-params": "off", "local-rules/no-barrel-imports": "error", "local-rules/no-budibase-imports": "error", "local-rules/no-console-error": "error", - "@typescript-eslint/no-this-alias": "off", - "@typescript-eslint/no-unused-expressions": "off", - "@typescript-eslint/no-empty-object-type": "off", - "@typescript-eslint/no-require-imports": "off", - "@typescript-eslint/ban-ts-comment": "off", + // @typscript-eslint/no-unused-vars supersedes no-unused-vars + "no-unused-vars": "off", "@typescript-eslint/no-unused-vars": [ "error", { @@ -125,22 +113,28 @@ export default [ }, ], + // @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", }, } }), { - files: ["**/*.spec.ts"], + files: ["**/*.spec.ts", "**/*.spec.js"], plugins: { jest: eslintPluginJest, + vitest: eslintPluginVitest, }, languageOptions: { globals: { ...eslintPluginJest.environments.globals.globals, + ...eslintPluginVitest.environments.env.globals, NodeJS: true, }, @@ -148,13 +142,20 @@ export default [ }, rules: { - "local-rules/no-test-com": "error", - "local-rules/email-domain-example-com": "error", + ...eslintPluginVitest.configs.recommended.rules, + ...eslintPluginJest.configs.recommended.rules, + "no-console": "warn", + + "vitest/expect-expect": "off", + "jest/expect-expect": "off", "jest/no-conditional-expect": "off", - "no-dupe-class-members": "off", - "no-redeclare": "off", + "jest/no-disabled-tests": "off", + "jest/no-standalone-expect": "off", + + "local-rules/no-test-com": "error", + "local-rules/email-domain-example-com": "error", }, }, { diff --git a/hosting/scripts/setup.js b/hosting/scripts/setup.js index c62ac14f29..35ee32bd64 100755 --- a/hosting/scripts/setup.js +++ b/hosting/scripts/setup.js @@ -2,7 +2,6 @@ const os = require("os") const exec = require("child_process").exec -const fs = require("fs") const platform = os.platform() const windows = platform === "win32" @@ -17,10 +16,11 @@ function execute(command) { async function commandExistsUnix(command) { const unixCmd = `command -v ${command} 2>/dev/null && { echo >&1 ${command}; exit 0; }` - return execute(command) + return execute(unixCmd) } async function commandExistsWindows(command) { + // eslint-disable-next-line no-control-regex if (/[\x00-\x1f<>:"|?*]/.test(command)) { return false } diff --git a/package.json b/package.json index f95685c6ff..b047d25461 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "@types/node": "20.10.0", "@types/proper-lockfile": "^4.1.4", "@typescript-eslint/parser": "8.17.0", + "@vitest/eslint-plugin": "^1.1.14", "cross-spawn": "7.0.6", "depcheck": "^1.4.7", "esbuild": "^0.18.17", diff --git a/packages/backend-core/tests/core/users/users.spec.js b/packages/backend-core/tests/core/users/users.spec.js index f08c435b95..dde0d87fb7 100644 --- a/packages/backend-core/tests/core/users/users.spec.js +++ b/packages/backend-core/tests/core/users/users.spec.js @@ -11,15 +11,15 @@ const { getCreatorCount } = require("../../../src/users/users") describe("Users", () => { let getGlobalDBMock - let getGlobalUserParamsMock let paginationMock beforeEach(() => { jest.resetAllMocks() getGlobalDBMock = jest.spyOn(context, "getGlobalDB") - getGlobalUserParamsMock = jest.spyOn(db, "getGlobalUserParams") paginationMock = jest.spyOn(db, "pagination") + + jest.spyOn(db, "getGlobalUserParams") }) it("Retrieves the number of creators", async () => { diff --git a/packages/server/src/api/controllers/query/import/tests/index.spec.js b/packages/server/src/api/controllers/query/import/tests/index.spec.js index fcbd4509ee..409a55e81b 100644 --- a/packages/server/src/api/controllers/query/import/tests/index.spec.js +++ b/packages/server/src/api/controllers/query/import/tests/index.spec.js @@ -111,8 +111,8 @@ describe("Rest Importer", () => { const importResult = await restImporter.importQueries(datasource._id) expect(importResult.errorQueries.length).toBe(0) expect(importResult.queries.length).toBe(assertions[key].count) - expect(events.query.imported).toBeCalledTimes(1) - expect(events.query.imported).toBeCalledWith( + expect(events.query.imported).toHaveBeenCalledTimes(1) + expect(events.query.imported).toHaveBeenCalledWith( datasource, assertions[key].source, assertions[key].count diff --git a/packages/server/src/api/routes/tests/analytics.spec.js b/packages/server/src/api/routes/tests/analytics.spec.js index c69307656d..0b947ebcd9 100644 --- a/packages/server/src/api/routes/tests/analytics.spec.js +++ b/packages/server/src/api/routes/tests/analytics.spec.js @@ -4,14 +4,13 @@ const { events, constants } = require("@budibase/backend-core") describe("/static", () => { let request = setup.getRequest() let config = setup.getConfig() - let app const timezone = "Europe/London" afterAll(setup.afterAll) beforeAll(async () => { - app = await config.init() + await config.init() }) beforeEach(() => { @@ -26,10 +25,10 @@ describe("/static", () => { .set(config.defaultHeaders()) .expect(200) - expect(events.serve.servedBuilder).toBeCalledTimes(1) - expect(events.serve.servedBuilder).toBeCalledWith(timezone) - expect(events.serve.servedApp).not.toBeCalled() - expect(events.serve.servedAppPreview).not.toBeCalled() + expect(events.serve.servedBuilder).toHaveBeenCalledTimes(1) + expect(events.serve.servedBuilder).toHaveBeenCalledWith(timezone) + expect(events.serve.servedApp).not.toHaveBeenCalled() + expect(events.serve.servedAppPreview).not.toHaveBeenCalled() }) it("should ping from app preview", async () => { @@ -39,12 +38,12 @@ describe("/static", () => { .set(config.defaultHeaders()) .expect(200) - expect(events.serve.servedAppPreview).toBeCalledTimes(1) - expect(events.serve.servedAppPreview).toBeCalledWith( + expect(events.serve.servedAppPreview).toHaveBeenCalledTimes(1) + expect(events.serve.servedAppPreview).toHaveBeenCalledWith( config.getApp(), timezone ) - expect(events.serve.servedApp).not.toBeCalled() + expect(events.serve.servedApp).not.toHaveBeenCalled() }) it("should ping from app", async () => { @@ -57,13 +56,13 @@ describe("/static", () => { .set(headers) .expect(200) - expect(events.serve.servedApp).toBeCalledTimes(1) - expect(events.serve.servedApp).toBeCalledWith( + expect(events.serve.servedApp).toHaveBeenCalledTimes(1) + expect(events.serve.servedApp).toHaveBeenCalledWith( config.getProdApp(), timezone, undefined ) - expect(events.serve.servedAppPreview).not.toBeCalled() + expect(events.serve.servedAppPreview).not.toHaveBeenCalled() }) it("should ping from an embedded app", async () => { @@ -76,13 +75,13 @@ describe("/static", () => { .set(headers) .expect(200) - expect(events.serve.servedApp).toBeCalledTimes(1) - expect(events.serve.servedApp).toBeCalledWith( + expect(events.serve.servedApp).toHaveBeenCalledTimes(1) + expect(events.serve.servedApp).toHaveBeenCalledWith( config.getProdApp(), timezone, true ) - expect(events.serve.servedAppPreview).not.toBeCalled() + expect(events.serve.servedAppPreview).not.toHaveBeenCalled() }) }) }) diff --git a/packages/server/src/api/routes/tests/dev.spec.js b/packages/server/src/api/routes/tests/dev.spec.js index 73f506d17f..4c999e98c3 100644 --- a/packages/server/src/api/routes/tests/dev.spec.js +++ b/packages/server/src/api/routes/tests/dev.spec.js @@ -19,7 +19,7 @@ describe("/dev", () => { .set(config.defaultHeaders()) .expect("Content-Type", /json/) .expect(200) - expect(events.app.reverted).toBeCalledTimes(1) + expect(events.app.reverted).toHaveBeenCalledTimes(1) }) }) @@ -32,8 +32,10 @@ describe("/dev", () => { .expect(200) expect(res.body.version).toBe("0.0.0+jest") - expect(events.installation.versionChecked).toBeCalledTimes(1) - expect(events.installation.versionChecked).toBeCalledWith("0.0.0+jest") + expect(events.installation.versionChecked).toHaveBeenCalledTimes(1) + expect(events.installation.versionChecked).toHaveBeenCalledWith( + "0.0.0+jest" + ) }) }) }) diff --git a/packages/server/src/api/routes/tests/layout.spec.js b/packages/server/src/api/routes/tests/layout.spec.js index c3a3010e32..c5ffeb9c20 100644 --- a/packages/server/src/api/routes/tests/layout.spec.js +++ b/packages/server/src/api/routes/tests/layout.spec.js @@ -25,7 +25,7 @@ describe("/layouts", () => { .expect("Content-Type", /json/) .expect(200) expect(res.body._rev).toBeDefined() - expect(events.layout.created).toBeCalledTimes(1) + expect(events.layout.created).toHaveBeenCalledTimes(1) }) it("should apply authorization to endpoint", async () => { @@ -45,7 +45,7 @@ describe("/layouts", () => { .expect("Content-Type", /json/) .expect(200) expect(res.body.message).toBeDefined() - expect(events.layout.deleted).toBeCalledTimes(1) + expect(events.layout.deleted).toHaveBeenCalledTimes(1) }) it("should apply authorization to endpoint", async () => { diff --git a/packages/server/src/integrations/tests/googlesheets.spec.ts b/packages/server/src/integrations/tests/googlesheets.spec.ts index 2c0e4dce84..966123513c 100644 --- a/packages/server/src/integrations/tests/googlesheets.spec.ts +++ b/packages/server/src/integrations/tests/googlesheets.spec.ts @@ -389,24 +389,24 @@ describe("Google Sheets Integration", () => { }) // TODO: this gets the error "Sheet is not large enough to fit 27 columns. Resize the sheet first." - // it("should be able to add a new column", async () => { - // const updatedTable = await config.api.table.save({ - // ...table, - // schema: { - // ...table.schema, - // newColumn: { - // name: "newColumn", - // type: FieldType.STRING, - // }, - // }, - // }) + it.skip("should be able to add a new column", async () => { + const updatedTable = await config.api.table.save({ + ...table, + schema: { + ...table.schema, + newColumn: { + name: "newColumn", + type: FieldType.STRING, + }, + }, + }) - // expect(updatedTable.schema.newColumn).toBeDefined() + expect(updatedTable.schema.newColumn).toBeDefined() - // expect(mock.cell("A1")).toEqual("name") - // expect(mock.cell("B1")).toEqual("description") - // expect(mock.cell("C1")).toEqual("newColumn") - // }) + expect(mock.cell("A1")).toEqual("name") + expect(mock.cell("B1")).toEqual("description") + expect(mock.cell("C1")).toEqual("newColumn") + }) it("should be able to delete a column", async () => { const row = await config.api.row.save(table._id!, { diff --git a/packages/server/src/integrations/tests/rest.spec.ts b/packages/server/src/integrations/tests/rest.spec.ts index fac6f58c3b..0411a1380e 100644 --- a/packages/server/src/integrations/tests/rest.spec.ts +++ b/packages/server/src/integrations/tests/rest.spec.ts @@ -3,6 +3,8 @@ import { RestIntegration } from "../rest" import { BodyType, RestAuthType } from "@budibase/types" import { Response } from "node-fetch" import TestConfiguration from "../../../src/tests/utilities/TestConfiguration" +import { createServer } from "http" +import { AddressInfo } from "net" const UUID_REGEX = "[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}" @@ -455,28 +457,27 @@ describe("REST Integration", () => { // NOTE(samwho): it seems like this code doesn't actually work because it requires // node-fetch >=3, and we're not on that because upgrading to it produces errors to // do with ESM that are above my pay grade. + it.skip("doesn't fail when legacyHttpParser is set", async () => { + const server = createServer((req, res) => { + res.writeHead(200, { + "Transfer-Encoding": "chunked", + "Content-Length": "10", + }) + res.end(JSON.stringify({ foo: "bar" })) + }) - // it("doesn't fail when legacyHttpParser is set", async () => { - // const server = createServer((req, res) => { - // res.writeHead(200, { - // "Transfer-Encoding": "chunked", - // "Content-Length": "10", - // }) - // res.end(JSON.stringify({ foo: "bar" })) - // }) + server.listen() + await new Promise(resolve => server.once("listening", resolve)) - // server.listen() - // await new Promise(resolve => server.once("listening", resolve)) + const address = server.address() as AddressInfo - // const address = server.address() as AddressInfo - - // const integration = new RestIntegration({ - // url: `http://localhost:${address.port}`, - // legacyHttpParser: true, - // }) - // const { data } = await integration.read({}) - // expect(data).toEqual({ foo: "bar" }) - // }) + const integration = new RestIntegration({ + url: `http://localhost:${address.port}`, + legacyHttpParser: true, + }) + const { data } = await integration.read({}) + expect(data).toEqual({ foo: "bar" }) + }) it("doesn't fail when legacyHttpParser is true", async () => { nock("https://example.com").get("/").reply(200, { foo: "bar" }) diff --git a/yarn.lock b/yarn.lock index 4b4ab5146f..1e44ea753a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6432,6 +6432,11 @@ resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== +"@vitest/eslint-plugin@^1.1.14": + version "1.1.14" + resolved "https://registry.yarnpkg.com/@vitest/eslint-plugin/-/eslint-plugin-1.1.14.tgz#dc3bb332461282cfab213b76e5e42bd2dad5929b" + integrity sha512-ej0cT5rUt7uvwxuu7Qxkm7fI+eaOq8vD34qGpuRoXCdvOybOlE5GDqtgvVCYbxLANkcRJfm5VDU1TnJmQRHi9g== + "@vitest/expect@0.29.8": version "0.29.8" resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-0.29.8.tgz#6ecdd031b4ea8414717d10b65ccd800908384612" From b6fcdf301dbb352cd00dba25434ee894af7231fc Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Mon, 9 Dec 2024 11:59:04 +0000 Subject: [PATCH 16/22] PR comments --- .../src/events/publishers/table.ts | 2 +- .../src/api/controllers/view/viewsV2.ts | 33 ++++++++----------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/packages/backend-core/src/events/publishers/table.ts b/packages/backend-core/src/events/publishers/table.ts index de765e2cdd..77a2c3e1a4 100644 --- a/packages/backend-core/src/events/publishers/table.ts +++ b/packages/backend-core/src/events/publishers/table.ts @@ -29,7 +29,7 @@ async function updated(oldTable: Table, newTable: Table) { for (const key in newTable.schema) { if (!oldTable.schema[key]) { const newColumn = newTable.schema[key] - if ("default" in newColumn) { + if ("default" in newColumn && newColumn.default != null) { defaultValues = true } if (newColumn.type === FieldType.AI) { diff --git a/packages/server/src/api/controllers/view/viewsV2.ts b/packages/server/src/api/controllers/view/viewsV2.ts index 2751a81234..66a6194096 100644 --- a/packages/server/src/api/controllers/view/viewsV2.ts +++ b/packages/server/src/api/controllers/view/viewsV2.ts @@ -187,29 +187,22 @@ async function handleViewEvents(existingView: ViewV2, view: ViewV2) { // if new columns in the view for (const key in view.schema) { - if (!existingView?.schema?.[key]) { - // view calculations - // @ts-expect-error non calculation types just won't have the calculationType field - const calculationType = view.schema[key].calculationType - if (calculationType) { - await events.view.calculationCreated({ - calculationType, - tableId: view.tableId, - }) - } + if ("calculationType" in view.schema[key] && !existingView?.schema?.[key]) { + await events.view.calculationCreated({ + calculationType: view.schema[key].calculationType, + tableId: view.tableId, + }) } // view joins - if (view.schema[key].columns) { - for (const column in view.schema[key]?.columns) { - // if the new column is visible and it wasn't before - if ( - !existingView?.schema?.[key].columns?.[column].visible && - view.schema?.[key].columns?.[column].visible - ) { - // new view join exposing a column - await events.view.viewJoinCreated({ tableId: view.tableId }) - } + for (const column in view.schema[key]?.columns ?? []) { + // if the new column is visible and it wasn't before + if ( + !existingView?.schema?.[key].columns?.[column].visible && + view.schema?.[key].columns?.[column].visible + ) { + // new view join exposing a column + await events.view.viewJoinCreated({ tableId: view.tableId }) } } } From 84d9f6816cf766cb5bbfc21789b25b2bd50bbaaf Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 9 Dec 2024 12:52:21 +0000 Subject: [PATCH 17/22] Enable a variety of useful looking lints. --- eslint.config.mjs | 128 ++++++++++-------- .../backend-core/src/db/couch/DatabaseImpl.ts | 2 +- packages/backend-core/src/db/couch/utils.ts | 4 +- packages/backend-core/src/db/lucene.ts | 2 +- .../src/events/processors/Processors.ts | 2 +- .../src/middleware/authenticated.ts | 4 +- .../src/middleware/passport/sso/sso.ts | 2 +- .../src/objectStore/objectStore.ts | 2 +- .../backend-core/src/redis/redlockImpl.ts | 2 +- .../tests/core/utilities/structures/quotas.ts | 2 +- packages/bbui/src/Form/Core/Signature.svelte | 2 +- .../backend/RoleEditor/BracketEdge.svelte | 6 +- .../app/embedded-map/EmbeddedMapControls.js | 8 +- packages/client/src/stores/theme.js | 1 + packages/server/src/api/controllers/dev.ts | 2 +- .../api/controllers/row/ExternalRequest.ts | 2 +- .../src/api/controllers/row/utils/basic.ts | 2 +- .../src/api/controllers/view/exporters.ts | 2 +- .../src/api/routes/tests/search.spec.ts | 2 +- .../tests/utilities/AutomationTestBuilder.ts | 2 +- .../src/integrations/microsoftSqlServer.ts | 2 +- packages/server/src/integrations/oracle.ts | 2 +- packages/server/src/integrations/postgres.ts | 4 +- packages/server/src/integrations/rest.ts | 2 +- .../src/integrations/tests/sqlAlias.spec.ts | 2 +- packages/server/src/middleware/builder.ts | 4 +- .../server/src/sdk/app/permissions/index.ts | 2 - .../src/sdk/app/rows/search/internal/sqs.ts | 2 +- .../server/src/tests/utilities/structures.ts | 6 +- packages/server/src/utilities/retry.ts | 2 +- packages/server/src/websockets/websocket.ts | 2 +- packages/shared-core/src/helpers/cron.ts | 2 +- .../string-templates/test/hbsToJs.spec.ts | 1 + packages/string-templates/test/utils.ts | 2 +- packages/types/src/sdk/db.ts | 2 +- packages/worker/src/sdk/accounts/metadata.ts | 5 +- packages/worker/src/tests/api/accounts.ts | 5 - packages/worker/src/tests/api/auditLogs.ts | 5 - packages/worker/src/tests/api/auth.ts | 5 - packages/worker/src/tests/api/configs.ts | 5 - packages/worker/src/tests/api/email.ts | 5 - packages/worker/src/tests/api/environment.ts | 5 - packages/worker/src/tests/api/groups.ts | 5 - packages/worker/src/tests/api/license.ts | 5 - packages/worker/src/tests/api/migrations.ts | 5 - packages/worker/src/tests/api/restore.ts | 5 - packages/worker/src/tests/api/roles.ts | 5 - packages/worker/src/tests/api/scim/groups.ts | 5 - packages/worker/src/tests/api/scim/shared.ts | 5 - packages/worker/src/tests/api/scim/users.ts | 5 - packages/worker/src/tests/api/self.ts | 5 - packages/worker/src/tests/api/status.ts | 5 - packages/worker/src/tests/api/templates.ts | 5 - packages/worker/src/tests/api/users.ts | 11 +- scripts/build.js | 2 +- 55 files changed, 120 insertions(+), 199 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 2d2385cbdb..c497974612 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -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"], diff --git a/packages/backend-core/src/db/couch/DatabaseImpl.ts b/packages/backend-core/src/db/couch/DatabaseImpl.ts index 371f3dc997..98e24e0996 100644 --- a/packages/backend-core/src/db/couch/DatabaseImpl.ts +++ b/packages/backend-core/src/db/couch/DatabaseImpl.ts @@ -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 diff --git a/packages/backend-core/src/db/couch/utils.ts b/packages/backend-core/src/db/couch/utils.ts index 270d953320..2200024bb2 100644 --- a/packages/backend-core/src/db/couch/utils.ts +++ b/packages/backend-core/src/db/couch/utils.ts @@ -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) diff --git a/packages/backend-core/src/db/lucene.ts b/packages/backend-core/src/db/lucene.ts index 0206bb2140..9d897553dd 100644 --- a/packages/backend-core/src/db/lucene.ts +++ b/packages/backend-core/src/db/lucene.ts @@ -279,7 +279,7 @@ export class QueryBuilder { 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 diff --git a/packages/backend-core/src/events/processors/Processors.ts b/packages/backend-core/src/events/processors/Processors.ts index 72de945d44..8fe8034280 100644 --- a/packages/backend-core/src/events/processors/Processors.ts +++ b/packages/backend-core/src/events/processors/Processors.ts @@ -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[]) { diff --git a/packages/backend-core/src/middleware/authenticated.ts b/packages/backend-core/src/middleware/authenticated.ts index 6713cc7687..54d808de86 100644 --- a/packages/backend-core/src/middleware/authenticated.ts +++ b/packages/backend-core/src/middleware/authenticated.ts @@ -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 diff --git a/packages/backend-core/src/middleware/passport/sso/sso.ts b/packages/backend-core/src/middleware/passport/sso/sso.ts index 8901fcc56f..1bb43d4466 100644 --- a/packages/backend-core/src/middleware/passport/sso/sso.ts +++ b/packages/backend-core/src/middleware/passport/sso/sso.ts @@ -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 ) { diff --git a/packages/backend-core/src/objectStore/objectStore.ts b/packages/backend-core/src/objectStore/objectStore.ts index 68b1b10ec2..79875b5e99 100644 --- a/packages/backend-core/src/objectStore/objectStore.ts +++ b/packages/backend-core/src/objectStore/objectStore.ts @@ -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 = { diff --git a/packages/backend-core/src/redis/redlockImpl.ts b/packages/backend-core/src/redis/redlockImpl.ts index adeb5b12ec..a48fac0c3d 100644 --- a/packages/backend-core/src/redis/redlockImpl.ts +++ b/packages/backend-core/src/redis/redlockImpl.ts @@ -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}` diff --git a/packages/backend-core/tests/core/utilities/structures/quotas.ts b/packages/backend-core/tests/core/utilities/structures/quotas.ts index 83c3a8a766..4b3c357b13 100644 --- a/packages/backend-core/tests/core/utilities/structures/quotas.ts +++ b/packages/backend-core/tests/core/utilities/structures/quotas.ts @@ -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(), diff --git a/packages/bbui/src/Form/Core/Signature.svelte b/packages/bbui/src/Form/Core/Signature.svelte index 729d3ac5e2..e02560568c 100644 --- a/packages/bbui/src/Form/Core/Signature.svelte +++ b/packages/bbui/src/Form/Core/Signature.svelte @@ -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 diff --git a/packages/builder/src/components/backend/RoleEditor/BracketEdge.svelte b/packages/builder/src/components/backend/RoleEditor/BracketEdge.svelte index 182b56f122..058c47f00c 100644 --- a/packages/builder/src/components/backend/RoleEditor/BracketEdge.svelte +++ b/packages/builder/src/components/backend/RoleEditor/BracketEdge.svelte @@ -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 diff --git a/packages/client/src/components/app/embedded-map/EmbeddedMapControls.js b/packages/client/src/components/app/embedded-map/EmbeddedMapControls.js index de14190b64..190bc810bf 100644 --- a/packages/client/src/components/app/embedded-map/EmbeddedMapControls.js +++ b/packages/client/src/components/app/embedded-map/EmbeddedMapControls.js @@ -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, diff --git a/packages/client/src/stores/theme.js b/packages/client/src/stores/theme.js index 523d34cdc5..5171449a91 100644 --- a/packages/client/src/stores/theme.js +++ b/packages/client/src/stores/theme.js @@ -1,3 +1,4 @@ +/* eslint-disable no-useless-concat */ import { derived } from "svelte/store" import { appStore } from "./app" import { builderStore } from "./builder" diff --git a/packages/server/src/api/controllers/dev.ts b/packages/server/src/api/controllers/dev.ts index ad0909a294..099f297cd4 100644 --- a/packages/server/src/api/controllers/dev.ts +++ b/packages/server/src/api/controllers/dev.ts @@ -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] || "" diff --git a/packages/server/src/api/controllers/row/ExternalRequest.ts b/packages/server/src/api/controllers/row/ExternalRequest.ts index 5f01f323e6..e0171a062e 100644 --- a/packages/server/src/api/controllers/row/ExternalRequest.ts +++ b/packages/server/src/api/controllers/row/ExternalRequest.ts @@ -378,7 +378,7 @@ export class ExternalRequest { } // many to one else { - const thisKey: string = "id" + const thisKey = "id" // @ts-ignore const otherKey: string = field.fieldName for (const relationship of row[key]) { diff --git a/packages/server/src/api/controllers/row/utils/basic.ts b/packages/server/src/api/controllers/row/utils/basic.ts index a7aa82e1f2..214080382c 100644 --- a/packages/server/src/api/controllers/row/utils/basic.ts +++ b/packages/server/src/api/controllers/row/utils/basic.ts @@ -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) { diff --git a/packages/server/src/api/controllers/view/exporters.ts b/packages/server/src/api/controllers/view/exporters.ts index 87e4bfc056..76e5f865a3 100644 --- a/packages/server/src/api/controllers/view/exporters.ts +++ b/packages/server/src/api/controllers/view/exporters.ts @@ -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)] diff --git a/packages/server/src/api/routes/tests/search.spec.ts b/packages/server/src/api/routes/tests/search.spec.ts index 6aac1d2069..6276d38e25 100644 --- a/packages/server/src/api/routes/tests/search.spec.ts +++ b/packages/server/src/api/routes/tests/search.spec.ts @@ -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, diff --git a/packages/server/src/automations/tests/utilities/AutomationTestBuilder.ts b/packages/server/src/automations/tests/utilities/AutomationTestBuilder.ts index 7a0d489f80..a3ea174da1 100644 --- a/packages/server/src/automations/tests/utilities/AutomationTestBuilder.ts +++ b/packages/server/src/automations/tests/utilities/AutomationTestBuilder.ts @@ -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 } = {} diff --git a/packages/server/src/integrations/microsoftSqlServer.ts b/packages/server/src/integrations/microsoftSqlServer.ts index 7d886fc33a..f3590d1885 100644 --- a/packages/server/src/integrations/microsoftSqlServer.ts +++ b/packages/server/src/integrations/microsoftSqlServer.ts @@ -223,7 +223,7 @@ const COLUMN_DEFINITION_METADATA: Record = { class SqlServerIntegration extends Sql implements DatasourcePlus { private readonly config: MSSQLConfig - private index: number = 0 + private index= 0 private client?: sqlServer.ConnectionPool MASTER_TABLES = [ diff --git a/packages/server/src/integrations/oracle.ts b/packages/server/src/integrations/oracle.ts index d8708d9053..5fbb95aab3 100644 --- a/packages/server/src/integrations/oracle.ts +++ b/packages/server/src/integrations/oracle.ts @@ -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 diff --git a/packages/server/src/integrations/postgres.ts b/packages/server/src/integrations/postgres.ts index b41ac28ede..f4db9d6959 100644 --- a/packages/server/src/integrations/postgres.ts +++ b/packages/server/src/integrations/postgres.ts @@ -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() } diff --git a/packages/server/src/integrations/rest.ts b/packages/server/src/integrations/rest.ts index 1b00a18f18..4f8b246233 100644 --- a/packages/server/src/integrations/rest.ts +++ b/packages/server/src/integrations/rest.ts @@ -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) { diff --git a/packages/server/src/integrations/tests/sqlAlias.spec.ts b/packages/server/src/integrations/tests/sqlAlias.spec.ts index 3d67a7aa41..b94f0c4c87 100644 --- a/packages/server/src/integrations/tests/sqlAlias.spec.ts +++ b/packages/server/src/integrations/tests/sqlAlias.spec.ts @@ -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) } diff --git a/packages/server/src/middleware/builder.ts b/packages/server/src/middleware/builder.ts index bc775991df..90bbd368ef 100644 --- a/packages/server/src/middleware/builder.ts +++ b/packages/server/src/middleware/builder.ts @@ -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 } } diff --git a/packages/server/src/sdk/app/permissions/index.ts b/packages/server/src/sdk/app/permissions/index.ts index 7c385864f4..6e912a0235 100644 --- a/packages/server/src/sdk/app/permissions/index.ts +++ b/packages/server/src/sdk/app/permissions/index.ts @@ -104,8 +104,6 @@ export async function getDependantResources( return p }, {} as Record) } - - return } export async function updatePermissionOnRole( diff --git a/packages/server/src/sdk/app/rows/search/internal/sqs.ts b/packages/server/src/sdk/app/rows/search/internal/sqs.ts index 19380bde43..aa799390b8 100644 --- a/packages/server/src/sdk/app/rows/search/internal/sqs.ts +++ b/packages/server/src/sdk/app/rows/search/internal/sqs.ts @@ -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 diff --git a/packages/server/src/tests/utilities/structures.ts b/packages/server/src/tests/utilities/structures.ts index beb03ecf08..33e6e407dc 100644 --- a/packages/server/src/tests/utilities/structures.ts +++ b/packages/server/src/tests/utilities/structures.ts @@ -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, diff --git a/packages/server/src/utilities/retry.ts b/packages/server/src/utilities/retry.ts index af5d4d7cb5..f6e8cbd0e5 100644 --- a/packages/server/src/utilities/retry.ts +++ b/packages/server/src/utilities/retry.ts @@ -1,6 +1,6 @@ export async function retry any>( fn: T, - maxTry: number = 5, + maxTry = 5, retryCount = 1 ): Promise>> { const currRetry = typeof retryCount === "number" ? retryCount : 1 diff --git a/packages/server/src/websockets/websocket.ts b/packages/server/src/websockets/websocket.ts index e8cd306fd2..607cf12b78 100644 --- a/packages/server/src/websockets/websocket.ts +++ b/packages/server/src/websockets/websocket.ts @@ -33,7 +33,7 @@ export class BaseSocket { constructor( app: Koa, server: http.Server, - path: string = "/", + path = "/", additionalMiddlewares?: any[] ) { this.app = app diff --git a/packages/shared-core/src/helpers/cron.ts b/packages/shared-core/src/helpers/cron.ts index a13c19c265..dab45ebcab 100644 --- a/packages/shared-core/src/helpers/cron.ts +++ b/packages/shared-core/src/helpers/cron.ts @@ -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 = [] diff --git a/packages/string-templates/test/hbsToJs.spec.ts b/packages/string-templates/test/hbsToJs.spec.ts index ae071cfe37..51fba083aa 100644 --- a/packages/string-templates/test/hbsToJs.spec.ts +++ b/packages/string-templates/test/hbsToJs.spec.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-template-curly-in-string */ import { convertToJS } from "../src/index" function checkLines(response: string, lines: string[]) { diff --git a/packages/string-templates/test/utils.ts b/packages/string-templates/test/utils.ts index 957366fc59..4934567788 100644 --- a/packages/string-templates/test/utils.ts +++ b/packages/string-templates/test/utils.ts @@ -11,7 +11,7 @@ function tryParseJson(str: string) { try { return JSON.parse(str.replace(/'/g, '"')) } catch (e) { - return + // do nothing } } diff --git a/packages/types/src/sdk/db.ts b/packages/types/src/sdk/db.ts index 9feecbdb2b..eb922bd81e 100644 --- a/packages/types/src/sdk/db.ts +++ b/packages/types/src/sdk/db.ts @@ -128,13 +128,13 @@ export interface Database { name: string exists(): Promise + exists(docId: string): Promise /** * @deprecated the plan is to get everything using `tryGet` instead, then rename * `tryGet` to `get`. */ get(id?: string): Promise tryGet(id?: string): Promise - exists(docId: string): Promise getMultiple( ids: string[], opts?: { allowMissing?: boolean; excludeDocs?: boolean } diff --git a/packages/worker/src/sdk/accounts/metadata.ts b/packages/worker/src/sdk/accounts/metadata.ts index 11ab069839..1cace19981 100644 --- a/packages/worker/src/sdk/accounts/metadata.ts +++ b/packages/worker/src/sdk/accounts/metadata.ts @@ -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 } } diff --git a/packages/worker/src/tests/api/accounts.ts b/packages/worker/src/tests/api/accounts.ts index bc6d055b77..25861226f9 100644 --- a/packages/worker/src/tests/api/accounts.ts +++ b/packages/worker/src/tests/api/accounts.ts @@ -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`) diff --git a/packages/worker/src/tests/api/auditLogs.ts b/packages/worker/src/tests/api/auditLogs.ts index d7bc4d99fb..c79b4ea934 100644 --- a/packages/worker/src/tests/api/auditLogs.ts +++ b/packages/worker/src/tests/api/auditLogs.ts @@ -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") diff --git a/packages/worker/src/tests/api/auth.ts b/packages/worker/src/tests/api/auth.ts index 552d4da505..2587fe4c8f 100644 --- a/packages/worker/src/tests/api/auth.ts +++ b/packages/worker/src/tests/api/auth.ts @@ -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, diff --git a/packages/worker/src/tests/api/configs.ts b/packages/worker/src/tests/api/configs.ts index e0c1c806af..36d145412a 100644 --- a/packages/worker/src/tests/api/configs.ts +++ b/packages/worker/src/tests/api/configs.ts @@ -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`) diff --git a/packages/worker/src/tests/api/email.ts b/packages/worker/src/tests/api/email.ts index b2f30e6ac1..a8f5967d58 100644 --- a/packages/worker/src/tests/api/email.ts +++ b/packages/worker/src/tests/api/email.ts @@ -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`) diff --git a/packages/worker/src/tests/api/environment.ts b/packages/worker/src/tests/api/environment.ts index d6a76f3b06..b394f692ec 100644 --- a/packages/worker/src/tests/api/environment.ts +++ b/packages/worker/src/tests/api/environment.ts @@ -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`) diff --git a/packages/worker/src/tests/api/groups.ts b/packages/worker/src/tests/api/groups.ts index 5153c19db0..5d983a53d4 100644 --- a/packages/worker/src/tests/api/groups.ts +++ b/packages/worker/src/tests/api/groups.ts @@ -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 } diff --git a/packages/worker/src/tests/api/license.ts b/packages/worker/src/tests/api/license.ts index a6645226af..bf7c952ab0 100644 --- a/packages/worker/src/tests/api/license.ts +++ b/packages/worker/src/tests/api/license.ts @@ -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") diff --git a/packages/worker/src/tests/api/migrations.ts b/packages/worker/src/tests/api/migrations.ts index 6038cbd5d8..6d62fe994a 100644 --- a/packages/worker/src/tests/api/migrations.ts +++ b/packages/worker/src/tests/api/migrations.ts @@ -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`) diff --git a/packages/worker/src/tests/api/restore.ts b/packages/worker/src/tests/api/restore.ts index c6a646317d..a39428da07 100644 --- a/packages/worker/src/tests/api/restore.ts +++ b/packages/worker/src/tests/api/restore.ts @@ -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`) diff --git a/packages/worker/src/tests/api/roles.ts b/packages/worker/src/tests/api/roles.ts index 8e7647583a..6c7be76054 100644 --- a/packages/worker/src/tests/api/roles.ts +++ b/packages/worker/src/tests/api/roles.ts @@ -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`) diff --git a/packages/worker/src/tests/api/scim/groups.ts b/packages/worker/src/tests/api/scim/groups.ts index d2df007614..0ec705fc52 100644 --- a/packages/worker/src/tests/api/scim/groups.ts +++ b/packages/worker/src/tests/api/scim/groups.ts @@ -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 & { params?: { diff --git a/packages/worker/src/tests/api/scim/shared.ts b/packages/worker/src/tests/api/scim/shared.ts index 546a940093..fca6f77abd 100644 --- a/packages/worker/src/tests/api/scim/shared.ts +++ b/packages/worker/src/tests/api/scim/shared.ts @@ -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", diff --git a/packages/worker/src/tests/api/scim/users.ts b/packages/worker/src/tests/api/scim/users.ts index 318492d378..f518d49ce6 100644 --- a/packages/worker/src/tests/api/scim/users.ts +++ b/packages/worker/src/tests/api/scim/users.ts @@ -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 & { params?: { diff --git a/packages/worker/src/tests/api/self.ts b/packages/worker/src/tests/api/self.ts index 1c1492f37f..6f8cd8decf 100644 --- a/packages/worker/src/tests/api/self.ts +++ b/packages/worker/src/tests/api/self.ts @@ -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`) diff --git a/packages/worker/src/tests/api/status.ts b/packages/worker/src/tests/api/status.ts index 5b0f77efc6..c658411abc 100644 --- a/packages/worker/src/tests/api/status.ts +++ b/packages/worker/src/tests/api/status.ts @@ -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) } diff --git a/packages/worker/src/tests/api/templates.ts b/packages/worker/src/tests/api/templates.ts index 0c8110394f..23e327b392 100644 --- a/packages/worker/src/tests/api/templates.ts +++ b/packages/worker/src/tests/api/templates.ts @@ -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`) diff --git a/packages/worker/src/tests/api/users.ts b/packages/worker/src/tests/api/users.ts index b54fb45d2c..b964ba5112 100644 --- a/packages/worker/src/tests/api/users.ts +++ b/packages/worker/src/tests/api/users.ts @@ -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()) diff --git a/scripts/build.js b/scripts/build.js index 93a2a1e589..d96b27b166 100755 --- a/scripts/build.js +++ b/scripts/build.js @@ -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" From e5453cc766db170affd212cc61dac0697f7ca9e0 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Mon, 9 Dec 2024 13:45:11 +0000 Subject: [PATCH 18/22] only fire view updated events when 2 or more groups are applied --- .../src/api/controllers/view/viewsV2.ts | 14 +++---- .../src/api/routes/tests/viewV2.spec.ts | 41 ++++++++++++++++++- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/packages/server/src/api/controllers/view/viewsV2.ts b/packages/server/src/api/controllers/view/viewsV2.ts index 66a6194096..4c65d673e8 100644 --- a/packages/server/src/api/controllers/view/viewsV2.ts +++ b/packages/server/src/api/controllers/view/viewsV2.ts @@ -167,15 +167,11 @@ export async function create(ctx: Ctx) { async function handleViewFilterEvents(existingView: ViewV2, view: ViewV2) { const filterGroups = view.queryUI?.groups?.length || 0 const properties = { filterGroups, tableId: view.tableId } - if (!existingView?.queryUI) { - await events.view.filterCreated(properties) - } else { - if ( - filterGroups > - ((existingView && existingView?.queryUI?.groups?.length) || 0) - ) { - await events.view.filterUpdated(properties) - } + if ( + filterGroups >= 2 && + ((existingView && existingView?.queryUI?.groups?.length) || 0) + ) { + await events.view.filterUpdated(properties) } } diff --git a/packages/server/src/api/routes/tests/viewV2.spec.ts b/packages/server/src/api/routes/tests/viewV2.spec.ts index 739603bb3c..244a0a23eb 100644 --- a/packages/server/src/api/routes/tests/viewV2.spec.ts +++ b/packages/server/src/api/routes/tests/viewV2.spec.ts @@ -997,6 +997,45 @@ if (descriptions.length) { expect(events.view.updated).toHaveBeenCalledTimes(1) }) + it("handles view grouped filter events", async () => { + view.queryUI = { + logicalOperator: UILogicalOperator.ALL, + onEmptyFilter: EmptyFilterOption.RETURN_ALL, + groups: [ + { + logicalOperator: UILogicalOperator.ALL, + filters: [ + { + operator: BasicOperator.EQUAL, + field: "newField", + value: "newValue", + }, + ], + }, + ], + } + await config.api.viewV2.update(view) + expect(events.view.filterUpdated).not.toHaveBeenCalled() + + // @ts-ignore + view.queryUI.groups.push({ + logicalOperator: UILogicalOperator.ALL, + filters: [ + { + operator: BasicOperator.EQUAL, + field: "otherField", + value: "otherValue", + }, + ], + }) + + await config.api.viewV2.update(view) + expect(events.view.filterUpdated).toHaveBeenCalledWith({ + filterGroups: 2, + tableId: view.tableId, + }) + }) + it("can update all fields", async () => { const tableId = table._id! @@ -1360,8 +1399,6 @@ if (descriptions.length) { }, }) - expect(events.view.filterCreated).toHaveBeenCalledTimes(1) - updatedView = await config.api.viewV2.get(view.id) expected = { onEmptyFilter: EmptyFilterOption.RETURN_ALL, From 7d5ca8449fb5b98ec74e2966b633fb1514077865 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Mon, 9 Dec 2024 14:01:47 +0000 Subject: [PATCH 19/22] only fire for 2 grouped filters --- .../src/events/processors/posthog/PosthogProcessor.ts | 1 - packages/server/src/api/controllers/view/viewsV2.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/backend-core/src/events/processors/posthog/PosthogProcessor.ts b/packages/backend-core/src/events/processors/posthog/PosthogProcessor.ts index e8e8f35d6d..6c45da09e6 100644 --- a/packages/backend-core/src/events/processors/posthog/PosthogProcessor.ts +++ b/packages/backend-core/src/events/processors/posthog/PosthogProcessor.ts @@ -14,7 +14,6 @@ const EXCLUDED_EVENTS: Event[] = [ Event.DATASOURCE_UPDATED, Event.QUERY_UPDATED, Event.VIEW_UPDATED, - Event.VIEW_FILTER_UPDATED, Event.VIEW_CALCULATION_UPDATED, Event.AUTOMATION_TRIGGER_UPDATED, Event.USER_GROUP_UPDATED, diff --git a/packages/server/src/api/controllers/view/viewsV2.ts b/packages/server/src/api/controllers/view/viewsV2.ts index 4c65d673e8..da579efed7 100644 --- a/packages/server/src/api/controllers/view/viewsV2.ts +++ b/packages/server/src/api/controllers/view/viewsV2.ts @@ -169,7 +169,7 @@ async function handleViewFilterEvents(existingView: ViewV2, view: ViewV2) { const properties = { filterGroups, tableId: view.tableId } if ( filterGroups >= 2 && - ((existingView && existingView?.queryUI?.groups?.length) || 0) + filterGroups > (existingView?.queryUI?.groups?.length || 0) ) { await events.view.filterUpdated(properties) } From 41c1e8092b88c378640b54c68e7d6cf78e8e6e1f Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 9 Dec 2024 17:19:18 +0000 Subject: [PATCH 20/22] Update pro reference. --- packages/pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pro b/packages/pro index b2f2e2b9d4..9d88d38d82 160000 --- a/packages/pro +++ b/packages/pro @@ -1 +1 @@ -Subproject commit b2f2e2b9d45906744196875b87a121948e8e4c09 +Subproject commit 9d88d38d82b928f43005197e1a9ec9856572946b From 34684df87a2910adbbe7f618d679a56dcb33bee5 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 9 Dec 2024 20:59:13 +0000 Subject: [PATCH 21/22] Fix formatting. --- packages/server/src/api/routes/tests/search.spec.ts | 2 +- packages/server/src/integrations/microsoftSqlServer.ts | 2 +- packages/server/src/integrations/postgres.ts | 2 +- packages/server/src/integrations/tests/sqlAlias.spec.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/server/src/api/routes/tests/search.spec.ts b/packages/server/src/api/routes/tests/search.spec.ts index 6276d38e25..67f303aac3 100644 --- a/packages/server/src/api/routes/tests/search.spec.ts +++ b/packages/server/src/api/routes/tests/search.spec.ts @@ -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= 0 + rowCount = 0 do { const response = await config.api.row.search( tableOrViewId, diff --git a/packages/server/src/integrations/microsoftSqlServer.ts b/packages/server/src/integrations/microsoftSqlServer.ts index f3590d1885..477813239b 100644 --- a/packages/server/src/integrations/microsoftSqlServer.ts +++ b/packages/server/src/integrations/microsoftSqlServer.ts @@ -223,7 +223,7 @@ const COLUMN_DEFINITION_METADATA: Record = { class SqlServerIntegration extends Sql implements DatasourcePlus { private readonly config: MSSQLConfig - private index= 0 + private index = 0 private client?: sqlServer.ConnectionPool MASTER_TABLES = [ diff --git a/packages/server/src/integrations/postgres.ts b/packages/server/src/integrations/postgres.ts index f4db9d6959..5551d33778 100644 --- a/packages/server/src/integrations/postgres.ts +++ b/packages/server/src/integrations/postgres.ts @@ -149,7 +149,7 @@ const SCHEMA: Integration = { class PostgresIntegration extends Sql implements DatasourcePlus { private readonly client: Client private readonly config: PostgresConfig - private index= 1 + private index = 1 private open: boolean PRIMARY_KEYS_SQL = () => ` diff --git a/packages/server/src/integrations/tests/sqlAlias.spec.ts b/packages/server/src/integrations/tests/sqlAlias.spec.ts index b94f0c4c87..7c6f583762 100644 --- a/packages/server/src/integrations/tests/sqlAlias.spec.ts +++ b/packages/server/src/integrations/tests/sqlAlias.spec.ts @@ -245,7 +245,7 @@ describe("Captures of real examples", () => { tableNames.push(generator.guid()) } const aliasing = new AliasTables(tableNames) - let alias= "" + let alias = "" for (let table of tableNames) { alias = aliasing.getAlias(table) } From 1c476e0e1de625f7db09cd107358a8eb42f15197 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 9 Dec 2024 21:25:20 +0000 Subject: [PATCH 22/22] Fix types. --- packages/worker/src/tests/api/base.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/worker/src/tests/api/base.ts b/packages/worker/src/tests/api/base.ts index 460d61e70a..78ca0bf961 100644 --- a/packages/worker/src/tests/api/base.ts +++ b/packages/worker/src/tests/api/base.ts @@ -10,7 +10,7 @@ export abstract class TestAPI { config: TestConfiguration request: SuperTest - protected constructor(config: TestConfiguration) { + constructor(config: TestConfiguration) { this.config = config this.request = config.request }