Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

data-api-client

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

data-api-client - npm Package Compare versions

Comparing version 1.2.1 to 1.3.0

555

index.js

@@ -39,53 +39,76 @@ 'use strict'

// Simple error function
const error = (...err) => { throw Error(...err) }
const error = (...err) => {
throw Error(...err)
}
// Parse SQL statement from provided arguments
const parseSQL = args =>
typeof args[0] === 'string' ? args[0]
: typeof args[0] === 'object' && typeof args[0].sql === 'string' ? args[0].sql
: error('No \'sql\' statement provided.')
const parseSQL = (args) =>
typeof args[0] === 'string'
? args[0]
: typeof args[0] === 'object' && typeof args[0].sql === 'string'
? args[0].sql
: error(`No 'sql' statement provided.`)
// Parse the parameters from provided arguments
const parseParams = args =>
Array.isArray(args[0].parameters) ? args[0].parameters
: typeof args[0].parameters === 'object' ? [args[0].parameters]
: Array.isArray(args[1]) ? args[1]
: typeof args[1] === 'object' ? [args[1]]
: args[0].parameters ? error('\'parameters\' must be an object or array')
: args[1] ? error('Parameters must be an object or array')
: []
const parseParams = (args) =>
Array.isArray(args[0].parameters)
? args[0].parameters
: typeof args[0].parameters === 'object'
? [args[0].parameters]
: Array.isArray(args[1])
? args[1]
: typeof args[1] === 'object'
? [args[1]]
: args[0].parameters
? error(`'parameters' must be an object or array`)
: args[1]
? error('Parameters must be an object or array')
: []
// Parse the supplied database, or default to config
const parseDatabase = (config,args) =>
config.transactionId ? config.database
: typeof args[0].database === 'string' ? args[0].database
: args[0].database ? error('\'database\' must be a string.')
: config.database ? config.database
: undefined // removed for #47 - error('No \'database\' provided.')
const parseDatabase = (config, args) =>
config.transactionId
? config.database
: typeof args[0].database === 'string'
? args[0].database
: args[0].database
? error(`'database' must be a string.`)
: config.database
? config.database
: undefined // removed for #47 - error('No \'database\' provided.')
// Parse the supplied hydrateColumnNames command, or default to config
const parseHydrate = (config,args) =>
typeof args[0].hydrateColumnNames === 'boolean' ? args[0].hydrateColumnNames
: args[0].hydrateColumnNames ? error('\'hydrateColumnNames\' must be a boolean.')
: config.hydrateColumnNames
const parseHydrate = (config, args) =>
typeof args[0].hydrateColumnNames === 'boolean'
? args[0].hydrateColumnNames
: args[0].hydrateColumnNames
? error(`'hydrateColumnNames' must be a boolean.`)
: config.hydrateColumnNames
// Parse the supplied format options, or default to config
const parseFormatOptions = (config,args) =>
typeof args[0].formatOptions === 'object' ? {
deserializeDate: typeof args[0].formatOptions.deserializeDate === 'boolean' ? args[0].formatOptions.deserializeDate
: args[0].formatOptions.deserializeDate ? error('\'formatOptions.deserializeDate\' must be a boolean.')
: config.formatOptions.deserializeDate,
treatAsLocalDate: typeof args[0].formatOptions.treatAsLocalDate == 'boolean' ? args[0].formatOptions.treatAsLocalDate
: args[0].formatOptions.treatAsLocalDate ? error('\'formatOptions.treatAsLocalDate\' must be a boolean.')
: config.formatOptions.treatAsLocalDate
}
: args[0].formatOptions ? error('\'formatOptions\' must be an object.')
: config.formatOptions
const parseFormatOptions = (config, args) =>
typeof args[0].formatOptions === 'object'
? {
deserializeDate:
typeof args[0].formatOptions.deserializeDate === 'boolean'
? args[0].formatOptions.deserializeDate
: args[0].formatOptions.deserializeDate
? error(`'formatOptions.deserializeDate' must be a boolean.`)
: config.formatOptions.deserializeDate,
treatAsLocalDate:
typeof args[0].formatOptions.treatAsLocalDate == 'boolean'
? args[0].formatOptions.treatAsLocalDate
: args[0].formatOptions.treatAsLocalDate
? error(`'formatOptions.treatAsLocalDate' must be a boolean.`)
: config.formatOptions.treatAsLocalDate
}
: args[0].formatOptions
? error(`'formatOptions' must be an object.`)
: config.formatOptions
// Prepare method params w/ supplied inputs if an object is passed
const prepareParams = ({ secretArn,resourceArn },args) => {
const prepareParams = ({ secretArn, resourceArn }, args) => {
return Object.assign(
{ secretArn,resourceArn }, // return Arns
typeof args[0] === 'object' ?
omit(args[0],['hydrateColumnNames','parameters']) : {} // merge any inputs
{ secretArn, resourceArn }, // return Arns
typeof args[0] === 'object' ? omit(args[0], ['hydrateColumnNames', 'parameters']) : {} // merge any inputs
)

@@ -95,31 +118,35 @@ }

// Utility function for removing certain keys from an object
const omit = (obj,values) => Object.keys(obj).reduce((acc,x) =>
values.includes(x) ? acc : Object.assign(acc,{ [x]: obj[x] })
,{})
const omit = (obj, values) =>
Object.keys(obj).reduce((acc, x) => (values.includes(x) ? acc : Object.assign(acc, { [x]: obj[x] })), {})
// Utility function for picking certain keys from an object
const pick = (obj,values) => Object.keys(obj).reduce((acc,x) =>
values.includes(x) ? Object.assign(acc,{ [x]: obj[x] }) : acc
,{})
const pick = (obj, values) =>
Object.keys(obj).reduce((acc, x) => (values.includes(x) ? Object.assign(acc, { [x]: obj[x] }) : acc), {})
// Utility function for flattening arrays
const flatten = arr => arr.reduce((acc,x) => acc.concat(x),[])
const flatten = (arr) => arr.reduce((acc, x) => acc.concat(x), [])
// Normize parameters so that they are all in standard format
const normalizeParams = params => params.reduce((acc, p) =>
Array.isArray(p) ? acc.concat([normalizeParams(p)])
: (
(Object.keys(p).length === 2 && p.name && typeof p.value !== 'undefined') ||
(Object.keys(p).length === 3 && p.name && typeof p.value !== 'undefined' && p.cast)
) ? acc.concat(p)
: acc.concat(splitParams(p))
, []) // end reduce
const normalizeParams = (params) =>
params.reduce(
(acc, p) =>
Array.isArray(p)
? acc.concat([normalizeParams(p)])
: (Object.keys(p).length === 2 && p.name && typeof p.value !== 'undefined') ||
(Object.keys(p).length === 3 && p.name && typeof p.value !== 'undefined' && p.cast)
? acc.concat(p)
: acc.concat(splitParams(p)),
[]
) // end reduce
// Prepare parameters
const processParams = (engine,sql,sqlParams,params,formatOptions,row=0) => {
const processParams = (engine, sql, sqlParams, params, formatOptions, row = 0) => {
return {
processedParams: params.reduce((acc,p) => {
processedParams: params.reduce((acc, p) => {
if (Array.isArray(p)) {
const result = processParams(engine,sql,sqlParams,p,formatOptions,row)
if (row === 0) { sql = result.escapedSql; row++ }
const result = processParams(engine, sql, sqlParams, p, formatOptions, row)
if (row === 0) {
sql = result.escapedSql
row++
}
return acc.concat([result.processedParams])

@@ -130,10 +157,5 @@ } else if (sqlParams[p.name]) {

const regex = new RegExp(':' + p.name + '\\b', 'g')
sql = sql.replace(
regex,
engine === 'pg'
? `:${p.name}::${p.cast}`
: `CAST(:${p.name} AS ${p.cast})`
)
sql = sql.replace(regex, engine === 'pg' ? `:${p.name}::${p.cast}` : `CAST(:${p.name} AS ${p.cast})`)
}
acc.push(formatParam(p.name,p.value,formatOptions))
acc.push(formatParam(p.name, p.value, formatOptions))
} else if (row === 0) {

@@ -147,3 +169,3 @@ const regex = new RegExp('::' + p.name + '\\b', 'g')

}
},[]),
}, []),
escapedSql: sql

@@ -154,28 +176,28 @@ }

// Converts parameter to the name/value format
const formatParam = (n,v,formatOptions) => formatType(n,v,getType(v),getTypeHint(v),formatOptions)
const formatParam = (n, v, formatOptions) => formatType(n, v, getType(v), getTypeHint(v), formatOptions)
// Converts object params into name/value format
const splitParams = p => Object.keys(p).reduce((arr,x) =>
arr.concat({ name: x, value: p[x] }),[])
const splitParams = (p) => Object.keys(p).reduce((arr, x) => arr.concat({ name: x, value: p[x] }), [])
// Get all the sql parameters and assign them types
const getSqlParams = sql => {
const getSqlParams = (sql) => {
// TODO: probably need to remove comments from the sql
// TODO: placeholders?
// sql.match(/\:{1,2}\w+|\?+/g).map((p,i) => {
return (sql.match(/:{1,2}\w+/g) || []).map((p) => {
// TODO: future support for placeholder parsing?
// return p === '??' ? { type: 'id' } // identifier
// : p === '?' ? { type: 'ph', label: '__d'+i } // placeholder
return p.startsWith('::') ? { type: 'n_id', label: p.substr(2) } // named id
: { type: 'n_ph', label: p.substr(1) } // named placeholder
}).reduce((acc,x) => {
return Object.assign(acc,
{
return (sql.match(/:{1,2}\w+/g) || [])
.map((p) => {
// TODO: future support for placeholder parsing?
// return p === '??' ? { type: 'id' } // identifier
// : p === '?' ? { type: 'ph', label: '__d'+i } // placeholder
return p.startsWith('::')
? { type: 'n_id', label: p.substr(2) } // named id
: { type: 'n_ph', label: p.substr(1) } // named placeholder
})
.reduce((acc, x) => {
return Object.assign(acc, {
[x.label]: {
type: x.type
}
}
)
},{}) // end reduce
})
}, {}) // end reduce
}

@@ -185,37 +207,44 @@

// TODO: Support more types as the are released
const getType = val =>
typeof val === 'string' ? 'stringValue'
: typeof val === 'boolean' ? 'booleanValue'
: typeof val === 'number' && parseInt(val) === val ? 'longValue'
: typeof val === 'number' && parseFloat(val) === val ? 'doubleValue'
: val === null ? 'isNull'
: isDate(val) ? 'stringValue'
: Buffer.isBuffer(val) ? 'blobValue'
// : Array.isArray(val) ? 'arrayValue' This doesn't work yet
// TODO: there is a 'structValue' now for postgres
: typeof val === 'object'
&& Object.keys(val).length === 1
&& supportedTypes.includes(Object.keys(val)[0]) ? null
: undefined
const getType = (val) =>
typeof val === 'string'
? 'stringValue'
: typeof val === 'boolean'
? 'booleanValue'
: typeof val === 'number' && parseInt(val) === val
? 'longValue'
: typeof val === 'number' && parseFloat(val) === val
? 'doubleValue'
: val === null
? 'isNull'
: isDate(val)
? 'stringValue'
: Buffer.isBuffer(val)
? 'blobValue'
: // : Array.isArray(val) ? 'arrayValue' This doesn't work yet
// TODO: there is a 'structValue' now for postgres
typeof val === 'object' && Object.keys(val).length === 1 && supportedTypes.includes(Object.keys(val)[0])
? null
: undefined
// Hint to specify the underlying object type for data type mapping
const getTypeHint = val =>
isDate(val) ? 'TIMESTAMP' : undefined
const getTypeHint = (val) => (isDate(val) ? 'TIMESTAMP' : undefined)
const isDate = val =>
val instanceof Date
const isDate = (val) => val instanceof Date
// Creates a standard Data API parameter using the supplied inputs
const formatType = (name,value,type,typeHint,formatOptions) => {
const formatType = (name, value, type, typeHint, formatOptions) => {
return Object.assign(
typeHint != null ? { name, typeHint } : { name },
type === null ? { value }
: {
value: {
[type ? type : error(`'${name}' is an invalid type`)]
: type === 'isNull' ? true
: isDate(value) ? formatToTimeStamp(value, formatOptions && formatOptions.treatAsLocalDate)
: value
}
}
type === null
? { value }
: {
value: {
[type ? type : error(`'${name}' is an invalid type`)]:
type === 'isNull'
? true
: isDate(value)
? formatToTimeStamp(value, formatOptions && formatOptions.treatAsLocalDate)
: value
}
}
)

@@ -227,3 +256,3 @@ } // end formatType

const formatToTimeStamp = (date, treatAsLocalDate) => {
const pad = (val,num=2) => '0'.repeat(num-(val + '').length) + val
const pad = (val, num = 2) => '0'.repeat(num - (val + '').length) + val

@@ -239,3 +268,3 @@ const year = treatAsLocalDate ? date.getFullYear() : date.getUTCFullYear()

const fraction = ms <= 0 ? '' : `.${pad(ms,3)}`
const fraction = ms <= 0 ? '' : `.${pad(ms, 3)}`

@@ -248,10 +277,11 @@ return `${year}-${pad(month)}-${pad(day)} ${pad(hours)}:${pad(minutes)}:${pad(seconds)}${fraction}`

// In all other cases convert value to datetime as-is (also values with TZ info)
const formatFromTimeStamp = (value,treatAsLocalDate) =>
!treatAsLocalDate && /^\d{4}-\d{2}-\d{2}(\s\d{2}:\d{2}:\d{2}(\.\d{3})?)?$/.test(value) ?
new Date(value + 'Z') :
new Date(value)
const formatFromTimeStamp = (value, treatAsLocalDate) =>
!treatAsLocalDate && /^\d{4}-\d{2}-\d{2}(\s\d{2}:\d{2}:\d{2}(\.\d+)?)?$/.test(value)
? new Date(value + 'Z')
: new Date(value)
// Formats the results of a query response
const formatResults = (
{ // destructure results
{
// destructure results
columnMetadata, // ONLY when hydrate or includeResultMetadata is true

@@ -266,82 +296,94 @@ numberOfRecordsUpdated, // ONLY for executeStatement method

formatOptions
) => Object.assign(
includeMeta ? { columnMetadata } : {},
numberOfRecordsUpdated !== undefined && !records ? { numberOfRecordsUpdated } : {},
records ? {
records: formatRecords(records, columnMetadata, hydrate, formatOptions)
} : {},
updateResults ? { updateResults: formatUpdateResults(updateResults) } : {},
generatedFields && generatedFields.length > 0 ?
{ insertId: generatedFields[0].longValue } : {}
)
) =>
Object.assign(
includeMeta ? { columnMetadata } : {},
numberOfRecordsUpdated !== undefined && !records ? { numberOfRecordsUpdated } : {},
records
? {
records: formatRecords(records, columnMetadata, hydrate, formatOptions)
}
: {},
updateResults ? { updateResults: formatUpdateResults(updateResults) } : {},
generatedFields && generatedFields.length > 0 ? { insertId: generatedFields[0].longValue } : {}
)
// Processes records and either extracts Typed Values into an array, or
// object with named column labels
const formatRecords = (recs,columns,hydrate,formatOptions) => {
const formatRecords = (recs, columns, hydrate, formatOptions) => {
// Create map for efficient value parsing
let fmap = recs && recs[0] ? recs[0].map((x,i) => {
return Object.assign({},
columns ? { label: columns[i].label, typeName: columns[i].typeName } : {} ) // add column label and typeName
}) : {}
let fmap =
recs && recs[0]
? recs[0].map((x, i) => {
return Object.assign({}, columns ? { label: columns[i].label, typeName: columns[i].typeName } : {}) // add column label and typeName
})
: {}
// Map over all the records (rows)
return recs ? recs.map(rec => {
return recs
? recs.map((rec) => {
// Reduce each field in the record (row)
return rec.reduce(
(acc, field, i) => {
// If the field is null, always return null
if (field.isNull === true) {
return hydrate // object if hydrate, else array
? Object.assign(acc, { [fmap[i].label]: null })
: acc.concat(null)
// Reduce each field in the record (row)
return rec.reduce((acc,field,i) => {
// If the field is mapped, return the mapped field
} else if (fmap[i] && fmap[i].field) {
const value = formatRecordValue(field[fmap[i].field], fmap[i].typeName, formatOptions)
return hydrate // object if hydrate, else array
? Object.assign(acc, { [fmap[i].label]: value })
: acc.concat(value)
// If the field is null, always return null
if (field.isNull === true) {
return hydrate ? // object if hydrate, else array
Object.assign(acc,{ [fmap[i].label]: null })
: acc.concat(null)
// Else discover the field type
} else {
// Look for non-null fields
Object.keys(field).map((type) => {
if (type !== 'isNull' && field[type] !== null) {
fmap[i]['field'] = type
}
})
// If the field is mapped, return the mapped field
} else if (fmap[i] && fmap[i].field) {
const value = formatRecordValue(field[fmap[i].field],fmap[i].typeName,formatOptions)
return hydrate ? // object if hydrate, else array
Object.assign(acc,{ [fmap[i].label]: value })
: acc.concat(value)
// Else discover the field type
} else {
// Look for non-null fields
Object.keys(field).map(type => {
if (type !== 'isNull' && field[type] !== null) {
fmap[i]['field'] = type
}
})
// Return the mapped field (this should NEVER be null)
const value = formatRecordValue(field[fmap[i].field],fmap[i].typeName,formatOptions)
return hydrate ? // object if hydrate, else array
Object.assign(acc,{ [fmap[i].label]: value })
: acc.concat(value)
}
}, hydrate ? {} : []) // init object if hydrate, else init array
}) : [] // empty record set returns an array
// Return the mapped field (this should NEVER be null)
const value = formatRecordValue(field[fmap[i].field], fmap[i].typeName, formatOptions)
return hydrate // object if hydrate, else array
? Object.assign(acc, { [fmap[i].label]: value })
: acc.concat(value)
}
},
hydrate ? {} : []
) // init object if hydrate, else init array
})
: [] // empty record set returns an array
} // end formatRecords
// Format record value based on its value, the database column's typeName and the formatting options
const formatRecordValue = (value,typeName,formatOptions) => formatOptions && formatOptions.deserializeDate &&
['DATE', 'DATETIME', 'TIMESTAMP', 'TIMESTAMP WITH TIME ZONE'].includes(typeName)
? formatFromTimeStamp(value,(formatOptions && formatOptions.treatAsLocalDate) || typeName === 'TIMESTAMP WITH TIME ZONE')
: value
const formatRecordValue = (value, typeName, formatOptions) => {
if (
formatOptions &&
formatOptions.deserializeDate &&
['DATE', 'DATETIME', 'TIMESTAMP', 'TIMESTAMPTZ', 'TIMESTAMP WITH TIME ZONE'].includes(typeName.toUpperCase())
) {
return formatFromTimeStamp(
value,
(formatOptions && formatOptions.treatAsLocalDate) || typeName === 'TIMESTAMP WITH TIME ZONE'
)
} else if (typeName === 'JSON') {
return JSON.parse(value)
} else {
return value
}
}
// Format updateResults and extract insertIds
const formatUpdateResults = res => res.map(x => {
return x.generatedFields && x.generatedFields.length > 0 ?
{ insertId: x.generatedFields[0].longValue } : {}
})
const formatUpdateResults = (res) =>
res.map((x) => {
return x.generatedFields && x.generatedFields.length > 0 ? { insertId: x.generatedFields[0].longValue } : {}
})
// Merge configuration data with supplied arguments
const mergeConfig = (initialConfig,args) =>
Object.assign(initialConfig,args)
const mergeConfig = (initialConfig, args) => Object.assign(initialConfig, args)
/********************************************************************/

@@ -352,3 +394,3 @@ /** QUERY MANAGEMENT **/

// Query function (use standard form for `this` context)
const query = async function(config,..._args) {
const query = async function (config, ..._args) {
// Flatten array if nested arrays (fixes #30)

@@ -362,6 +404,6 @@ const args = Array.isArray(_args[0]) ? flatten(_args) : _args

// Parse hydration setting
const hydrateColumnNames = parseHydrate(config,args)
const hydrateColumnNames = parseHydrate(config, args)
// Parse data format settings
const formatOptions = parseFormatOptions(config,args)
const formatOptions = parseFormatOptions(config, args)

@@ -372,19 +414,19 @@ // Parse and normalize parameters

// Process parameters and escape necessary SQL
const { processedParams,escapedSql } = processParams(config.engine,sql,sqlParams,parameters,formatOptions)
const { processedParams, escapedSql } = processParams(config.engine, sql, sqlParams, parameters, formatOptions)
// Determine if this is a batch request
const isBatch = processedParams.length > 0
&& Array.isArray(processedParams[0])
const isBatch = processedParams.length > 0 && Array.isArray(processedParams[0])
// Create/format the parameters
const params = Object.assign(
prepareParams(config,args),
prepareParams(config, args),
{
database: parseDatabase(config,args), // add database
database: parseDatabase(config, args), // add database
sql: escapedSql // add escaped sql statement
},
// Only include parameters if they exist
processedParams.length > 0 ?
// Batch statements require parameterSets instead of parameters
{ [isBatch ? 'parameterSets' : 'parameters']: processedParams } : {},
processedParams.length > 0
? // Batch statements require parameterSets instead of parameters
{ [isBatch ? 'parameterSets' : 'parameters']: processedParams }
: {},
// Force meta data if set and not a batch

@@ -396,24 +438,19 @@ hydrateColumnNames && !isBatch ? { includeResultMetadata: true } : {},

try { // attempt to run the query
try {
// attempt to run the query
// Capture the result for debugging
let result = await (isBatch ? config.RDS.batchExecuteStatement(params).promise()
let result = await (isBatch
? config.RDS.batchExecuteStatement(params).promise()
: config.RDS.executeStatement(params).promise())
// Format and return the results
return formatResults(
result,
hydrateColumnNames,
args[0].includeResultMetadata === true,
formatOptions
)
} catch(e) {
return formatResults(result, hydrateColumnNames, args[0].includeResultMetadata === true, formatOptions)
} catch (e) {
if (this && this.rollback) {
let rollback = await config.RDS.rollbackTransaction(
pick(params,['resourceArn','secretArn','transactionId'])
pick(params, ['resourceArn', 'secretArn', 'transactionId'])
).promise()
this.rollback(e,rollback)
this.rollback(e, rollback)
}

@@ -423,7 +460,4 @@ // Throw the error

}
} // end query
/********************************************************************/

@@ -434,4 +468,3 @@ /** TRANSACTION MANAGEMENT **/

// Init a transaction object and return methods
const transaction = (config,_args) => {
const transaction = (config, _args) => {
let args = typeof _args === 'object' ? [_args] : [{}]

@@ -441,14 +474,11 @@ let queries = [] // keep track of queries

const txConfig = Object.assign(
prepareParams(config,args),
{
database: parseDatabase(config,args), // add database
hydrateColumnNames: parseHydrate(config,args), // add hydrate
formatOptions: parseFormatOptions(config,args), // add formatOptions
RDS: config.RDS // reference the RDSDataService instance
}
)
const txConfig = Object.assign(prepareParams(config, args), {
database: parseDatabase(config, args), // add database
hydrateColumnNames: parseHydrate(config, args), // add hydrate
formatOptions: parseFormatOptions(config, args), // add formatOptions
RDS: config.RDS // reference the RDSDataService instance
})
return {
query: function(...args) {
query: function (...args) {
if (typeof args[0] === 'function') {

@@ -461,7 +491,11 @@ queries.push(args[0])

},
rollback: function(fn) {
if (typeof fn === 'function') { rollback = fn }
rollback: function (fn) {
if (typeof fn === 'function') {
rollback = fn
}
return this
},
commit: async function() { return await commit(txConfig,queries,rollback) }
commit: async function () {
return await commit(txConfig, queries, rollback)
}
}

@@ -471,4 +505,3 @@ }

// Commit transaction by running queries
const commit = async (config,queries,rollback) => {
const commit = async (config, queries, rollback) => {
let results = [] // keep track of results

@@ -478,3 +511,3 @@

const { transactionId } = await config.RDS.beginTransaction(
pick(config,['resourceArn','secretArn','database'])
pick(config, ['resourceArn', 'secretArn', 'database'])
).promise()

@@ -488,3 +521,3 @@

// Execute the queries, pass the rollback as context
let result = await query.apply({rollback},[config,queries[i](results[results.length-1],results)])
let result = await query.apply({ rollback }, [config, queries[i](results[results.length - 1], results)])
// Add the result to the main results accumulator

@@ -496,7 +529,7 @@ results.push(result)

const { transactionStatus } = await txConfig.RDS.commitTransaction(
pick(config,['resourceArn','secretArn','transactionId'])
pick(config, ['resourceArn', 'secretArn', 'transactionId'])
).promise()
// Add the transaction status to the results
results.push({transactionStatus})
results.push({ transactionStatus })

@@ -532,8 +565,10 @@ // Return the results

*/
const init = params => {
const init = (params) => {
// Set the options for the RDSDataService
const options = typeof params.options === 'object' ? params.options
: params.options !== undefined ? error('\'options\' must be an object')
: {}
const options =
typeof params.options === 'object'
? params.options
: params.options !== undefined
? error(`'options' must be an object`)
: {}

@@ -553,21 +588,18 @@ // Update the AWS http agent with the region

// Require engine
engine: typeof params.engine === 'string' ?
params.engine
: 'mysql',
engine: typeof params.engine === 'string' ? params.engine : 'mysql',
// Require secretArn
secretArn: typeof params.secretArn === 'string' ?
params.secretArn
: error('\'secretArn\' string value required'),
secretArn: typeof params.secretArn === 'string' ? params.secretArn : error(`'secretArn' string value required`),
// Require resourceArn
resourceArn: typeof params.resourceArn === 'string' ?
params.resourceArn
: error('\'resourceArn\' string value required'),
resourceArn:
typeof params.resourceArn === 'string' ? params.resourceArn : error(`'resourceArn' string value required`),
// Load optional database
database: typeof params.database === 'string' ?
params.database
: params.database !== undefined ? error('\'database\' must be a string')
: undefined,
database:
typeof params.database === 'string'
? params.database
: params.database !== undefined
? error(`'database' must be a string`)
: undefined,

@@ -580,5 +612,3 @@ // Load optional schema DISABLED for now since this isn't used with MySQL

// Set hydrateColumnNames (default to true)
hydrateColumnNames:
typeof params.hydrateColumnNames === 'boolean' ?
params.hydrateColumnNames : true,
hydrateColumnNames: typeof params.hydrateColumnNames === 'boolean' ? params.hydrateColumnNames : true,

@@ -589,4 +619,3 @@ // Value formatting options. For date the deserialization is enabled and (re)stored as UTC

typeof params.formatOptions === 'object' && params.formatOptions.deserializeDate === false ? false : true,
treatAsLocalDate:
typeof params.formatOptions === 'object' && params.formatOptions.treatAsLocalDate
treatAsLocalDate: typeof params.formatOptions === 'object' && params.formatOptions.treatAsLocalDate
},

@@ -596,4 +625,3 @@

// Create an instance of RDSDataService
RDS: new AWS.RDSDataService(options)
RDS: params.AWS ? new params.AWS.RDSDataService(options) : new AWS.RDSDataService(options)
} // end config

@@ -604,5 +632,5 @@

// Query method, pass config and parameters
query: (...x) => query(config,...x),
query: (...x) => query(config, ...x),
// Transaction method, pass config and parameters
transaction: (x) => transaction(config,x),
transaction: (x) => transaction(config, x),

@@ -612,24 +640,15 @@ // Export promisified versions of the RDSDataService methods

config.RDS.batchExecuteStatement(
mergeConfig(pick(config,['resourceArn','secretArn','database']),args)
mergeConfig(pick(config, ['resourceArn', 'secretArn', 'database']), args)
).promise(),
beginTransaction: (args) =>
config.RDS.beginTransaction(
mergeConfig(pick(config,['resourceArn','secretArn','database']),args)
).promise(),
config.RDS.beginTransaction(mergeConfig(pick(config, ['resourceArn', 'secretArn', 'database']), args)).promise(),
commitTransaction: (args) =>
config.RDS.commitTransaction(
mergeConfig(pick(config,['resourceArn','secretArn']),args)
).promise(),
config.RDS.commitTransaction(mergeConfig(pick(config, ['resourceArn', 'secretArn']), args)).promise(),
executeStatement: (args) =>
config.RDS.executeStatement(
mergeConfig(pick(config,['resourceArn','secretArn','database']),args)
).promise(),
config.RDS.executeStatement(mergeConfig(pick(config, ['resourceArn', 'secretArn', 'database']), args)).promise(),
rollbackTransaction: (args) =>
config.RDS.rollbackTransaction(
mergeConfig(pick(config,['resourceArn','secretArn']),args)
).promise()
config.RDS.rollbackTransaction(mergeConfig(pick(config, ['resourceArn', 'secretArn']), args)).promise()
}
} // end exports
module.exports = init
{
"name": "data-api-client",
"version": "1.2.1",
"version": "1.3.0",
"description": "A lightweight wrapper that simplifies working with the Amazon Aurora Serverless Data API",

@@ -29,4 +29,6 @@ "main": "index.js",

"aws-sdk": "^2.811.0",
"eslint": "^6.8.0",
"eslint": "^8.12.0",
"eslint-config-prettier": "^8.5.0",
"jest": "^27.5.1",
"prettier": "^2.6.2",
"rewire": "^6.0.0"

@@ -33,0 +35,0 @@ },

@@ -137,2 +137,3 @@ ![Aurora Serverless Data API Client](https://user-images.githubusercontent.com/2053544/79285017-44053500-7e8a-11ea-8515-998ccf9c2d2e.png)

| -------- | ---- | ----------- | ------- |
| AWS | `AWS` | A custom `aws-sdk` instance | |
| resourceArn | `string` | The ARN of your Aurora Serverless Cluster. This value is *required*, but can be overridden when querying. | |

@@ -340,2 +341,26 @@ | secretArn | `string` | The ARN of the secret associated with your database credentials. This is *required*, but can be overridden when querying. | |

## Custom AWS instance
`data-api-client` allows for introducing a custom `AWS` as a parameter. This parameter is optional. If not present - `data-api-client` will fall back to the default `AWS` instance that comes with the library.
```javascript
// Instantiate data-api-client with a custom AWS instance
const data = require('data-api-client')({
AWS: customAWS,
...
})
```
Custom AWS parameter allows to introduce, e.g. tracing Data API calls through X-Ray with:
```javascript
const AWSXRay = require('aws-xray-sdk')
const AWS = AWSXRay.captureAWS(require('aws-sdk'))
const data = require('data-api-client')({
AWS: AWS,
...
})
```
## Data API Limitations / Wonkiness

@@ -342,0 +367,0 @@ The first GA release of the Data API has *a lot* of promise, unfortunately, there are still quite a few things that make it a bit wonky and may require you to implement some workarounds. I've outlined some of my findings below.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc