diff --git a/hosting/single/Dockerfile b/hosting/single/Dockerfile index be01056b53..e8ac306c51 100644 --- a/hosting/single/Dockerfile +++ b/hosting/single/Dockerfile @@ -19,9 +19,6 @@ RUN chmod +x ./scripts/removeWorkspaceDependencies.sh RUN ./scripts/removeWorkspaceDependencies.sh packages/server/package.json RUN ./scripts/removeWorkspaceDependencies.sh packages/worker/package.json - -# We will never want to sync pro, but the script is still required -RUN echo '' > scripts/syncProPackage.js RUN jq 'del(.scripts.postinstall)' package.json > temp.json && mv temp.json package.json RUN ./scripts/removeWorkspaceDependencies.sh package.json RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install --production --frozen-lockfile diff --git a/package.json b/package.json index e60a086e17..fcd6989b6c 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,6 @@ "yargs": "^17.7.2" }, "scripts": { - "preinstall": "node scripts/syncProPackage.js", "get-past-client-version": "node scripts/getPastClientVersion.js", "setup": "git config submodule.recurse true && git submodule update && node ./hosting/scripts/setup.js && yarn && yarn build && yarn dev", "build": "NODE_OPTIONS=--max-old-space-size=1500 lerna run build --stream", @@ -107,6 +106,7 @@ "@budibase/shared-core": "0.0.0", "@budibase/string-templates": "0.0.0", "@budibase/types": "0.0.0", + "@budibase/pro": "npm:@budibase/pro@latest", "tough-cookie": "4.1.3", "node-fetch": "2.6.7", "semver": "7.5.3", diff --git a/packages/frontend-core/src/components/grid/cells/GridCell.svelte b/packages/frontend-core/src/components/grid/cells/GridCell.svelte index 74d98ec130..32a9dea83b 100644 --- a/packages/frontend-core/src/components/grid/cells/GridCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/GridCell.svelte @@ -43,6 +43,9 @@ on:mouseup on:click on:contextmenu + on:touchstart + on:touchend + on:touchcancel {style} > {#if error} diff --git a/packages/frontend-core/src/components/grid/cells/HeaderCell.svelte b/packages/frontend-core/src/components/grid/cells/HeaderCell.svelte index 6cc21fb6f5..ed742530ba 100644 --- a/packages/frontend-core/src/components/grid/cells/HeaderCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/HeaderCell.svelte @@ -12,7 +12,6 @@ export let column export let idx - export let orderable = true const { reorder, @@ -58,6 +57,7 @@ $: resetSearchValue(column.name) $: searching = searchValue != null $: debouncedUpdateFilter(searchValue) + $: orderable = !column.primaryDisplay const close = () => { open = false @@ -104,16 +104,17 @@ } const onMouseDown = e => { - if (e.button === 0 && orderable) { + if ((e.touches?.length || e.button === 0) && orderable) { timeout = setTimeout(() => { reorder.actions.startReordering(column.name, e) }, 200) } } - const onMouseUp = e => { - if (e.button === 0 && orderable) { + const onMouseUp = () => { + if (timeout) { clearTimeout(timeout) + timeout = null } } @@ -250,6 +251,9 @@ Use as display column @@ -368,7 +373,7 @@ Move right diff --git a/packages/frontend-core/src/components/grid/controls/HideColumnsButton.svelte b/packages/frontend-core/src/components/grid/controls/HideColumnsButton.svelte index 01c9dc648b..4e19e64297 100644 --- a/packages/frontend-core/src/components/grid/controls/HideColumnsButton.svelte +++ b/packages/frontend-core/src/components/grid/controls/HideColumnsButton.svelte @@ -81,6 +81,7 @@ size="S" value={column.visible} on:change={e => toggleVisibility(column, e.detail)} + disabled={column.primaryDisplay} /> {/each} diff --git a/packages/frontend-core/src/components/grid/layout/NewRow.svelte b/packages/frontend-core/src/components/grid/layout/NewRow.svelte index 66c42e5303..f5de870f7e 100644 --- a/packages/frontend-core/src/components/grid/layout/NewRow.svelte +++ b/packages/frontend-core/src/components/grid/layout/NewRow.svelte @@ -30,6 +30,7 @@ refreshing, config, filter, + inlineFilters, columnRenderMap, } = getContext("grid") @@ -157,7 +158,11 @@ {#if !visible && !selectedRowCount && $config.canAddRows} diff --git a/packages/frontend-core/src/components/grid/lib/utils.js b/packages/frontend-core/src/components/grid/lib/utils.js index c7c618e6f8..02e6d66e0e 100644 --- a/packages/frontend-core/src/components/grid/lib/utils.js +++ b/packages/frontend-core/src/components/grid/lib/utils.js @@ -20,3 +20,10 @@ export const getColumnIcon = column => { return result || "Text" } + +export const parseEventLocation = e => { + return { + x: e.clientX ?? e.touches?.[0]?.clientX, + y: e.clientY ?? e.touches?.[0]?.clientY, + } +} diff --git a/packages/frontend-core/src/components/grid/overlays/ResizeOverlay.svelte b/packages/frontend-core/src/components/grid/overlays/ResizeOverlay.svelte index 1140962583..e564108430 100644 --- a/packages/frontend-core/src/components/grid/overlays/ResizeOverlay.svelte +++ b/packages/frontend-core/src/components/grid/overlays/ResizeOverlay.svelte @@ -21,6 +21,7 @@ class="resize-slider" class:visible={activeColumn === $stickyColumn.name} on:mousedown={e => resize.actions.startResizing($stickyColumn, e)} + on:touchstart={e => resize.actions.startResizing($stickyColumn, e)} on:dblclick={() => resize.actions.resetSize($stickyColumn)} style="left:{GutterWidth + $stickyColumn.width}px;" > @@ -32,6 +33,7 @@ class="resize-slider" class:visible={activeColumn === column.name} on:mousedown={e => resize.actions.startResizing(column, e)} + on:touchstart={e => resize.actions.startResizing(column, e)} on:dblclick={() => resize.actions.resetSize(column)} style={getStyle(column, offset, $scrollLeft)} > diff --git a/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte b/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte index b10f245fcb..71d04ecbda 100644 --- a/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte +++ b/packages/frontend-core/src/components/grid/overlays/ScrollOverlay.svelte @@ -2,6 +2,7 @@ import { getContext } from "svelte" import { domDebounce } from "../../../utils/utils" import { DefaultRowHeight, ScrollBarSize } from "../lib/constants" + import { parseEventLocation } from "../lib/utils" const { scroll, @@ -55,17 +56,10 @@ $focusedCellAPI?.blur() } - const getLocation = e => { - return { - y: e.touches?.[0]?.clientY ?? e.clientY, - x: e.touches?.[0]?.clientX ?? e.clientX, - } - } - // V scrollbar drag handlers const startVDragging = e => { e.preventDefault() - initialMouse = getLocation(e).y + initialMouse = parseEventLocation(e).y initialScroll = $scrollTop document.addEventListener("mousemove", moveVDragging) document.addEventListener("touchmove", moveVDragging) @@ -75,7 +69,7 @@ closePopovers() } const moveVDragging = domDebounce(e => { - const delta = getLocation(e).y - initialMouse + const delta = parseEventLocation(e).y - initialMouse const weight = delta / availHeight const newScrollTop = initialScroll + weight * $maxScrollTop scroll.update(state => ({ @@ -94,7 +88,7 @@ // H scrollbar drag handlers const startHDragging = e => { e.preventDefault() - initialMouse = getLocation(e).x + initialMouse = parseEventLocation(e).x initialScroll = $scrollLeft document.addEventListener("mousemove", moveHDragging) document.addEventListener("touchmove", moveHDragging) @@ -104,7 +98,7 @@ closePopovers() } const moveHDragging = domDebounce(e => { - const delta = getLocation(e).x - initialMouse + const delta = parseEventLocation(e).x - initialMouse const weight = delta / availWidth const newScrollLeft = initialScroll + weight * $maxScrollLeft scroll.update(state => ({ diff --git a/packages/frontend-core/src/components/grid/stores/columns.js b/packages/frontend-core/src/components/grid/stores/columns.js index 31638e7c79..8ceaae105f 100644 --- a/packages/frontend-core/src/components/grid/stores/columns.js +++ b/packages/frontend-core/src/components/grid/stores/columns.js @@ -48,22 +48,28 @@ export const createStores = () => { export const deriveStores = context => { const { columns, stickyColumn } = context - // Derive if we have any normal columns - const hasNonAutoColumn = derived( + // Quick access to all columns + const allColumns = derived( [columns, stickyColumn], ([$columns, $stickyColumn]) => { let allCols = $columns || [] if ($stickyColumn) { allCols = [...allCols, $stickyColumn] } - const normalCols = allCols.filter(column => { - return !column.schema?.autocolumn - }) - return normalCols.length > 0 + return allCols } ) + // Derive if we have any normal columns + const hasNonAutoColumn = derived(allColumns, $allColumns => { + const normalCols = $allColumns.filter(column => { + return !column.schema?.autocolumn + }) + return normalCols.length > 0 + }) + return { + allColumns, hasNonAutoColumn, } } @@ -142,24 +148,26 @@ export const createActions = context => { } export const initialise = context => { - const { definition, columns, stickyColumn, enrichedSchema } = context + const { + definition, + columns, + stickyColumn, + allColumns, + enrichedSchema, + compact, + } = context // Merge new schema fields with existing schema in order to preserve widths - enrichedSchema.subscribe($enrichedSchema => { + const processColumns = $enrichedSchema => { if (!$enrichedSchema) { columns.set([]) stickyColumn.set(null) return } const $definition = get(definition) - const $columns = get(columns) + const $allColumns = get(allColumns) const $stickyColumn = get(stickyColumn) - - // Generate array of all columns to easily find pre-existing columns - let allColumns = $columns || [] - if ($stickyColumn) { - allColumns.push($stickyColumn) - } + const $compact = get(compact) // Find primary display let primaryDisplay @@ -171,7 +179,7 @@ export const initialise = context => { // Get field list let fields = [] Object.keys($enrichedSchema).forEach(field => { - if (field !== primaryDisplay) { + if ($compact || field !== primaryDisplay) { fields.push(field) } }) @@ -181,7 +189,7 @@ export const initialise = context => { fields .map(field => { const fieldSchema = $enrichedSchema[field] - const oldColumn = allColumns?.find(x => x.name === field) + const oldColumn = $allColumns?.find(x => x.name === field) return { name: field, label: fieldSchema.displayName || field, @@ -189,9 +197,18 @@ export const initialise = context => { width: fieldSchema.width || oldColumn?.width || DefaultColumnWidth, visible: fieldSchema.visible ?? true, order: fieldSchema.order ?? oldColumn?.order, + primaryDisplay: field === primaryDisplay, } }) .sort((a, b) => { + // If we don't have a pinned column then primary display will be in + // the normal columns list, and should be first + if (a.name === primaryDisplay) { + return -1 + } else if (b.name === primaryDisplay) { + return 1 + } + // Sort by order first const orderA = a.order const orderB = b.order @@ -214,12 +231,12 @@ export const initialise = context => { ) // Update sticky column - if (!primaryDisplay) { + if ($compact || !primaryDisplay) { stickyColumn.set(null) return } const stickySchema = $enrichedSchema[primaryDisplay] - const oldStickyColumn = allColumns?.find(x => x.name === primaryDisplay) + const oldStickyColumn = $allColumns?.find(x => x.name === primaryDisplay) stickyColumn.set({ name: primaryDisplay, label: stickySchema.displayName || primaryDisplay, @@ -228,6 +245,13 @@ export const initialise = context => { visible: true, order: 0, left: GutterWidth, + primaryDisplay: true, }) - }) + } + + // Process columns when schema changes + enrichedSchema.subscribe(processColumns) + + // Process columns when compact flag changes + compact.subscribe(() => processColumns(get(enrichedSchema))) } diff --git a/packages/frontend-core/src/components/grid/stores/reorder.js b/packages/frontend-core/src/components/grid/stores/reorder.js index fed9f4c6ef..c4a5119b6d 100644 --- a/packages/frontend-core/src/components/grid/stores/reorder.js +++ b/packages/frontend-core/src/components/grid/stores/reorder.js @@ -1,4 +1,5 @@ import { get, writable, derived } from "svelte/store" +import { parseEventLocation } from "../lib/utils" const reorderInitialState = { sourceColumn: null, @@ -33,6 +34,7 @@ export const createActions = context => { stickyColumn, ui, maxScrollLeft, + width, } = context let autoScrollInterval @@ -55,6 +57,11 @@ export const createActions = context => { x: 0, column: $stickyColumn.name, }) + } else if (!$visibleColumns[0].primaryDisplay) { + breakpoints.unshift({ + x: 0, + column: null, + }) } // Update state @@ -69,6 +76,9 @@ export const createActions = context => { // Add listeners to handle mouse movement document.addEventListener("mousemove", onReorderMouseMove) document.addEventListener("mouseup", stopReordering) + document.addEventListener("touchmove", onReorderMouseMove) + document.addEventListener("touchend", stopReordering) + document.addEventListener("touchcancel", stopReordering) // Trigger a move event immediately so ensure a candidate column is chosen onReorderMouseMove(e) @@ -77,7 +87,7 @@ export const createActions = context => { // Callback when moving the mouse when reordering columns const onReorderMouseMove = e => { // Immediately handle the current position - const x = e.clientX + const { x } = parseEventLocation(e) reorder.update(state => ({ ...state, latestX: x, @@ -86,7 +96,7 @@ export const createActions = context => { // Check if we need to start auto-scrolling const $reorder = get(reorder) - const proximityCutoff = 140 + const proximityCutoff = Math.min(140, get(width) / 6) const speedFactor = 16 const rightProximity = Math.max(0, $reorder.gridLeft + $reorder.width - x) const leftProximity = Math.max(0, x - $reorder.gridLeft) @@ -158,19 +168,22 @@ export const createActions = context => { // Ensure auto-scrolling is stopped stopAutoScroll() - // Swap position of columns - let { sourceColumn, targetColumn } = get(reorder) - moveColumn(sourceColumn, targetColumn) - - // Reset state - reorder.set(reorderInitialState) - // Remove event handlers document.removeEventListener("mousemove", onReorderMouseMove) document.removeEventListener("mouseup", stopReordering) + document.removeEventListener("touchmove", onReorderMouseMove) + document.removeEventListener("touchend", stopReordering) + document.removeEventListener("touchcancel", stopReordering) - // Save column changes - await columns.actions.saveChanges() + // Ensure there's actually a change + let { sourceColumn, targetColumn } = get(reorder) + if (sourceColumn !== targetColumn) { + moveColumn(sourceColumn, targetColumn) + await columns.actions.saveChanges() + } + + // Reset state + reorder.set(reorderInitialState) } // Moves a column after another columns. @@ -185,8 +198,7 @@ export const createActions = context => { if (--targetIdx < sourceIdx) { targetIdx++ } - state.splice(targetIdx, 0, removed[0]) - return state.slice() + return state.toSpliced(targetIdx, 0, removed[0]) }) } diff --git a/packages/frontend-core/src/components/grid/stores/resize.js b/packages/frontend-core/src/components/grid/stores/resize.js index 2dc9e0784c..157465e838 100644 --- a/packages/frontend-core/src/components/grid/stores/resize.js +++ b/packages/frontend-core/src/components/grid/stores/resize.js @@ -1,5 +1,6 @@ import { writable, get, derived } from "svelte/store" import { MinColumnWidth, DefaultColumnWidth } from "../lib/constants" +import { parseEventLocation } from "../lib/utils" const initialState = { initialMouseX: null, @@ -24,8 +25,11 @@ export const createActions = context => { // Starts resizing a certain column const startResizing = (column, e) => { + const { x } = parseEventLocation(e) + // Prevent propagation to stop reordering triggering e.stopPropagation() + e.preventDefault() ui.actions.blur() // Find and cache index @@ -39,7 +43,7 @@ export const createActions = context => { width: column.width, left: column.left, initialWidth: column.width, - initialMouseX: e.clientX, + initialMouseX: x, column: column.name, columnIdx, }) @@ -47,12 +51,16 @@ export const createActions = context => { // Add mouse event listeners to handle resizing document.addEventListener("mousemove", onResizeMouseMove) document.addEventListener("mouseup", stopResizing) + document.addEventListener("touchmove", onResizeMouseMove) + document.addEventListener("touchend", stopResizing) + document.addEventListener("touchcancel", stopResizing) } // Handler for moving the mouse to resize columns const onResizeMouseMove = e => { const { initialMouseX, initialWidth, width, columnIdx } = get(resize) - const dx = e.clientX - initialMouseX + const { x } = parseEventLocation(e) + const dx = x - initialMouseX const newWidth = Math.round(Math.max(MinColumnWidth, initialWidth + dx)) // Ignore small changes @@ -87,6 +95,9 @@ export const createActions = context => { resize.set(initialState) document.removeEventListener("mousemove", onResizeMouseMove) document.removeEventListener("mouseup", stopResizing) + document.removeEventListener("touchmove", onResizeMouseMove) + document.removeEventListener("touchend", stopResizing) + document.removeEventListener("touchcancel", stopResizing) // Persist width if it changed if ($resize.width !== $resize.initialWidth) { diff --git a/packages/frontend-core/src/components/grid/stores/ui.js b/packages/frontend-core/src/components/grid/stores/ui.js index da0558bb5b..928f93f3e1 100644 --- a/packages/frontend-core/src/components/grid/stores/ui.js +++ b/packages/frontend-core/src/components/grid/stores/ui.js @@ -98,7 +98,7 @@ export const deriveStores = context => { // Derive whether we should use the compact UI, depending on width const compact = derived([stickyColumn, width], ([$stickyColumn, $width]) => { - return ($stickyColumn?.width || 0) + $width + GutterWidth < 1100 + return ($stickyColumn?.width || 0) + $width + GutterWidth < 800 }) return { diff --git a/scripts/syncProPackage.js b/scripts/syncProPackage.js deleted file mode 100755 index 14ee222ce7..0000000000 --- a/scripts/syncProPackage.js +++ /dev/null @@ -1,41 +0,0 @@ -const fs = require("fs") -const path = require("path") -const { execSync } = require("child_process") - -let version = "0.0.0" -const localPro = fs.existsSync("packages/pro/src") -if (!localPro) { - version = "latest" -} - -// Get the list of workspaces with mismatched dependencies -const output = execSync("yarn --silent workspaces info --json", { - encoding: "utf-8", -}) -const data = JSON.parse(output) - -// Loop through each workspace and update the dependencies -Object.keys(data).forEach(workspace => { - // Loop through each dependency and update its version in package.json - const packageJsonPath = path.join(data[workspace].location, "package.json") - const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8")) - if (packageJson.version !== "0.0.0") { - // Don't change if we are not using local versions - return - } - - let hasChanges = false - - if (packageJson.dependencies && packageJson.dependencies["@budibase/pro"]) { - packageJson.dependencies["@budibase/pro"] = version - hasChanges = true - } - - // Write changes to package.json if there are any - if (hasChanges) { - fs.writeFileSync( - packageJsonPath, - JSON.stringify(packageJson, null, 2) + "\n" - ) - } -}) diff --git a/yarn.lock b/yarn.lock index b5ba401291..d833731db4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2053,6 +2053,44 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@budibase/backend-core@2.23.12": + version "0.0.0" + dependencies: + "@budibase/nano" "10.1.5" + "@budibase/pouchdb-replication-stream" "1.2.10" + "@budibase/shared-core" "0.0.0" + "@budibase/types" "0.0.0" + "@govtechsg/passport-openidconnect" "^1.0.2" + aws-cloudfront-sign "3.0.2" + aws-sdk "2.1030.0" + bcrypt "5.1.0" + bcryptjs "2.4.3" + bull "4.10.1" + correlation-id "4.0.0" + dd-trace "5.2.0" + dotenv "16.0.1" + ioredis "5.3.2" + joi "17.6.0" + jsonwebtoken "9.0.2" + koa-passport "^6.0.0" + koa-pino-logger "4.0.0" + lodash "4.17.21" + node-fetch "2.6.7" + passport-google-oauth "2.0.0" + passport-local "1.0.0" + passport-oauth2-refresh "^2.1.0" + pino "8.11.0" + pino-http "8.3.3" + posthog-node "1.3.0" + pouchdb "7.3.0" + pouchdb-find "7.2.2" + redlock "4.2.0" + rotating-file-stream "3.1.0" + sanitize-s3-objectkey "0.0.1" + semver "^7.5.4" + tar-fs "2.1.1" + uuid "^8.3.2" + "@budibase/handlebars-helpers@^0.13.1": version "0.13.1" resolved "https://registry.yarnpkg.com/@budibase/handlebars-helpers/-/handlebars-helpers-0.13.1.tgz#d02e73c0df8305cd675e70dc37f8427eb0842080" @@ -2097,6 +2135,44 @@ pouchdb-promise "^6.0.4" through2 "^2.0.0" +"@budibase/pro@npm:@budibase/pro@latest": + version "2.23.12" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.23.12.tgz#b2e813c547a5ed22b5bd86b1158159fe4b918260" + integrity sha512-DMtfkrJDSIF9V7AL6brpuWWw7Ot5XxO4YQ32ggmr0264uU9KYsTFvlFXFP3MSF2H+247ZYUouSJU76+XeC13qQ== + dependencies: + "@budibase/backend-core" "2.23.12" + "@budibase/shared-core" "2.23.12" + "@budibase/string-templates" "2.23.12" + "@budibase/types" "2.23.12" + "@koa/router" "8.0.8" + bull "4.10.1" + joi "17.6.0" + jsonwebtoken "9.0.2" + lru-cache "^7.14.1" + memorystream "^0.3.1" + node-fetch "2.6.7" + scim-patch "^0.8.1" + scim2-parse-filter "^0.2.8" + +"@budibase/shared-core@2.23.12": + version "0.0.0" + dependencies: + "@budibase/types" "0.0.0" + cron-validate "1.4.5" + +"@budibase/string-templates@2.23.12": + version "0.0.0" + dependencies: + "@budibase/handlebars-helpers" "^0.13.1" + dayjs "^1.10.8" + handlebars "^4.7.8" + lodash.clonedeep "^4.5.0" + +"@budibase/types@2.23.12": + version "0.0.0" + dependencies: + scim-patch "^0.8.1" + "@bull-board/api@5.10.2": version "5.10.2" resolved "https://registry.yarnpkg.com/@bull-board/api/-/api-5.10.2.tgz#ae8ff6918b23897bf879a6ead3683f964374c4b3" @@ -5920,6 +5996,14 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== +"@types/readable-stream@^4.0.0": + version "4.0.11" + resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-4.0.11.tgz#684f1e947c90cb6a8ad3904523d650bb66cdbb84" + integrity sha512-R3eUMUTTKoIoaz7UpYLxvZCrOmCRPRbAmoDDHKcimTEySltaJhF8hLzj4+EzyDifiX5eK6oDQGSfmNnXjxZzYQ== + dependencies: + "@types/node" "*" + safe-buffer "~5.1.1" + "@types/readdir-glob@*": version "1.1.5" resolved "https://registry.yarnpkg.com/@types/readdir-glob/-/readdir-glob-1.1.5.tgz#21a4a98898fc606cb568ad815f2a0eedc24d412a" @@ -16173,10 +16257,10 @@ mute-stream@~1.0.0: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== -mysql2@3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/mysql2/-/mysql2-3.5.2.tgz#a06050e1514e9ac15711a8b883ffd51cb44b2dc8" - integrity sha512-cptobmhYkYeTBIFp2c0piw2+gElpioga1rUw5UidHvo8yaHijMZoo8A3zyBVoo/K71f7ZFvrShA9iMIy9dCzCA== +mysql2@3.9.7: + version "3.9.7" + resolved "https://registry.yarnpkg.com/mysql2/-/mysql2-3.9.7.tgz#843755daf65b5ef08afe545fe14b8fb62824741a" + integrity sha512-KnJT8vYRcNAZv73uf9zpXqNbvBG7DJrs+1nACsjZP1HMJ1TgXEy8wnNilXAn/5i57JizXKtrUtwDB7HxT9DDpw== dependencies: denque "^2.1.0" generate-function "^2.3.1"