Merge remote-tracking branch 'origin/develop' into bindings-fixes
This commit is contained in:
commit
221cf0979a
|
@ -37,7 +37,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||||
- name: Use Node.js 14.x
|
- name: Use Node.js 14.x
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
|
@ -55,7 +55,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||||
- name: Use Node.js 14.x
|
- name: Use Node.js 14.x
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
|
@ -75,7 +75,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||||
- name: Use Node.js 14.x
|
- name: Use Node.js 14.x
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
|
@ -85,7 +85,7 @@ jobs:
|
||||||
- run: yarn test --scope=@budibase/worker --scope=@budibase/server
|
- run: yarn test --scope=@budibase/worker --scope=@budibase/server
|
||||||
- uses: codecov/codecov-action@v3
|
- uses: codecov/codecov-action@v3
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
|
token: ${{ secrets.CODECOV_TOKEN || github.token }} # not required for public repos
|
||||||
name: codecov-umbrella
|
name: codecov-umbrella
|
||||||
verbose: true
|
verbose: true
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||||
- name: Use Node.js 14.x
|
- name: Use Node.js 14.x
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
|
@ -110,7 +110,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||||
- name: Use Node.js 14.x
|
- name: Use Node.js 14.x
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
|
@ -134,7 +134,7 @@ jobs:
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Check submodule
|
- name: Check submodule
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "2.6.19-alpha.39",
|
"version": "2.6.19-alpha.44",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/backend-core",
|
"packages/backend-core",
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
"correlation-id": "4.0.0",
|
"correlation-id": "4.0.0",
|
||||||
"dotenv": "16.0.1",
|
"dotenv": "16.0.1",
|
||||||
"emitter-listener": "1.1.2",
|
"emitter-listener": "1.1.2",
|
||||||
"ioredis": "4.28.0",
|
"ioredis": "5.3.2",
|
||||||
"joi": "17.6.0",
|
"joi": "17.6.0",
|
||||||
"jsonwebtoken": "9.0.0",
|
"jsonwebtoken": "9.0.0",
|
||||||
"koa-passport": "4.1.4",
|
"koa-passport": "4.1.4",
|
||||||
|
@ -62,7 +62,6 @@
|
||||||
"@swc/jest": "^0.2.24",
|
"@swc/jest": "^0.2.24",
|
||||||
"@trendyol/jest-testcontainers": "^2.1.1",
|
"@trendyol/jest-testcontainers": "^2.1.1",
|
||||||
"@types/chance": "1.1.3",
|
"@types/chance": "1.1.3",
|
||||||
"@types/ioredis": "4.28.0",
|
|
||||||
"@types/jest": "29.5.0",
|
"@types/jest": "29.5.0",
|
||||||
"@types/koa": "2.13.4",
|
"@types/koa": "2.13.4",
|
||||||
"@types/lodash": "4.14.180",
|
"@types/lodash": "4.14.180",
|
||||||
|
@ -74,7 +73,7 @@
|
||||||
"@types/tar-fs": "2.0.1",
|
"@types/tar-fs": "2.0.1",
|
||||||
"@types/uuid": "8.3.4",
|
"@types/uuid": "8.3.4",
|
||||||
"chance": "1.1.8",
|
"chance": "1.1.8",
|
||||||
"ioredis-mock": "5.8.0",
|
"ioredis-mock": "8.7.0",
|
||||||
"jest": "29.5.0",
|
"jest": "29.5.0",
|
||||||
"jest-environment-node": "29.5.0",
|
"jest-environment-node": "29.5.0",
|
||||||
"jest-serial-runner": "^1.2.1",
|
"jest-serial-runner": "^1.2.1",
|
||||||
|
|
|
@ -97,7 +97,6 @@ const environment = {
|
||||||
REDIS_URL: process.env.REDIS_URL || "localhost:6379",
|
REDIS_URL: process.env.REDIS_URL || "localhost:6379",
|
||||||
REDIS_PASSWORD: process.env.REDIS_PASSWORD,
|
REDIS_PASSWORD: process.env.REDIS_PASSWORD,
|
||||||
REDIS_CLUSTERED: process.env.REDIS_CLUSTERED,
|
REDIS_CLUSTERED: process.env.REDIS_CLUSTERED,
|
||||||
MOCK_REDIS: process.env.MOCK_REDIS,
|
|
||||||
MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,
|
MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,
|
||||||
MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,
|
MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,
|
||||||
AWS_REGION: process.env.AWS_REGION,
|
AWS_REGION: process.env.AWS_REGION,
|
||||||
|
@ -129,6 +128,7 @@ const environment = {
|
||||||
PLUGIN_BUCKET_NAME:
|
PLUGIN_BUCKET_NAME:
|
||||||
process.env.PLUGIN_BUCKET_NAME || DefaultBucketName.PLUGINS,
|
process.env.PLUGIN_BUCKET_NAME || DefaultBucketName.PLUGINS,
|
||||||
USE_COUCH: process.env.USE_COUCH || true,
|
USE_COUCH: process.env.USE_COUCH || true,
|
||||||
|
MOCK_REDIS: process.env.MOCK_REDIS,
|
||||||
DEFAULT_LICENSE: process.env.DEFAULT_LICENSE,
|
DEFAULT_LICENSE: process.env.DEFAULT_LICENSE,
|
||||||
SERVICE: process.env.SERVICE || "budibase",
|
SERVICE: process.env.SERVICE || "budibase",
|
||||||
LOG_LEVEL: process.env.LOG_LEVEL || "info",
|
LOG_LEVEL: process.env.LOG_LEVEL || "info",
|
||||||
|
|
|
@ -21,6 +21,7 @@ export * as context from "./context"
|
||||||
export * as cache from "./cache"
|
export * as cache from "./cache"
|
||||||
export * as objectStore from "./objectStore"
|
export * as objectStore from "./objectStore"
|
||||||
export * as redis from "./redis"
|
export * as redis from "./redis"
|
||||||
|
export { Client as RedisClient } from "./redis"
|
||||||
export * as locks from "./redis/redlockImpl"
|
export * as locks from "./redis/redlockImpl"
|
||||||
export * as utils from "./utils"
|
export * as utils from "./utils"
|
||||||
export * as errors from "./errors"
|
export * as errors from "./errors"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import env from "../environment"
|
import env from "../environment"
|
||||||
|
import Redis from "ioredis"
|
||||||
// ioredis mock is all in memory
|
// ioredis mock is all in memory
|
||||||
const Redis = env.MOCK_REDIS ? require("ioredis-mock") : require("ioredis")
|
const MockRedis = require("ioredis-mock")
|
||||||
import {
|
import {
|
||||||
addDbPrefix,
|
addDbPrefix,
|
||||||
removeDbPrefix,
|
removeDbPrefix,
|
||||||
|
@ -18,7 +19,7 @@ const DEFAULT_SELECT_DB = SelectableDatabase.DEFAULT
|
||||||
// for testing just generate the client once
|
// for testing just generate the client once
|
||||||
let CLOSED = false
|
let CLOSED = false
|
||||||
let CLIENTS: { [key: number]: any } = {}
|
let CLIENTS: { [key: number]: any } = {}
|
||||||
|
0
|
||||||
let CONNECTED = false
|
let CONNECTED = false
|
||||||
|
|
||||||
// mock redis always connected
|
// mock redis always connected
|
||||||
|
@ -55,6 +56,7 @@ function connectionError(
|
||||||
* will return the ioredis client which will be ready to use.
|
* will return the ioredis client which will be ready to use.
|
||||||
*/
|
*/
|
||||||
function init(selectDb = DEFAULT_SELECT_DB) {
|
function init(selectDb = DEFAULT_SELECT_DB) {
|
||||||
|
const RedisCore = env.MOCK_REDIS ? MockRedis : Redis
|
||||||
let timeout: NodeJS.Timeout
|
let timeout: NodeJS.Timeout
|
||||||
CLOSED = false
|
CLOSED = false
|
||||||
let client = pickClient(selectDb)
|
let client = pickClient(selectDb)
|
||||||
|
@ -64,7 +66,7 @@ function init(selectDb = DEFAULT_SELECT_DB) {
|
||||||
}
|
}
|
||||||
// testing uses a single in memory client
|
// testing uses a single in memory client
|
||||||
if (env.MOCK_REDIS) {
|
if (env.MOCK_REDIS) {
|
||||||
CLIENTS[selectDb] = new Redis(getRedisOptions())
|
CLIENTS[selectDb] = new RedisCore(getRedisOptions())
|
||||||
}
|
}
|
||||||
// start the timer - only allowed 5 seconds to connect
|
// start the timer - only allowed 5 seconds to connect
|
||||||
timeout = setTimeout(() => {
|
timeout = setTimeout(() => {
|
||||||
|
@ -84,11 +86,11 @@ function init(selectDb = DEFAULT_SELECT_DB) {
|
||||||
const { redisProtocolUrl, opts, host, port } = getRedisOptions()
|
const { redisProtocolUrl, opts, host, port } = getRedisOptions()
|
||||||
|
|
||||||
if (CLUSTERED) {
|
if (CLUSTERED) {
|
||||||
client = new Redis.Cluster([{ host, port }], opts)
|
client = new RedisCore.Cluster([{ host, port }], opts)
|
||||||
} else if (redisProtocolUrl) {
|
} else if (redisProtocolUrl) {
|
||||||
client = new Redis(redisProtocolUrl)
|
client = new RedisCore(redisProtocolUrl)
|
||||||
} else {
|
} else {
|
||||||
client = new Redis(opts)
|
client = new RedisCore(opts)
|
||||||
}
|
}
|
||||||
// attach handlers
|
// attach handlers
|
||||||
client.on("end", (err: Error) => {
|
client.on("end", (err: Error) => {
|
||||||
|
|
|
@ -95,7 +95,7 @@ export function getRedisOptions() {
|
||||||
opts.port = port
|
opts.port = port
|
||||||
opts.password = password
|
opts.password = password
|
||||||
}
|
}
|
||||||
return { opts, host, port, redisProtocolUrl }
|
return { opts, host, port: parseInt(port), redisProtocolUrl }
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addDbPrefix(db: string, key: string) {
|
export function addDbPrefix(db: string, key: string) {
|
||||||
|
|
|
@ -36,6 +36,10 @@
|
||||||
selected = $tab.title
|
selected = $tab.title
|
||||||
dispatch("select", thisSelected)
|
dispatch("select", thisSelected)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
thisSelected = $tab.title
|
||||||
|
selected = $tab.title
|
||||||
|
dispatch("select", thisSelected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($tab.title !== thisSelected) {
|
if ($tab.title !== thisSelected) {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 86c32b80e08d2f19b57dcc2a3159667ac5a86c21
|
Subproject commit cd06642b860111aa1bd3443ee10076ca3abf03c3
|
|
@ -80,6 +80,7 @@
|
||||||
"global-agent": "3.0.0",
|
"global-agent": "3.0.0",
|
||||||
"google-auth-library": "7.12.0",
|
"google-auth-library": "7.12.0",
|
||||||
"google-spreadsheet": "3.2.0",
|
"google-spreadsheet": "3.2.0",
|
||||||
|
"ioredis": "5.3.2",
|
||||||
"jimp": "0.16.1",
|
"jimp": "0.16.1",
|
||||||
"joi": "17.6.0",
|
"joi": "17.6.0",
|
||||||
"js-yaml": "4.1.0",
|
"js-yaml": "4.1.0",
|
||||||
|
@ -122,8 +123,8 @@
|
||||||
"validate.js": "0.13.1",
|
"validate.js": "0.13.1",
|
||||||
"vm2": "3.9.17",
|
"vm2": "3.9.17",
|
||||||
"worker-farm": "1.7.0",
|
"worker-farm": "1.7.0",
|
||||||
"yargs": "13.2.4",
|
"xml2js": "0.5.0",
|
||||||
"xml2js": "0.5.0"
|
"yargs": "13.2.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.17.4",
|
"@babel/core": "7.17.4",
|
||||||
|
@ -137,7 +138,6 @@
|
||||||
"@types/bson": "4.2.0",
|
"@types/bson": "4.2.0",
|
||||||
"@types/global-agent": "2.1.1",
|
"@types/global-agent": "2.1.1",
|
||||||
"@types/google-spreadsheet": "3.1.5",
|
"@types/google-spreadsheet": "3.1.5",
|
||||||
"@types/ioredis": "4.28.10",
|
|
||||||
"@types/jest": "29.5.0",
|
"@types/jest": "29.5.0",
|
||||||
"@types/koa": "2.13.4",
|
"@types/koa": "2.13.4",
|
||||||
"@types/koa__router": "8.0.8",
|
"@types/koa__router": "8.0.8",
|
||||||
|
@ -157,7 +157,6 @@
|
||||||
"copyfiles": "2.4.1",
|
"copyfiles": "2.4.1",
|
||||||
"docker-compose": "0.23.17",
|
"docker-compose": "0.23.17",
|
||||||
"eslint": "6.8.0",
|
"eslint": "6.8.0",
|
||||||
"ioredis-mock": "7.2.0",
|
|
||||||
"is-wsl": "2.2.0",
|
"is-wsl": "2.2.0",
|
||||||
"jest": "29.5.0",
|
"jest": "29.5.0",
|
||||||
"jest-openapi": "0.14.2",
|
"jest-openapi": "0.14.2",
|
||||||
|
|
|
@ -21,6 +21,7 @@ import {
|
||||||
CreateDatasourceRequest,
|
CreateDatasourceRequest,
|
||||||
VerifyDatasourceRequest,
|
VerifyDatasourceRequest,
|
||||||
VerifyDatasourceResponse,
|
VerifyDatasourceResponse,
|
||||||
|
FetchDatasourceInfoRequest,
|
||||||
FetchDatasourceInfoResponse,
|
FetchDatasourceInfoResponse,
|
||||||
IntegrationBase,
|
IntegrationBase,
|
||||||
DatasourcePlus,
|
DatasourcePlus,
|
||||||
|
@ -57,6 +58,21 @@ async function getConnector(
|
||||||
return new Connector(datasource.config)
|
return new Connector(datasource.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getAndMergeDatasource(datasource: Datasource) {
|
||||||
|
let existingDatasource: undefined | Datasource
|
||||||
|
if (datasource._id) {
|
||||||
|
existingDatasource = await sdk.datasources.get(datasource._id)
|
||||||
|
}
|
||||||
|
let enrichedDatasource = datasource
|
||||||
|
if (existingDatasource) {
|
||||||
|
enrichedDatasource = sdk.datasources.mergeConfigs(
|
||||||
|
datasource,
|
||||||
|
existingDatasource
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return await sdk.datasources.enrich(enrichedDatasource)
|
||||||
|
}
|
||||||
|
|
||||||
async function buildSchemaHelper(datasource: Datasource) {
|
async function buildSchemaHelper(datasource: Datasource) {
|
||||||
const connector = (await getConnector(datasource)) as DatasourcePlus
|
const connector = (await getConnector(datasource)) as DatasourcePlus
|
||||||
await connector.buildSchema(datasource._id!, datasource.entities!)
|
await connector.buildSchema(datasource._id!, datasource.entities!)
|
||||||
|
@ -132,17 +148,7 @@ export async function verify(
|
||||||
ctx: UserCtx<VerifyDatasourceRequest, VerifyDatasourceResponse>
|
ctx: UserCtx<VerifyDatasourceRequest, VerifyDatasourceResponse>
|
||||||
) {
|
) {
|
||||||
const { datasource } = ctx.request.body
|
const { datasource } = ctx.request.body
|
||||||
let existingDatasource: undefined | Datasource
|
const enrichedDatasource = await getAndMergeDatasource(datasource)
|
||||||
if (datasource._id) {
|
|
||||||
existingDatasource = await sdk.datasources.get(datasource._id)
|
|
||||||
}
|
|
||||||
let enrichedDatasource = datasource
|
|
||||||
if (existingDatasource) {
|
|
||||||
enrichedDatasource = sdk.datasources.mergeConfigs(
|
|
||||||
datasource,
|
|
||||||
existingDatasource
|
|
||||||
)
|
|
||||||
}
|
|
||||||
const connector = await getConnector(enrichedDatasource)
|
const connector = await getConnector(enrichedDatasource)
|
||||||
if (!connector.testConnection) {
|
if (!connector.testConnection) {
|
||||||
ctx.throw(400, "Connection information verification not supported")
|
ctx.throw(400, "Connection information verification not supported")
|
||||||
|
@ -156,11 +162,11 @@ export async function verify(
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function information(
|
export async function information(
|
||||||
ctx: UserCtx<void, FetchDatasourceInfoResponse>
|
ctx: UserCtx<FetchDatasourceInfoRequest, FetchDatasourceInfoResponse>
|
||||||
) {
|
) {
|
||||||
const datasourceId = ctx.params.datasourceId
|
const { datasource } = ctx.request.body
|
||||||
const datasource = await sdk.datasources.get(datasourceId, { enriched: true })
|
const enrichedDatasource = await getAndMergeDatasource(datasource)
|
||||||
const connector = (await getConnector(datasource)) as DatasourcePlus
|
const connector = (await getConnector(enrichedDatasource)) as DatasourcePlus
|
||||||
if (!connector.getTableNames) {
|
if (!connector.getTableNames) {
|
||||||
ctx.throw(400, "Table name fetching not supported by datasource")
|
ctx.throw(400, "Table name fetching not supported by datasource")
|
||||||
}
|
}
|
||||||
|
@ -297,7 +303,7 @@ export async function update(ctx: UserCtx<any, UpdateDatasourceResponse>) {
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
datasource: await sdk.datasources.removeSecretSingle(datasource),
|
datasource: await sdk.datasources.removeSecretSingle(datasource),
|
||||||
}
|
}
|
||||||
builderSocket.emitDatasourceUpdate(ctx, datasource)
|
builderSocket?.emitDatasourceUpdate(ctx, datasource)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function save(
|
export async function save(
|
||||||
|
@ -340,7 +346,7 @@ export async function save(
|
||||||
response.error = schemaError
|
response.error = schemaError
|
||||||
}
|
}
|
||||||
ctx.body = response
|
ctx.body = response
|
||||||
builderSocket.emitDatasourceUpdate(ctx, datasource)
|
builderSocket?.emitDatasourceUpdate(ctx, datasource)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function destroyInternalTablesBySourceId(datasourceId: string) {
|
async function destroyInternalTablesBySourceId(datasourceId: string) {
|
||||||
|
@ -400,7 +406,7 @@ export async function destroy(ctx: UserCtx) {
|
||||||
|
|
||||||
ctx.message = `Datasource deleted.`
|
ctx.message = `Datasource deleted.`
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
builderSocket.emitDatasourceDeletion(ctx, datasourceId)
|
builderSocket?.emitDatasourceDeletion(ctx, datasourceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function find(ctx: UserCtx) {
|
export async function find(ctx: UserCtx) {
|
||||||
|
|
|
@ -71,7 +71,7 @@ export async function create(ctx: any) {
|
||||||
|
|
||||||
const doc = await pro.plugins.storePlugin(metadata, directory, source)
|
const doc = await pro.plugins.storePlugin(metadata, directory, source)
|
||||||
|
|
||||||
clientAppSocket.emit("plugins-update", { name, hash: doc.hash })
|
clientAppSocket?.emit("plugins-update", { name, hash: doc.hash })
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
message: "Plugin uploaded successfully",
|
message: "Plugin uploaded successfully",
|
||||||
plugins: [doc],
|
plugins: [doc],
|
||||||
|
|
|
@ -78,7 +78,7 @@ export async function save(ctx: UserCtx) {
|
||||||
ctx.eventEmitter &&
|
ctx.eventEmitter &&
|
||||||
ctx.eventEmitter.emitTable(`table:save`, appId, savedTable)
|
ctx.eventEmitter.emitTable(`table:save`, appId, savedTable)
|
||||||
ctx.body = savedTable
|
ctx.body = savedTable
|
||||||
builderSocket.emitTableUpdate(ctx, savedTable)
|
builderSocket?.emitTableUpdate(ctx, savedTable)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function destroy(ctx: UserCtx) {
|
export async function destroy(ctx: UserCtx) {
|
||||||
|
@ -91,7 +91,7 @@ export async function destroy(ctx: UserCtx) {
|
||||||
ctx.status = 200
|
ctx.status = 200
|
||||||
ctx.table = deletedTable
|
ctx.table = deletedTable
|
||||||
ctx.body = { message: `Table ${tableId} deleted.` }
|
ctx.body = { message: `Table ${tableId} deleted.` }
|
||||||
builderSocket.emitTableDeletion(ctx, tableId)
|
builderSocket?.emitTableDeletion(ctx, tableId)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function bulkImport(ctx: UserCtx) {
|
export async function bulkImport(ctx: UserCtx) {
|
||||||
|
|
|
@ -58,7 +58,7 @@ export async function save(ctx: Ctx) {
|
||||||
await handleViewEvents(existingTable.views[viewName], table.views[viewName])
|
await handleViewEvents(existingTable.views[viewName], table.views[viewName])
|
||||||
|
|
||||||
ctx.body = table.views[viewName]
|
ctx.body = table.views[viewName]
|
||||||
builderSocket.emitTableUpdate(ctx, table)
|
builderSocket?.emitTableUpdate(ctx, table)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function calculationEvents(existingView: View, newView: View) {
|
export async function calculationEvents(existingView: View, newView: View) {
|
||||||
|
@ -127,7 +127,7 @@ export async function destroy(ctx: Ctx) {
|
||||||
await events.view.deleted(view)
|
await events.view.deleted(view)
|
||||||
|
|
||||||
ctx.body = view
|
ctx.body = view
|
||||||
builderSocket.emitTableUpdate(ctx, table)
|
builderSocket?.emitTableUpdate(ctx, table)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function exportView(ctx: Ctx) {
|
export async function exportView(ctx: Ctx) {
|
||||||
|
|
|
@ -20,8 +20,8 @@ router
|
||||||
authorized(permissions.BUILDER),
|
authorized(permissions.BUILDER),
|
||||||
datasourceController.verify
|
datasourceController.verify
|
||||||
)
|
)
|
||||||
.get(
|
.post(
|
||||||
"/api/datasources/:datasourceId/info",
|
"/api/datasources/info",
|
||||||
authorized(permissions.BUILDER),
|
authorized(permissions.BUILDER),
|
||||||
datasourceController.information
|
datasourceController.information
|
||||||
)
|
)
|
||||||
|
|
|
@ -114,8 +114,8 @@ describe("/views", () => {
|
||||||
expect(res.body.tableId).toBe(table._id)
|
expect(res.body.tableId).toBe(table._id)
|
||||||
|
|
||||||
const updatedTable = await config.getTable(table._id)
|
const updatedTable = await config.getTable(table._id)
|
||||||
expect(updatedTable.views).toEqual({
|
const expectedObj = expect.objectContaining({
|
||||||
TestView: {
|
TestView: expect.objectContaining({
|
||||||
field: "Price",
|
field: "Price",
|
||||||
calculation: "stats",
|
calculation: "stats",
|
||||||
tableId: table._id,
|
tableId: table._id,
|
||||||
|
@ -143,8 +143,9 @@ describe("/views", () => {
|
||||||
type: "string",
|
type: "string",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}),
|
||||||
})
|
})
|
||||||
|
expect(updatedTable.views).toEqual(expectedObj)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ const config = setup.getConfig()!
|
||||||
jest.setTimeout(30000)
|
jest.setTimeout(30000)
|
||||||
|
|
||||||
jest.unmock("pg")
|
jest.unmock("pg")
|
||||||
|
jest.mock("../websockets")
|
||||||
|
|
||||||
describe("postgres integrations", () => {
|
describe("postgres integrations", () => {
|
||||||
let makeRequest: MakeRequestResponse,
|
let makeRequest: MakeRequestResponse,
|
||||||
|
@ -1055,13 +1056,12 @@ describe("postgres integrations", () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("GET /api/datasources/:datasourceId/info", () => {
|
describe("POST /api/datasources/info", () => {
|
||||||
it("should fetch information about postgres datasource", async () => {
|
it("should fetch information about postgres datasource", async () => {
|
||||||
const primaryName = primaryPostgresTable.name
|
const primaryName = primaryPostgresTable.name
|
||||||
const response = await makeRequest(
|
const response = await makeRequest("post", "/api/datasources/info", {
|
||||||
"get",
|
datasource: postgresDatasource,
|
||||||
`/api/datasources/${postgresDatasource._id}/info`
|
})
|
||||||
)
|
|
||||||
expect(response.status).toBe(200)
|
expect(response.status).toBe(200)
|
||||||
expect(response.body.tableNames).toBeDefined()
|
expect(response.body.tableNames).toBeDefined()
|
||||||
expect(response.body.tableNames.indexOf(primaryName)).not.toBe(-1)
|
expect(response.body.tableNames.indexOf(primaryName)).not.toBe(-1)
|
||||||
|
|
|
@ -177,7 +177,13 @@ class RedisIntegration {
|
||||||
const pipeline = this.client.pipeline(pipelineCommands)
|
const pipeline = this.client.pipeline(pipelineCommands)
|
||||||
const result = await pipeline.exec()
|
const result = await pipeline.exec()
|
||||||
|
|
||||||
return result.map((output: string | string[]) => output[1])
|
return result?.map((output: any) => {
|
||||||
|
if (typeof output === "string") {
|
||||||
|
return output
|
||||||
|
} else if (Array.isArray(output)) {
|
||||||
|
return output[1]
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,6 @@ export async function processUploaded(plugin: FileType, source?: PluginSource) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const doc = await pro.plugins.storePlugin(metadata, directory, source)
|
const doc = await pro.plugins.storePlugin(metadata, directory, source)
|
||||||
clientAppSocket.emit("plugin-update", { name: doc.name, hash: doc.hash })
|
clientAppSocket?.emit("plugin-update", { name: doc.name, hash: doc.hash })
|
||||||
return doc
|
return doc
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,10 +44,18 @@ function getLoopIterations(loopStep: LoopStep) {
|
||||||
if (!binding) {
|
if (!binding) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
const isString = typeof binding === "string"
|
||||||
|
try {
|
||||||
|
if (isString) {
|
||||||
|
binding = JSON.parse(binding)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// ignore error - wasn't able to parse
|
||||||
|
}
|
||||||
if (Array.isArray(binding)) {
|
if (Array.isArray(binding)) {
|
||||||
return binding.length
|
return binding.length
|
||||||
}
|
}
|
||||||
if (typeof binding === "string") {
|
if (isString) {
|
||||||
return automationUtils.stringSplit(binding).length
|
return automationUtils.stringSplit(binding).length
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
import { redis } from "@budibase/backend-core"
|
import { redis, RedisClient } from "@budibase/backend-core"
|
||||||
import { getGlobalIDFromUserMetadataID } from "../db/utils"
|
import { getGlobalIDFromUserMetadataID } from "../db/utils"
|
||||||
import { ContextUser } from "@budibase/types"
|
import { ContextUser } from "@budibase/types"
|
||||||
|
import env from "../environment"
|
||||||
|
|
||||||
const APP_DEV_LOCK_SECONDS = 600
|
const APP_DEV_LOCK_SECONDS = 600
|
||||||
const AUTOMATION_TEST_FLAG_SECONDS = 60
|
const AUTOMATION_TEST_FLAG_SECONDS = 60
|
||||||
let devAppClient: any, debounceClient: any, flagClient: any
|
let devAppClient: RedisClient,
|
||||||
|
debounceClient: RedisClient,
|
||||||
|
flagClient: RedisClient
|
||||||
|
|
||||||
// We need to maintain a duplicate client for socket.io pub/sub
|
// We need to maintain a duplicate client for socket.io pub/sub
|
||||||
let socketClient: any
|
let socketClient: RedisClient
|
||||||
let socketSubClient: any
|
let socketSubClient: any
|
||||||
|
|
||||||
// We init this as we want to keep the connection open all the time
|
// We init this as we want to keep the connection open all the time
|
||||||
|
@ -22,7 +25,9 @@ export async function init() {
|
||||||
|
|
||||||
// Duplicate the socket client for pub/sub
|
// Duplicate the socket client for pub/sub
|
||||||
socketClient = await redis.clients.getSocketClient()
|
socketClient = await redis.clients.getSocketClient()
|
||||||
|
if (!env.isTest()) {
|
||||||
socketSubClient = socketClient.getClient().duplicate()
|
socketSubClient = socketClient.getClient().duplicate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function shutdown() {
|
export async function shutdown() {
|
||||||
|
|
|
@ -14,9 +14,9 @@ export default class BuilderSocket extends BaseSocket {
|
||||||
super(app, server, "/socket/builder", [authorized(permissions.BUILDER)])
|
super(app, server, "/socket/builder", [authorized(permissions.BUILDER)])
|
||||||
}
|
}
|
||||||
|
|
||||||
async onConnect(socket: Socket) {
|
async onConnect(socket?: Socket) {
|
||||||
// Initial identification of selected app
|
// Initial identification of selected app
|
||||||
socket.on(BuilderSocketEvent.SelectApp, async (appId, callback) => {
|
socket?.on(BuilderSocketEvent.SelectApp, async (appId, callback) => {
|
||||||
await this.joinRoom(socket, appId)
|
await this.joinRoom(socket, appId)
|
||||||
|
|
||||||
// Reply with all users in current room
|
// Reply with all users in current room
|
||||||
|
@ -49,14 +49,14 @@ export default class BuilderSocket extends BaseSocket {
|
||||||
this.io
|
this.io
|
||||||
.in(ctx.appId)
|
.in(ctx.appId)
|
||||||
.emit(BuilderSocketEvent.TableChange, { id: table._id, table })
|
.emit(BuilderSocketEvent.TableChange, { id: table._id, table })
|
||||||
gridSocket.emitTableUpdate(table)
|
gridSocket?.emitTableUpdate(table)
|
||||||
}
|
}
|
||||||
|
|
||||||
emitTableDeletion(ctx: any, id: string) {
|
emitTableDeletion(ctx: any, id: string) {
|
||||||
this.io
|
this.io
|
||||||
.in(ctx.appId)
|
.in(ctx.appId)
|
||||||
.emit(BuilderSocketEvent.TableChange, { id, table: null })
|
.emit(BuilderSocketEvent.TableChange, { id, table: null })
|
||||||
gridSocket.emitTableDeletion(id)
|
gridSocket?.emitTableDeletion(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
emitDatasourceUpdate(ctx: any, datasource: Datasource) {
|
emitDatasourceUpdate(ctx: any, datasource: Datasource) {
|
||||||
|
|
|
@ -3,15 +3,19 @@ import Koa from "koa"
|
||||||
import ClientAppSocket from "./client"
|
import ClientAppSocket from "./client"
|
||||||
import GridSocket from "./grid"
|
import GridSocket from "./grid"
|
||||||
import BuilderSocket from "./builder"
|
import BuilderSocket from "./builder"
|
||||||
|
import env from "../environment"
|
||||||
|
|
||||||
let clientAppSocket: ClientAppSocket
|
let clientAppSocket: ClientAppSocket | undefined
|
||||||
let gridSocket: GridSocket
|
let gridSocket: GridSocket | undefined
|
||||||
let builderSocket: BuilderSocket
|
let builderSocket: BuilderSocket | undefined
|
||||||
|
|
||||||
export const initialise = (app: Koa, server: http.Server) => {
|
export const initialise = (app: Koa, server: http.Server) => {
|
||||||
|
// have to remove these for testing until ioredis-mock can be fully removed
|
||||||
|
if (!env.isTest()) {
|
||||||
clientAppSocket = new ClientAppSocket(app, server)
|
clientAppSocket = new ClientAppSocket(app, server)
|
||||||
gridSocket = new GridSocket(app, server)
|
gridSocket = new GridSocket(app, server)
|
||||||
builderSocket = new BuilderSocket(app, server)
|
builderSocket = new BuilderSocket(app, server)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { clientAppSocket, gridSocket, builderSocket }
|
export { clientAppSocket, gridSocket, builderSocket }
|
||||||
|
|
|
@ -23,6 +23,10 @@ export interface VerifyDatasourceResponse {
|
||||||
error?: string
|
error?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface FetchDatasourceInfoRequest {
|
||||||
|
datasource: Datasource
|
||||||
|
}
|
||||||
|
|
||||||
export interface FetchDatasourceInfoResponse {
|
export interface FetchDatasourceInfoResponse {
|
||||||
tableNames: string[]
|
tableNames: string[]
|
||||||
}
|
}
|
||||||
|
|
60
yarn.lock
60
yarn.lock
|
@ -2591,6 +2591,16 @@
|
||||||
resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340"
|
resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340"
|
||||||
integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==
|
integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==
|
||||||
|
|
||||||
|
"@ioredis/as-callback@^3.0.0":
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@ioredis/as-callback/-/as-callback-3.0.0.tgz#b96c9b05e6701e85ec6a5e62fa254071b0aec97f"
|
||||||
|
integrity sha512-Kqv1rZ3WbgOrS+hgzJ5xG5WQuhvzzSTRYvNeyPMLOAM78MHSnuKI20JeJGbpuAt//LCuP0vsexZcorqW7kWhJg==
|
||||||
|
|
||||||
|
"@ioredis/commands@^1.1.1", "@ioredis/commands@^1.2.0":
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.2.0.tgz#6d61b3097470af1fdbbe622795b8921d42018e11"
|
||||||
|
integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==
|
||||||
|
|
||||||
"@isaacs/string-locale-compare@^1.1.0":
|
"@isaacs/string-locale-compare@^1.1.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz#291c227e93fd407a96ecd59879a35809120e432b"
|
resolved "https://registry.yarnpkg.com/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz#291c227e93fd407a96ecd59879a35809120e432b"
|
||||||
|
@ -5649,13 +5659,6 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.1.tgz#20172f9578b225f6c7da63446f56d4ce108d5a65"
|
resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.1.tgz#20172f9578b225f6c7da63446f56d4ce108d5a65"
|
||||||
integrity sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==
|
integrity sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==
|
||||||
|
|
||||||
"@types/ioredis@4.28.0":
|
|
||||||
version "4.28.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/ioredis/-/ioredis-4.28.0.tgz#609b2ea0d91231df2dd7f67dd77436bc72584911"
|
|
||||||
integrity sha512-HSA/JQivJgV0e+353gvgu6WVoWvGRe0HyHOnAN2AvbVIhUlJBhNnnkP8gEEokrDWrxywrBkwo8NuDZ6TVPL9XA==
|
|
||||||
dependencies:
|
|
||||||
"@types/node" "*"
|
|
||||||
|
|
||||||
"@types/ioredis@4.28.10":
|
"@types/ioredis@4.28.10":
|
||||||
version "4.28.10"
|
version "4.28.10"
|
||||||
resolved "https://registry.yarnpkg.com/@types/ioredis/-/ioredis-4.28.10.tgz#40ceb157a4141088d1394bb87c98ed09a75a06ff"
|
resolved "https://registry.yarnpkg.com/@types/ioredis/-/ioredis-4.28.10.tgz#40ceb157a4141088d1394bb87c98ed09a75a06ff"
|
||||||
|
@ -11956,7 +11959,7 @@ fecha@^4.2.0:
|
||||||
resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd"
|
resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd"
|
||||||
integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==
|
integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==
|
||||||
|
|
||||||
fengari-interop@^0.1.2, fengari-interop@^0.1.3:
|
fengari-interop@^0.1.3:
|
||||||
version "0.1.3"
|
version "0.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/fengari-interop/-/fengari-interop-0.1.3.tgz#3ad37a90e7430b69b365441e9fc0ba168942a146"
|
resolved "https://registry.yarnpkg.com/fengari-interop/-/fengari-interop-0.1.3.tgz#3ad37a90e7430b69b365441e9fc0ba168942a146"
|
||||||
integrity sha512-EtZ+oTu3kEwVJnoymFPBVLIbQcCoy9uWCVnMA6h3M/RqHkUBsLYp29+RRHf9rKr6GwjubWREU1O7RretFIXjHw==
|
integrity sha512-EtZ+oTu3kEwVJnoymFPBVLIbQcCoy9uWCVnMA6h3M/RqHkUBsLYp29+RRHf9rKr6GwjubWREU1O7RretFIXjHw==
|
||||||
|
@ -13993,39 +13996,28 @@ invert-kv@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
|
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
|
||||||
integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==
|
integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==
|
||||||
|
|
||||||
ioredis-mock@5.8.0:
|
ioredis-mock@8.7.0:
|
||||||
version "5.8.0"
|
version "8.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/ioredis-mock/-/ioredis-mock-5.8.0.tgz#99d3f0fe58419c2ff15c81cb4e13709aff8f2a44"
|
resolved "https://registry.yarnpkg.com/ioredis-mock/-/ioredis-mock-8.7.0.tgz#9877a85e0d233e1b49123d1c6e320df01e9a1d36"
|
||||||
integrity sha512-PokVyNC/d3qaAyHAdf+Ex4HHBe7GdaSGrcn8pP7ran+pVmSrJ6Aofwm7Od5bQ5JtjDSiylEtIoZzEPYIjUKMHA==
|
integrity sha512-BJcSjkR3sIMKbH93fpFzwlWi/jl1kd5I3vLvGQxnJ/W/6bD2ksrxnyQN186ljAp3Foz4p1ivViDE3rZeKEAluA==
|
||||||
dependencies:
|
|
||||||
fengari "^0.1.4"
|
|
||||||
fengari-interop "^0.1.2"
|
|
||||||
lodash "^4.17.21"
|
|
||||||
standard-as-callback "^2.1.0"
|
|
||||||
|
|
||||||
ioredis-mock@7.2.0:
|
|
||||||
version "7.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/ioredis-mock/-/ioredis-mock-7.2.0.tgz#48f006c07ef7f1f93f75e60d8f9035fa46c4ef0a"
|
|
||||||
integrity sha512-xzABBG3NhfDBGxH1KX9n6vs7WGNn9lhcxMT3b+vjynVImxlUV+vOXU+tjGzSUnGmx4IYllA8RqbXN8z6ROMPVA==
|
|
||||||
dependencies:
|
dependencies:
|
||||||
|
"@ioredis/as-callback" "^3.0.0"
|
||||||
|
"@ioredis/commands" "^1.2.0"
|
||||||
fengari "^0.1.4"
|
fengari "^0.1.4"
|
||||||
fengari-interop "^0.1.3"
|
fengari-interop "^0.1.3"
|
||||||
redis-commands "^1.7.0"
|
semver "^7.3.8"
|
||||||
standard-as-callback "^2.1.0"
|
|
||||||
|
|
||||||
ioredis@4.28.0:
|
ioredis@5.3.2:
|
||||||
version "4.28.0"
|
version "5.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.28.0.tgz#5a2be3f37ff2075e2332f280eaeb02ab4d9ff0d3"
|
resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.3.2.tgz#9139f596f62fc9c72d873353ac5395bcf05709f7"
|
||||||
integrity sha512-I+zkeeWp3XFgPT2CtJKxvaF5FjGBGt4yGYljRjQecdQKteThuAsKqffeF1lgHVlYnuNeozRbPOCDNZ7tDWPeig==
|
integrity sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA==
|
||||||
dependencies:
|
dependencies:
|
||||||
|
"@ioredis/commands" "^1.1.1"
|
||||||
cluster-key-slot "^1.1.0"
|
cluster-key-slot "^1.1.0"
|
||||||
debug "^4.3.1"
|
debug "^4.3.4"
|
||||||
denque "^1.1.0"
|
denque "^2.1.0"
|
||||||
lodash.defaults "^4.2.0"
|
lodash.defaults "^4.2.0"
|
||||||
lodash.flatten "^4.4.0"
|
|
||||||
lodash.isarguments "^3.1.0"
|
lodash.isarguments "^3.1.0"
|
||||||
p-map "^2.1.0"
|
|
||||||
redis-commands "1.7.0"
|
|
||||||
redis-errors "^1.2.0"
|
redis-errors "^1.2.0"
|
||||||
redis-parser "^3.0.0"
|
redis-parser "^3.0.0"
|
||||||
standard-as-callback "^2.1.0"
|
standard-as-callback "^2.1.0"
|
||||||
|
@ -21759,7 +21751,7 @@ redent@^3.0.0:
|
||||||
indent-string "^4.0.0"
|
indent-string "^4.0.0"
|
||||||
strip-indent "^3.0.0"
|
strip-indent "^3.0.0"
|
||||||
|
|
||||||
redis-commands@1.7.0, redis-commands@^1.7.0:
|
redis-commands@1.7.0:
|
||||||
version "1.7.0"
|
version "1.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.7.0.tgz#15a6fea2d58281e27b1cd1acfb4b293e278c3a89"
|
resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.7.0.tgz#15a6fea2d58281e27b1cd1acfb4b293e278c3a89"
|
||||||
integrity sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==
|
integrity sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==
|
||||||
|
|
Loading…
Reference in New Issue