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

@aws-lite/client

Package Overview
Dependencies
Maintainers
3
Versions
73
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@aws-lite/client - npm Package Compare versions

Comparing version 0.12.2 to 0.13.0

15

package.json
{
"name": "@aws-lite/client",
"version": "0.12.2",
"version": "0.13.0",
"description": "A simple, fast, extensible AWS client",

@@ -19,5 +19,5 @@ "homepage": "https://github.com/architect/aws-lite",

"test:precommit": "cross-env PRECOMMIT=true npm run gen && npm run lint",
"test:integration": "cross-env tape 'test/integration/**/*-test.js' | tap-spec",
"test:unit": "cross-env tape 'test/unit/**/*-test.js' | tap-spec",
"test:live": "cross-env tape 'test/live/**/*-test.js' | tap-spec",
"test:integration": "cross-env tape 'test/integration/**/*-test.js' | tap-arc",
"test:unit": "cross-env tape 'test/unit/**/*-test.js' | tap-arc",
"test:live": "cross-env tape 'test/live/**/*-test.js' | tap-arc",
"coverage": "nyc --reporter=lcov --reporter=text npm run test:unit",

@@ -53,3 +53,3 @@ "vendor": "scripts/vendor/vendor.sh"

"simple-git-hooks": "^2.9.0",
"tap-spec": "^5.0.0",
"tap-arc": "^1.2.2",
"tape": "^5.7.0"

@@ -61,3 +61,8 @@ },

"workspaces": [
"plugins/apigateway",
"plugins/apigatewaymanagementapi",
"plugins/apigatewayv2",
"plugins/cloudformation",
"plugins/cloudfront",
"plugins/cloudwatch-logs",
"plugins/dynamodb",

@@ -64,0 +69,0 @@ "plugins/lambda",

@@ -195,3 +195,7 @@ <h1><a href="https://aws-lite.org"><code>aws-lite</code></a></h1>

<!-- plugins_start -->
- [API Gateway V2](https://www.npmjs.com/package/@aws-lite/apigatewayv2)
- [API Gateway WebSocket Management API](https://www.npmjs.com/package/@aws-lite/apigatewaymanagementapi)
- [CloudFormation](https://www.npmjs.com/package/@aws-lite/cloudformation)
- [CloudFront](https://www.npmjs.com/package/@aws-lite/cloudfront)
- [CloudWatch Logs](https://www.npmjs.com/package/@aws-lite/cloudwatch-logs)
- [DynamoDB](https://www.npmjs.com/package/@aws-lite/dynamodb)

@@ -198,0 +202,0 @@ - [Lambda](https://www.npmjs.com/package/@aws-lite/lambda)

@@ -1,7 +0,5 @@

let { readdir } = require('fs/promises')
let { join } = require('path')
let { services } = require('./services')
let request = require('./request')
let { validateInput } = require('./validate')
let { awsjson } = require('./lib')
let { awsjson, exists } = require('./lib')
let errorHandler = require('./error')

@@ -54,2 +52,4 @@ let aws

if (autoloadPlugins) {
let { readdir } = require('fs/promises')
let { join } = require('path')
let awsLite = '@aws-lite'

@@ -59,12 +59,14 @@ let nodeModulesDir

catch { nodeModulesDir = join(process.cwd(), 'node_modules') } // Likely just aws-lite tests
let mods = await readdir(nodeModulesDir)
// Find first-party plugins
if (mods.includes(awsLite)) {
let knownPlugins = await readdir(join(nodeModulesDir, awsLite))
let filtered = knownPlugins.filter(p => !ignored.includes(p) && !p.endsWith('-types')).map(p => `@aws-lite/${p}`)
plugins.push(...filtered)
if (await exists(nodeModulesDir)) {
let mods = await readdir(nodeModulesDir)
// Find first-party plugins
if (mods.includes(awsLite)) {
let knownPlugins = await readdir(join(nodeModulesDir, awsLite))
let filtered = knownPlugins.filter(p => !ignored.includes(p) && !p.endsWith('-types')).map(p => `@aws-lite/${p}`)
plugins.push(...filtered)
}
// Find correctly namespaced 3rd-party plugins
let findPlugins = mod => mod.startsWith('aws-lite-plugin-') && plugins.push(mod)
mods.forEach(findPlugins)
}
// Find correctly namespaced 3rd-party plugins
let findPlugins = mod => mod.startsWith('aws-lite-plugin-') && plugins.push(mod)
mods.forEach(findPlugins)
}

@@ -78,3 +80,2 @@

try {
// eslint-disable-next-line
plugin = require(pluginName)

@@ -115,3 +116,2 @@ }

if (!aws) {
// eslint-disable-next-line
aws = require('./_vendor/aws')

@@ -199,3 +199,3 @@ }

let updatedError
if (method.error && !(input instanceof Error)) {
if (method.error && !(err instanceof Error)) {
try {

@@ -202,0 +202,0 @@ updatedError = await method.error(err, { ...pluginUtils, region: selectedRegion })

@@ -22,7 +22,12 @@ module.exports = function errorHandler (input) {

// The most common error response from AWS services
// Note: many services return a `Code` property; this generally represents the coded error name
// (jic, also look for `code` and `__type`)
if (error && typeof error === 'object') {
Object.entries(error).forEach(([ name, value ]) => {
if (name.toLowerCase() === 'message') err.message = value
else err[name] = value
Object.entries(error).forEach(([ n, value ]) => {
const name = n.toLowerCase()
/**/ if (name === 'message') err[name] = value
else if (name === 'code') err[name] = err.name = value
else err[n] = value
})
if (err.__type && !err.code) err.code = err.name = err.__type
}

@@ -29,0 +34,0 @@ // Less common: sometimes strings (of XML), possibly without a content-type

@@ -1,2 +0,2 @@

let aws, ini
let aws, ini, xml

@@ -60,2 +60,12 @@ // AWS-flavored JSON stuff

function tidyQuery (obj) {
let qs = require('querystring')
let tidied = {}
Object.entries(obj).forEach(([ k, v ]) => {
// Who knows, maybe there's an API service that uses boolean query string params
if (v || v === false) tidied[k] = v
})
if (Object.keys(tidied).length) return qs.stringify(tidied)
}
// Probably this is going to need some refactoring in Arc 11

@@ -74,2 +84,52 @@ // Certainly it is not reliable in !Arc local Lambda emulation

module.exports = { awsjson, exists, loadAwsConfig, readConfig, useAWS }
// XML stuff
let textNodeName = '#text'
/* istanbul ignore next */
function instantiateXml () {
if (xml) return
// Only require the vendor if + when it's actually needed
let vendor = require('./_vendor/xml')
// The following was pulled directly from AWS's implementations of `fast-xml-parser` in SDKv3
xml = {
parser: new vendor.XMLParser({
attributeNamePrefix: '',
htmlEntities: true,
ignoreAttributes: false,
ignoreDeclaration: true,
parseTagValue: false,
trimValues: false,
tagValueProcessor: (_, val) => (val.trim() === '' && val.includes('\n') ? '' : undefined),
}),
builder: new vendor.XMLBuilder(),
}
xml.parser.addEntity('#xD', '\r')
xml.parser.addEntity('#10', '\n')
xml.parser.getValueFromTextNode = vendor.getValueFromTextNode
}
function buildXml (obj) {
instantiateXml()
return xml.builder.build(obj)
}
function parseXml (body) {
instantiateXml()
let parsed = xml.parser.parse(body)
let key = Object.keys(parsed)[0]
let payloadToReturn = parsed[key]
/* istanbul ignore next */ // TODO remove + test
if (payloadToReturn[textNodeName]) {
payloadToReturn[key] = payloadToReturn[textNodeName]
delete payloadToReturn[textNodeName]
}
return xml.parser.getValueFromTextNode(payloadToReturn)
}
module.exports = {
awsjson,
exists,
loadAwsConfig,
readConfig,
tidyQuery,
useAWS,
buildXml,
parseXml,
}

@@ -1,8 +0,4 @@

let qs = require('querystring')
let { Readable } = require('stream')
let aws4 = require('aws4')
let { globalServices, semiGlobalServices } = require('./services')
let { is } = require('./validate')
let { awsjson, useAWS } = require('./lib')
let xml
let { awsjson, buildXml, parseXml, tidyQuery, useAWS } = require('./lib')

@@ -17,3 +13,2 @@ /* istanbul ignore next */

let XMLContentType = ct => ct.match(XMLregex)
let textNodeName = '#text'

@@ -37,31 +32,2 @@ // HTTP client agent cache to prevent generating new agents for every request

}
/* istanbul ignore next */
function instantiateXml () {
// eslint-disable-next-line
let vendor = require('./_vendor/xml')
// The following was pulled directly from AWS's implementations of `fast-xml-parser` in SDKv3
xml = new vendor.XMLParser({
attributeNamePrefix: '',
htmlEntities: true,
ignoreAttributes: false,
ignoreDeclaration: true,
parseTagValue: false,
trimValues: false,
tagValueProcessor: (_, val) => (val.trim() === '' && val.includes('\n') ? '' : undefined),
})
xml.addEntity('#xD', '\r')
xml.addEntity('#10', '\n')
xml.getValueFromTextNode = vendor.getValueFromTextNode
}
function parseXml (body) {
let parsed = xml.parse(body)
let key = Object.keys(parsed)[0]
let payloadToReturn = parsed[key]
/* istanbul ignore next */ // TODO remove + test
if (payloadToReturn[textNodeName]) {
payloadToReturn[key] = payloadToReturn[textNodeName]
delete payloadToReturn[textNodeName]
}
return xml.getValueFromTextNode(payloadToReturn)
}

@@ -105,7 +71,11 @@ module.exports = async function _request (params, creds, region, config, metadata) {

if (params.query) {
let { is } = require('./validate')
if (!is.object(params.query)) {
throw ReferenceError('Query property must be an object')
}
// Expect aws4 to handle RFC 3986 encoding when appending the query string to the passed path
params.path += '?' + qs.stringify(params.query)
let query = tidyQuery(params.query)
if (query) {
// Expect aws4 to handle RFC 3986 encoding when appending the query string to the passed path
params.path += '?' + query
}
}

@@ -122,3 +92,3 @@

let isBuffer = body instanceof Buffer
let isStream = body instanceof Readable
let isStream = (body?.on && body?._read && body?._readableState)

@@ -130,15 +100,20 @@ // Detecting objects leaves open the possibility of some weird valid JSON (like just a null), deal with it if / when we need to I guess

// A variety of services use AWS JSON; we'll make it easier via a header or passed param
// Allow for manual encoding by passing a header while setting awsjson to false
let awsjsonEncode = params.awsjson ||
(AwsJSONContentType(contentType) && params.awsjson !== false)
if (awsjsonEncode) {
// Backfill content-type header yet again
if (!AwsJSONContentType(contentType)) {
contentType = 'application/x-amz-json-1.0'
if (XMLContentType(contentType)) {
params.body = buildXml(body)
}
else {
// A variety of services use AWS JSON; we'll make it easier via a header or passed param
// Allow for manual encoding by passing a header while setting awsjson to false
let awsjsonEncode = params.awsjson ||
(AwsJSONContentType(contentType) && params.awsjson !== false)
if (awsjsonEncode) {
// Backfill content-type header yet again
if (!AwsJSONContentType(contentType)) {
contentType = 'application/x-amz-json-1.0'
}
body = awsjson.marshall(body, params.awsjson)
}
body = awsjson.marshall(body, params.awsjson)
// Final JSON encoding
params.body = JSON.stringify(body)
}
// Final JSON encoding
params.body = JSON.stringify(body)
}

@@ -186,3 +161,3 @@ // Everything besides streams pass through for signing

let isHTTPS = options.host.includes('.amazonaws.com') || options.protocol === 'https:'
/* istanbul ignore next */ // eslint-disable-next-line
/* istanbul ignore next */
let http = isHTTPS ? require('https') : require('http')

@@ -220,3 +195,5 @@

let body = Buffer.concat(data), payload, rawString
let contentType = config.responseContentType || headers['content-type'] || headers['Content-Type'] || ''
let contentType = config.responseContentType ||
headers['content-type'] ||
headers['Content-Type'] || ''
if (body.length && (JSONContentType(contentType) || AwsJSONContentType(contentType))) {

@@ -237,6 +214,5 @@ payload = JSON.parse(body)

if (body.length && XMLContentType(contentType)) {
// Only require the vendor if it's actually needed
payload = parseXml(body)
/* istanbul ignore next */
if (!xml) instantiateXml()
payload = parseXml(body)
if (payload.xmlns) delete payload.xmlns

@@ -254,5 +230,2 @@ /* istanbul ignore next */

try {
// Only require the vendor if it's actually needed
/* istanbul ignore next */
if (!xml) instantiateXml()
payload = parseXml(body)

@@ -321,2 +294,4 @@ }

let { type, cursor, token, accumulator } = params.paginator
let nestedAccumulator = accumulator.split('.').length > 1
if (!cursor || typeof cursor !== 'string') {

@@ -340,2 +315,3 @@ throw ReferenceError(`aws-lite paginator requires a cursor property name (string)`)

let items = []
let statusCode, headers
async function get () {

@@ -352,10 +328,38 @@ let result = await request(

}
if (!result.payload[accumulator]) {
let accumulated = nestedAccumulator
? accumulator.split('.').reduce((parent, child) => parent?.[child], result.payload)
: result.payload[accumulator]
if (!accumulated) {
throw ReferenceError(`Pagination error: response accumulator property '${accumulator}' not found`)
}
if (!Array.isArray(result.payload[accumulator])) {
throw ReferenceError(`Pagination error: response accumulator property '${accumulator}' must be an array`)
// Best effort handling of properties that sometimes are / are not arrays, courtesy of XML
// This can perhaps backfire in a few different ways, so hold onto your butts
if (accumulated && !Array.isArray(accumulated)) {
accumulated = [ accumulated ]
}
items.push(...result.payload[accumulator])
// Update statusCode and headers for response hooks
statusCode = result.statusCode
headers = result.headers
// Exit if we're out of results
if (!accumulated.length) {
return
}
// Some services will just keep re-sending the final page with the final token
// Exit here to prevent infinite loops if cursors match
if (result.payload[token] && (type === 'payload' || !type) &&
result.payload[token] === params.payload[cursor]) {
return
}
if (result.payload[token] && (type === 'query') &&
result.payload[token] === params.query[cursor]) {
return
}
items.push(...accumulated)
if (result.payload[token]) {

@@ -375,3 +379,13 @@ if (type === 'payload' || !type) {

await get()
return { payload: { [accumulator]: items } }
if (nestedAccumulator) {
return { statusCode, headers, payload: reNestAccumulated(accumulator, items) }
}
return { statusCode, headers, payload: { [accumulator]: items } }
}
/* istanbul ignore next */
function reNestAccumulated (acc, items) {
acc = Array.isArray(acc) ? acc : acc.split('.')
if (!acc.length) return items
return { [acc.shift()]: reNestAccumulated(acc, items) }
}
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