@restroom-mw/db
Advanced tools
Comparing version 0.13.1-ac1b27c.0 to 0.13.1-b1506da.59
@@ -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-ac1b27c.0+ac1b27c", | ||
"version": "0.13.1-b1506da.59+b1506da", | ||
"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": "ac1b27c1afdd31805ed6a563937ddf89cbdba222" | ||
"gitHead": "b1506da7903a3ecf9965a0012e77bc4d7a7b3c1f" | ||
} |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
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