mirror of
https://github.com/lowdefy/lowdefy.git
synced 2025-02-05 13:59:56 +08:00
fix: Refactored connection-redis plugin to have non restrictive schemas.
This commit is contained in:
parent
ee2315d69c
commit
f8d9f8e149
@ -23,47 +23,33 @@ test('All requests are present', () => {
|
||||
expect(Redis.requests.Redis).toBeDefined();
|
||||
});
|
||||
|
||||
test('valid connection schema, with url', () => {
|
||||
test('valid connection schema, with string', () => {
|
||||
const connection = {
|
||||
url: '/path',
|
||||
connection: '/path',
|
||||
};
|
||||
expect(validate({ schema, data: connection })).toEqual({ valid: true });
|
||||
});
|
||||
|
||||
test('valid connection schema, with socket', () => {
|
||||
test('valid connection schema, with object', () => {
|
||||
const connection = {
|
||||
socket: {
|
||||
host: 'https://example.com/redis',
|
||||
port: 6379,
|
||||
connection: {
|
||||
socket: {
|
||||
host: 'https://example.com/redis',
|
||||
port: 6379,
|
||||
},
|
||||
username: 'username',
|
||||
password: 'password',
|
||||
database: 5,
|
||||
},
|
||||
username: 'username',
|
||||
password: 'password',
|
||||
database: 5,
|
||||
};
|
||||
expect(validate({ schema, data: connection })).toEqual({ valid: true });
|
||||
});
|
||||
|
||||
test('invalid connection schema, with all properties', () => {
|
||||
test('invalid connection schema', () => {
|
||||
const connection = {
|
||||
url: '/path',
|
||||
socket: {
|
||||
host: 'https://example.com/redis',
|
||||
port: 6379,
|
||||
},
|
||||
username: 'username',
|
||||
password: 'password',
|
||||
database: 0,
|
||||
connection: null,
|
||||
};
|
||||
expect(() => validate({ schema, data: connection })).toThrow(
|
||||
'Redis connection should have required property "url" or "socket.host" and "socket.port".'
|
||||
);
|
||||
});
|
||||
|
||||
test('url is not a string', () => {
|
||||
const connection = {
|
||||
url: true,
|
||||
};
|
||||
expect(() => validate({ schema, data: connection })).toThrow(
|
||||
'Redis property "url" should be a string.'
|
||||
'Redis connection property "connection" should be a string or object.'
|
||||
);
|
||||
});
|
||||
|
@ -19,23 +19,49 @@ import { createClient } from 'redis';
|
||||
import schema from './schema.js';
|
||||
|
||||
async function Redis({ request, connection }) {
|
||||
const client = new createClient(connection);
|
||||
const connectionObject = type.isString(connection.connection)
|
||||
? { url: connection.connection }
|
||||
: connection.connection;
|
||||
|
||||
const client = new createClient(connectionObject);
|
||||
client.on('error', (error) => {
|
||||
throw error;
|
||||
});
|
||||
|
||||
const { command, parameters, modifiers } = request;
|
||||
|
||||
try {
|
||||
const { command, params, modifiers } = request;
|
||||
await client.connect();
|
||||
const commandParams = type.isArray(params) ? params : [params];
|
||||
const commandReturn = await client[command.toUpperCase()](...commandParams, modifiers);
|
||||
} catch (error) {
|
||||
throw new Error(`Connection refused.`);
|
||||
}
|
||||
|
||||
if (!type.isFunction(client[command.toUpperCase()])) {
|
||||
throw new Error(`Invalid redis command "${command}".`);
|
||||
}
|
||||
|
||||
if (!type.isArray(parameters)) {
|
||||
throw new Error(
|
||||
`Invalid command, command "${command}" parameters should be an array, received ${JSON.stringify(
|
||||
parameters
|
||||
)}.`
|
||||
);
|
||||
}
|
||||
|
||||
const upperCaseModifiers = Object.entries(modifiers).reduce((acc, [key, value]) => {
|
||||
acc[key.toUpperCase()] = value;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
try {
|
||||
const commandReturn = await client[command.toUpperCase()](...parameters, upperCaseModifiers);
|
||||
await client.quit();
|
||||
return commandReturn;
|
||||
} catch (error) {
|
||||
if (error.code !== 'ECONNREFUSED') {
|
||||
await client.quit();
|
||||
}
|
||||
throw error;
|
||||
client.quit();
|
||||
throw new Error(
|
||||
`Invalid command "${command}" parameters, received ${JSON.stringify(parameters)}.`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,59 +21,30 @@ const { checkRead, checkWrite } = Redis.meta;
|
||||
const schema = Redis.schema;
|
||||
|
||||
test('valid request schema, with url', () => {
|
||||
const connection = {
|
||||
const request = {
|
||||
command: 'set',
|
||||
params: ['key', 10],
|
||||
parameters: ['key', 10],
|
||||
};
|
||||
expect(validate({ schema, data: connection })).toEqual({ valid: true });
|
||||
expect(validate({ schema, data: request })).toEqual({ valid: true });
|
||||
});
|
||||
|
||||
test('command is not a string', () => {
|
||||
const connection = {
|
||||
const request = {
|
||||
command: true,
|
||||
params: ['key', 'value'],
|
||||
parameters: ['key', 'value'],
|
||||
};
|
||||
expect(() => validate({ schema, data: connection })).toThrow(
|
||||
expect(() => validate({ schema, data: request })).toThrow(
|
||||
'Redis request property "command" should be a string.'
|
||||
);
|
||||
});
|
||||
|
||||
test('command is not valid', () => {
|
||||
const connection = {
|
||||
command: 'notValidCommand',
|
||||
params: ['key', 'value'],
|
||||
};
|
||||
expect(() => validate({ schema, data: connection })).toThrow(
|
||||
'Redis request property "command" is not a valid value.'
|
||||
);
|
||||
});
|
||||
|
||||
test('params are not valid for command', () => {
|
||||
const connection = {
|
||||
command: 'get',
|
||||
params: ['key', 'value'],
|
||||
};
|
||||
expect(() => validate({ schema, data: connection })).toThrow(
|
||||
'Redis request property "params" should be a string.'
|
||||
);
|
||||
});
|
||||
|
||||
test('params are not valid for command', () => {
|
||||
const connection = {
|
||||
test('parameters is not an array', () => {
|
||||
const request = {
|
||||
command: 'set',
|
||||
params: 'key',
|
||||
parameters: 'string',
|
||||
};
|
||||
expect(() => validate({ schema, data: connection })).toThrow(
|
||||
'Redis request property "params" should be an array.'
|
||||
);
|
||||
});
|
||||
|
||||
test('params are not present', () => {
|
||||
const connection = {
|
||||
command: 'set',
|
||||
};
|
||||
expect(() => validate({ schema, data: connection })).toThrow(
|
||||
'Redis request property "params" should be present.'
|
||||
expect(() => validate({ schema, data: request })).toThrow(
|
||||
'Redis request property "parameters" should be an array.'
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -21,11 +21,16 @@ export default {
|
||||
properties: {
|
||||
command: {
|
||||
type: 'string',
|
||||
enum: ['get', 'set', 'hget', 'hset'],
|
||||
description: 'Redis command to execute.',
|
||||
errorMessage: {
|
||||
type: 'Redis request property "command" should be a string.',
|
||||
enum: 'Redis request property "command" is not a valid value.',
|
||||
},
|
||||
},
|
||||
parameters: {
|
||||
type: 'array',
|
||||
description: 'The parameters to use with the command.',
|
||||
errorMessage: {
|
||||
type: 'Redis request property "parameters" should be an array.',
|
||||
},
|
||||
},
|
||||
modifiers: {
|
||||
@ -38,37 +43,6 @@ export default {
|
||||
},
|
||||
},
|
||||
required: ['command'],
|
||||
if: {
|
||||
properties: { command: { enum: ['get'] } },
|
||||
},
|
||||
then: {
|
||||
properties: {
|
||||
params: {
|
||||
type: 'string',
|
||||
errorMessage: {
|
||||
type: 'Redis request property "params" should be a string.',
|
||||
},
|
||||
},
|
||||
},
|
||||
required: ['params'],
|
||||
errorMessage: {
|
||||
required: 'Redis request property "params" should be present.',
|
||||
},
|
||||
},
|
||||
else: {
|
||||
properties: {
|
||||
params: {
|
||||
type: 'array',
|
||||
errorMessage: {
|
||||
type: 'Redis request property "params" should be an array.',
|
||||
},
|
||||
},
|
||||
},
|
||||
required: ['params'],
|
||||
errorMessage: {
|
||||
required: 'Redis request property "params" should be present.',
|
||||
},
|
||||
},
|
||||
errorMessage: {
|
||||
type: 'Redis request properties should be an object.',
|
||||
},
|
||||
|
@ -19,74 +19,16 @@ export default {
|
||||
title: 'Lowdefy Connection Schema - Redis',
|
||||
type: 'object',
|
||||
properties: {
|
||||
url: {
|
||||
type: 'string',
|
||||
description:
|
||||
'The redis server url to connect to (redis[s]://[[username][:password]@][host][:port][/db-number])',
|
||||
connection: {
|
||||
type: ['string', 'object'],
|
||||
description: 'Connection object or string to pass to the redis client.',
|
||||
errorMessage: {
|
||||
type: 'Redis property "url" should be a string.',
|
||||
},
|
||||
},
|
||||
socket: {
|
||||
type: 'object',
|
||||
description: 'Object defining socket connection properties.',
|
||||
properties: {
|
||||
host: {
|
||||
type: 'string',
|
||||
description: 'Hostname to connect to',
|
||||
default: 'localhost',
|
||||
errorMessage: {
|
||||
type: 'Redis property "socket.host" should be a string.',
|
||||
},
|
||||
},
|
||||
port: {
|
||||
type: 'number',
|
||||
description: 'Port to connect to',
|
||||
default: 6379,
|
||||
errorMessage: {
|
||||
type: 'Redis property "socket.port" should be a number.',
|
||||
},
|
||||
},
|
||||
},
|
||||
required: ['host', 'port'],
|
||||
errorMessage: {
|
||||
type: 'Redis property "socket" should be an object.',
|
||||
},
|
||||
},
|
||||
username: {
|
||||
type: 'string',
|
||||
description: 'ACL username',
|
||||
errorMessage: {
|
||||
type: 'Redis property "username" should be a string.',
|
||||
},
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
description: 'ACL password',
|
||||
errorMessage: {
|
||||
type: 'Redis property "password" should be a string.',
|
||||
},
|
||||
},
|
||||
database: {
|
||||
type: 'number',
|
||||
description: 'Database number to connect to',
|
||||
minimum: 0,
|
||||
errorMessage: {
|
||||
type: 'Redis property "database" should be a number.',
|
||||
type: 'Redis connection property "connection" should be a string or object.',
|
||||
},
|
||||
},
|
||||
},
|
||||
oneOf: [
|
||||
{
|
||||
required: ['url'],
|
||||
},
|
||||
{
|
||||
required: ['socket'],
|
||||
},
|
||||
],
|
||||
require: ['connection'],
|
||||
errorMessage: {
|
||||
type: 'Redis connection properties should be an object.',
|
||||
oneOf:
|
||||
'Redis connection should have required property "url" or "socket.host" and "socket.port".',
|
||||
},
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user