@restroom-mw/db
Advanced tools
Comparing version 0.13.1-b58baa9.9 to 0.13.1-d29cf33.33
@@ -16,22 +16,7 @@ "use strict"; | ||
} | ||
const ACTIONS = { | ||
GET_URI_KEYS: "have a database uri named {}", | ||
GET_TABLE_KEYS: "have a database table named {}", | ||
GET_RECORD: "read the record {} of the table {} of the database {} and save the result into {}", | ||
SAVE_OUTPUT: "save the output into the database {} into the table {}", | ||
SAVE_VAR: "save the {} into the database {} into the table {}", | ||
}; | ||
const parse = (o) => { | ||
try { | ||
return JSON.parse(o); | ||
} | ||
catch (e) { | ||
throw new Error(`[DATABASE] Error in JSON format "${o}"`); | ||
} | ||
}; | ||
; | ||
exports.default = (req, res, next) => { | ||
try { | ||
const rr = new core_1.Restroom(req, res); | ||
let keysContent; | ||
let dataContent; | ||
const parse = (o) => rr.safeJSONParse(o, `[DATABASE] Error in JSON format "${o}"`); | ||
let content = {}; | ||
@@ -41,29 +26,33 @@ let contentKeys; | ||
let tableKeys = []; | ||
const validate = (queries) => { | ||
runChecks(queries, dbUriKeys, contentKeys, "database"); | ||
runChecks(queries, tableKeys, contentKeys, "table"); | ||
}; | ||
rr.onBefore((params) => __awaiter(void 0, void 0, void 0, function* () { | ||
const { zencode, keys, data } = params; | ||
keysContent = | ||
typeof keys === "undefined" | ||
? {} | ||
: keys && typeof keys === "object" | ||
? keys | ||
: parse(keys); | ||
dataContent = | ||
typeof data === "undefined" | ||
? {} | ||
: data && typeof data === "object" | ||
? data | ||
: parse(data); | ||
content = Object.assign(Object.assign({}, dataContent), keysContent); | ||
let { zencode, keys, data } = params; | ||
if (!data) | ||
data = {}; | ||
content = rr.combineDataKeys(Object.assign({}, data), keys); | ||
contentKeys = Object.keys(content); | ||
if (zencode.match(ACTIONS.GET_URI_KEYS)) { | ||
dbUriKeys = zencode.paramsOf(ACTIONS.GET_URI_KEYS); | ||
if (zencode.match("have a database uri named {}" /* ACTIONS.GET_URI_KEYS */)) { | ||
dbUriKeys = zencode.paramsOf("have a database uri named {}" /* ACTIONS.GET_URI_KEYS */); | ||
} | ||
if (zencode.match(ACTIONS.GET_TABLE_KEYS)) { | ||
tableKeys = zencode.paramsOf(ACTIONS.GET_TABLE_KEYS); | ||
if (zencode.match("have a database table named {}" /* ACTIONS.GET_TABLE_KEYS */)) { | ||
tableKeys = zencode.paramsOf("have a database table named {}" /* ACTIONS.GET_TABLE_KEYS */); | ||
} | ||
if (zencode.match(ACTIONS.GET_RECORD)) { | ||
const dbAllRecordData = zencode.paramsOf(ACTIONS.GET_RECORD); | ||
//create object(s) with the FOUR values of each GET_RECORD | ||
if (zencode.match("execute the SQL statement named {} on the database named {} and save the result into {}" /* ACTIONS.EXECUTE_SQL */)) { | ||
const promises = zencode.chunkedParamsOf("execute the SQL statement named {} on the database named {} and save the result into {}" /* ACTIONS.EXECUTE_SQL */, 3).map(([statement, database, output]) => __awaiter(void 0, void 0, void 0, function* () { | ||
const db = new sequelize_1.Sequelize(content[database]); | ||
const t = yield db.transaction(); | ||
const [o, m] = yield db.query(content[statement], { transaction: t }); | ||
yield t.commit(); | ||
data[output] = JSON.stringify(o ? o : m); | ||
})); | ||
yield Promise.all(promises); | ||
} | ||
if (zencode.match("read the record {} of the table {} of the database {} and save the result into {}" /* ACTIONS.GET_RECORD */)) { | ||
const dbAllRecordData = zencode.paramsOf("read the record {} of the table {} of the database {} and save the result into {}" /* ACTIONS.GET_RECORD */); | ||
// create object(s) with the FOUR values of each GET_RECORD | ||
const dbQueries = []; | ||
for (var i = 0; i < dbAllRecordData.length; i += 4) { | ||
for (let i = 0; i < dbAllRecordData.length; i += 4) { | ||
dbQueries.push({ | ||
@@ -76,4 +65,3 @@ id: dbAllRecordData[i], | ||
} | ||
runChecks(dbQueries, dbUriKeys, contentKeys, "database"); | ||
runChecks(dbQueries, tableKeys, contentKeys, "table"); | ||
validate(dbQueries); | ||
try { | ||
@@ -93,6 +81,3 @@ for (const query of dbQueries) { | ||
// column name is result | ||
const resultData = typeof result["result"] === "object" | ||
? result["result"] | ||
: parse(result["result"]); | ||
checkForNestedBoolean(resultData); | ||
const resultData = parse(result.result); | ||
data[query.varName] = resultData; | ||
@@ -113,4 +98,3 @@ } | ||
catch (e) { | ||
throw new Error(`[DATABASE] | ||
Databse error: ${e}`); | ||
throw new Error(`[DATABASE] Database error: ${e}`); | ||
} | ||
@@ -121,15 +105,14 @@ } | ||
const { result, zencode } = args; | ||
if (zencode.match(ACTIONS.SAVE_OUTPUT)) { | ||
const dbAllSaveOutput = zencode.paramsOf(ACTIONS.SAVE_OUTPUT); | ||
if (zencode.match("save the output into the database {} into the table {}" /* ACTIONS.SAVE_OUTPUT */)) { | ||
const dbAllSaveOutput = zencode.paramsOf("save the output into the database {} into the table {}" /* ACTIONS.SAVE_OUTPUT */); | ||
const dbQueries = []; | ||
//create object(s) with the TWO values in each GET_RECORD | ||
for (var i = 0; i < dbAllSaveOutput.length; i += 2) { | ||
// create object(s) with the TWO values in each GET_RECORD | ||
for (let j = 0; j < dbAllSaveOutput.length; j += 2) { | ||
dbQueries.push({ | ||
database: dbAllSaveOutput[i], | ||
table: dbAllSaveOutput[i + 1], | ||
database: dbAllSaveOutput[j], | ||
table: dbAllSaveOutput[j + 1], | ||
}); | ||
} | ||
//check that table and db are defined in keys or data, and in zencode | ||
runChecks(dbQueries, dbUriKeys, contentKeys, "database"); | ||
runChecks(dbQueries, tableKeys, contentKeys, "table"); | ||
// check that table and db are defined in keys or data, and in zencode | ||
validate(dbQueries); | ||
try { | ||
@@ -145,3 +128,3 @@ for (const query of dbQueries) { | ||
try { | ||
//column name must be result | ||
// column name must be result | ||
yield Result.create({ result: JSON.stringify(result) }); | ||
@@ -157,12 +140,11 @@ } | ||
catch (e) { | ||
throw new Error(`[DATABASE] | ||
Databse error: ${e}`); | ||
throw new Error(`[DATABASE] Database error: ${e}`); | ||
} | ||
} | ||
if (zencode.match(ACTIONS.SAVE_VAR)) { | ||
if (zencode.match("save the {} into the database {} into the table {}" /* ACTIONS.SAVE_VAR */)) { | ||
const resultObj = typeof result === "object" ? result : parse(result); | ||
const dbAllSaveVar = zencode.paramsOf(ACTIONS.SAVE_VAR); | ||
const dbAllSaveVar = zencode.paramsOf("save the {} into the database {} into the table {}" /* ACTIONS.SAVE_VAR */); | ||
const dbQueries = []; | ||
//create object(s) with the THREE values in each GET_RECORD | ||
for (var i = 0; i < dbAllSaveVar.length; i += 3) { | ||
// create object(s) with the THREE values in each GET_RECORD | ||
for (let i = 0; i < dbAllSaveVar.length; i += 3) { | ||
dbQueries.push({ | ||
@@ -174,5 +156,4 @@ varName: dbAllSaveVar[i], | ||
} | ||
//check that table and db are defined in keys or data and in zencode | ||
runChecks(dbQueries, dbUriKeys, contentKeys, "database"); | ||
runChecks(dbQueries, tableKeys, contentKeys, "table"); | ||
// check that table and db are defined in keys or data and in zencode | ||
validate(dbQueries); | ||
try { | ||
@@ -191,3 +172,3 @@ for (const query of dbQueries) { | ||
try { | ||
//column name must be result | ||
// column name must be result | ||
yield Result.create({ | ||
@@ -207,4 +188,3 @@ result: JSON.stringify({ | ||
catch (e) { | ||
throw new Error(`[DATABASE] | ||
Databse error: ${e}`); | ||
throw new Error(`[DATABASE] Database error: ${e}`); | ||
} | ||
@@ -221,7 +201,7 @@ } | ||
keys.forEach((key) => { | ||
//Check that all enpoints (urlKeys) have been defined using statement EXTERNAL_CONNECTION | ||
// Check that all enpoints (urlKeys) have been defined using statement EXTERNAL_CONNECTION | ||
if (actionKeys.includes(key[keyName]) === false) { | ||
throw new Error(`[DATABASE] | ||
Error: "${key[keyName]}" has not been defined in zencode, please define it with | ||
the following zencode sentence "${ACTIONS.GET_URI_KEYS}" or "${ACTIONS.GET_TABLE_KEYS}" `); | ||
the following zencode sentence "${"have a database uri named {}" /* ACTIONS.GET_URI_KEYS */}" or "${"have a database table named {}" /* ACTIONS.GET_TABLE_KEYS */}" `); | ||
} | ||
@@ -237,22 +217,1 @@ // check that all endpoints (urlKeys) are properties in either data or keys | ||
}; | ||
const checkForNestedBoolean = (obj) => { | ||
const res = {}; | ||
function recurse(obj, current) { | ||
for (const key in obj) { | ||
let value = obj[key]; | ||
if (value != undefined) { | ||
if (value && typeof value === "object") { | ||
recurse(value, key); | ||
} | ||
else { | ||
if (typeof value === "boolean") { | ||
throw new Error(`[HTTP] | ||
Boolean values are not permitted. Response JSON has property "${key}" with a boolean value. | ||
Please use, for example, 0 and 1`); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
recurse(obj, null); | ||
}; |
{ | ||
"name": "@restroom-mw/db", | ||
"version": "0.13.1-b58baa9.9+b58baa9", | ||
"version": "0.13.1-d29cf33.33+d29cf33", | ||
"description": "Database utilities middleware for Restroom", | ||
@@ -27,2 +27,3 @@ "author": "Puria Nafisi Azizi <puria@dyne.org>", | ||
"links": "yarn link", | ||
"lint": "tslint -c ../../tslint.json src/**/*.ts", | ||
"test": "nyc ava" | ||
@@ -42,3 +43,3 @@ }, | ||
}, | ||
"gitHead": "b58baa9af523ea2554745c95bb088aa6f214caa4" | ||
"gitHead": "d29cf33f9dfa0b38b471ab25d17830a051542829" | ||
} |
213
src/index.ts
@@ -5,2 +5,4 @@ import { DataTypes, Model, Sequelize } from "sequelize"; | ||
import { ObjectLiteral } from "@restroom-mw/types"; | ||
import { QueryGetRecord, QuerySaveOutput, QuerySaveVar } from "./interfaces"; | ||
import { Zencode } from "@restroom-mw/zencode"; | ||
@@ -11,43 +13,76 @@ class Result extends Model { | ||
const ACTIONS = { | ||
GET_URI_KEYS: "have a database uri named {}", | ||
GET_TABLE_KEYS: "have a database table named {}", | ||
GET_RECORD: | ||
"read the record {} of the table {} of the database {} and save the result into {}", //done | ||
SAVE_OUTPUT: "save the output into the database {} into the table {}", | ||
SAVE_VAR: "save the {} into the database {} into the table {}", | ||
}; | ||
const parse = (o: string) => { | ||
try { | ||
return JSON.parse(o); | ||
} catch (e) { | ||
throw new Error(`[DATABASE] Error in JSON format "${o}"`); | ||
} | ||
/** | ||
* Available actions for the @restroom-mw/db database middleware | ||
* | ||
* @enum {number} | ||
*/ | ||
const enum ACTIONS { | ||
/** | ||
* Given I have a database uri named {} | ||
* @param {string} uri the key of the connection string | ||
* @example | ||
* SQLITE: sqlite://:memory:/ or sqlite:///path/to/database.sqlite | ||
* MSSQL: Server=localhost\MSSQLSERVER01;Database=master;Trusted_Connection=True | ||
* MYSQL: mysql://root:root@localhost:3306/test | ||
* POSTGRES: postgres://postgres:postgres@localhost:5432/test | ||
* MARIADB: mariadb://root:root@localhost:3306/test | ||
* REDSHIFT: postgres://root:root@localhost:5432/test | ||
* SNOWFLAKE: snowflake://root:root@localhost:5432/test | ||
*/ | ||
GET_URI_KEYS = "have a database uri named {}", | ||
/** | ||
* Given I have a database table named {} | ||
* @param {string} key of the table in data/keys | ||
*/ | ||
GET_TABLE_KEYS = "have a database table named {}", | ||
/** | ||
* Given I read the record {} of the table {} of the database {} and save the result into {} | ||
* @param {string} record name of the field (row) | ||
* @param {string} table keyName of the table | ||
* @param {string} database keyName of the database | ||
* @param {string} output the variable to save the output | ||
*/ | ||
GET_RECORD = "read the record {} of the table {} of the database {} and save the result into {}", | ||
/** | ||
* Given I execute the SQL statement named {} on the database named {} and save the result into {} | ||
* | ||
* @param {string} statement name of the SQL statement | ||
* @param {string} database keyName of the database | ||
* @param {string} output the variable to save the output | ||
*/ | ||
EXECUTE_SQL = "execute the SQL statement named {} on the database named {} and save the result into {}", | ||
/** | ||
* **TBD** | ||
* Given I execute the SQL statement named {} pass the parameters named {} on the database named {} and save the result into {} | ||
* | ||
* @param {string} statement name of the SQL statement | ||
* @param {string} parameters name of the parameters | ||
* @param {string} database keyName of the database | ||
* @param {string} output the variable to save the output | ||
*/ | ||
EXECUTE_SQL_WITH_PARAMS = "execute the SQL statement named {} pass the parameters named {} on the database named {} and save the result into {}", | ||
/** | ||
* Then save the output into the database {} into the table {} | ||
* | ||
* | ||
* @param {string} database keyName of the database | ||
* @param {string} table keyName of the table | ||
*/ | ||
SAVE_OUTPUT = "save the output into the database {} into the table {}", | ||
/** | ||
* Then save the {} into the database {} into the table {} | ||
* | ||
* @param {string} output the variable to save the output | ||
* @param {string} database keyName of the database | ||
* @param {string} table keyName of the table | ||
*/ | ||
SAVE_VAR = "save the {} into the database {} into the table {}", | ||
}; | ||
interface QueryGetRecord { | ||
id: string; | ||
table: string; | ||
database: string; | ||
varName: string; | ||
} | ||
interface QuerySaveOutput { | ||
table: string; | ||
database: string; | ||
} | ||
interface QuerySaveVar { | ||
varName: string; | ||
database: string; | ||
table: string; | ||
} | ||
export default (req: Request, res: Response, next: NextFunction) => { | ||
try { | ||
const rr = new Restroom(req, res); | ||
let keysContent; | ||
let dataContent; | ||
const parse = (o: string) => rr.safeJSONParse(o, `[DATABASE] Error in JSON format "${o}"`) | ||
let content: ObjectLiteral = {}; | ||
@@ -58,17 +93,11 @@ let contentKeys: string[]; | ||
rr.onBefore(async (params) => { | ||
const { zencode, keys, data } = params; | ||
keysContent = | ||
typeof keys === "undefined" | ||
? {} | ||
: keys && typeof keys === "object" | ||
? keys | ||
: parse(keys); | ||
dataContent = | ||
typeof data === "undefined" | ||
? {} | ||
: data && typeof data === "object" | ||
? data | ||
: parse(data); | ||
content = { ...dataContent, ...keysContent }; | ||
const validate = (queries: any[]) => { | ||
runChecks(queries, dbUriKeys, contentKeys, "database"); | ||
runChecks(queries, tableKeys, contentKeys, "table"); | ||
} | ||
rr.onBefore(async (params: { zencode: Zencode, keys: string, data: ObjectLiteral }) => { | ||
let { zencode, keys, data } = params; | ||
if (!data) data = {} | ||
content = rr.combineDataKeys({ ...data }, keys); | ||
contentKeys = Object.keys(content); | ||
@@ -84,8 +113,19 @@ | ||
if (zencode.match(ACTIONS.EXECUTE_SQL)) { | ||
const promises = zencode.chunkedParamsOf(ACTIONS.EXECUTE_SQL, 3).map(async ([statement, database, output]: [content: string, database: string, output: string]) => { | ||
const db = new Sequelize(content[database]); | ||
const t = await db.transaction(); | ||
const [o, m] = await db.query(content[statement], { transaction: t }); | ||
await t.commit(); | ||
data[output] = JSON.stringify(o ? o : m) | ||
}) | ||
await Promise.all(promises) | ||
} | ||
if (zencode.match(ACTIONS.GET_RECORD)) { | ||
const dbAllRecordData: string[] = zencode.paramsOf(ACTIONS.GET_RECORD); | ||
//create object(s) with the FOUR values of each GET_RECORD | ||
// create object(s) with the FOUR values of each GET_RECORD | ||
const dbQueries: QueryGetRecord[] = []; | ||
for (var i = 0; i < dbAllRecordData.length; i += 4) { | ||
for (let i = 0; i < dbAllRecordData.length; i += 4) { | ||
dbQueries.push({ | ||
@@ -98,4 +138,3 @@ id: dbAllRecordData[i], | ||
} | ||
runChecks(dbQueries, dbUriKeys, contentKeys, "database"); | ||
runChecks(dbQueries, tableKeys, contentKeys, "table"); | ||
validate(dbQueries); | ||
try { | ||
@@ -118,7 +157,3 @@ for (const query of dbQueries) { | ||
// column name is result | ||
const resultData = | ||
typeof result["result"] === "object" | ||
? result["result"] | ||
: parse(result["result"]); | ||
checkForNestedBoolean(resultData); | ||
const resultData = parse(result.result); | ||
data[query.varName] = resultData; | ||
@@ -136,4 +171,3 @@ } else { | ||
} catch (e) { | ||
throw new Error(`[DATABASE] | ||
Databse error: ${e}`); | ||
throw new Error(`[DATABASE] Database error: ${e}`); | ||
} | ||
@@ -143,3 +177,3 @@ } | ||
rr.onSuccess(async (args: { result: any; zencode: any }) => { | ||
rr.onSuccess(async (args: { result: any; zencode: Zencode }) => { | ||
const { result, zencode } = args; | ||
@@ -150,12 +184,11 @@ | ||
const dbQueries: QuerySaveOutput[] = []; | ||
//create object(s) with the TWO values in each GET_RECORD | ||
for (var i = 0; i < dbAllSaveOutput.length; i += 2) { | ||
// create object(s) with the TWO values in each GET_RECORD | ||
for (let j = 0; j < dbAllSaveOutput.length; j += 2) { | ||
dbQueries.push({ | ||
database: dbAllSaveOutput[i], | ||
table: dbAllSaveOutput[i + 1], | ||
database: dbAllSaveOutput[j], | ||
table: dbAllSaveOutput[j + 1], | ||
}); | ||
} | ||
//check that table and db are defined in keys or data, and in zencode | ||
runChecks(dbQueries, dbUriKeys, contentKeys, "database"); | ||
runChecks(dbQueries, tableKeys, contentKeys, "table"); | ||
// check that table and db are defined in keys or data, and in zencode | ||
validate(dbQueries); | ||
try { | ||
@@ -174,3 +207,3 @@ for (const query of dbQueries) { | ||
try { | ||
//column name must be result | ||
// column name must be result | ||
await Result.create({ result: JSON.stringify(result) }); | ||
@@ -184,4 +217,3 @@ } catch (e) { | ||
} catch (e) { | ||
throw new Error(`[DATABASE] | ||
Databse error: ${e}`); | ||
throw new Error(`[DATABASE] Database error: ${e}`); | ||
} | ||
@@ -195,4 +227,4 @@ } | ||
const dbQueries: QuerySaveVar[] = []; | ||
//create object(s) with the THREE values in each GET_RECORD | ||
for (var i = 0; i < dbAllSaveVar.length; i += 3) { | ||
// create object(s) with the THREE values in each GET_RECORD | ||
for (let i = 0; i < dbAllSaveVar.length; i += 3) { | ||
dbQueries.push({ | ||
@@ -204,5 +236,4 @@ varName: dbAllSaveVar[i], | ||
} | ||
//check that table and db are defined in keys or data and in zencode | ||
runChecks(dbQueries, dbUriKeys, contentKeys, "database"); | ||
runChecks(dbQueries, tableKeys, contentKeys, "table"); | ||
// check that table and db are defined in keys or data and in zencode | ||
validate(dbQueries); | ||
try { | ||
@@ -225,3 +256,3 @@ for (const query of dbQueries) { | ||
try { | ||
//column name must be result | ||
// column name must be result | ||
await Result.create({ | ||
@@ -239,4 +270,3 @@ result: JSON.stringify({ | ||
} catch (e) { | ||
throw new Error(`[DATABASE] | ||
Databse error: ${e}`); | ||
throw new Error(`[DATABASE] Database error: ${e}`); | ||
} | ||
@@ -258,3 +288,3 @@ } | ||
keys.forEach((key: any) => { | ||
//Check that all enpoints (urlKeys) have been defined using statement EXTERNAL_CONNECTION | ||
// Check that all enpoints (urlKeys) have been defined using statement EXTERNAL_CONNECTION | ||
if (actionKeys.includes(key[keyName]) === false) { | ||
@@ -275,22 +305,1 @@ throw new Error(`[DATABASE] | ||
}; | ||
const checkForNestedBoolean = (obj: any) => { | ||
const res = {}; | ||
function recurse(obj: { [x: string]: any }, current: string) { | ||
for (const key in obj) { | ||
let value = obj[key]; | ||
if (value != undefined) { | ||
if (value && typeof value === "object") { | ||
recurse(value, key); | ||
} else { | ||
if (typeof value === "boolean") { | ||
throw new Error(`[HTTP] | ||
Boolean values are not permitted. Response JSON has property "${key}" with a boolean value. | ||
Please use, for example, 0 and 1`); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
recurse(obj, null); | ||
}; |
Sorry, the diff of this file is not supported yet
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
58626
10
509