@begin/data
Advanced tools
Comparing version 4.0.0-RC.1 to 4.0.0-RC.2
@@ -7,4 +7,11 @@ # Begin Data changelog | ||
### Added | ||
- Added support for Sandbox dynamic port selection | ||
- Added best-effort attempt to find Sandbox ports via internal SSM | ||
### Changed | ||
- Deep require `aws-sdk` deps for a potentially large cold start perf boost | ||
- Breaking change: Begin Data no longer relies on or makes direct use of `NODE_ENV` or other legacy Architect env vars. `@begin/data` v4+ now requires Architect v10 / Sandbox v5 or later. | ||
@@ -11,0 +18,0 @@ - Improved table lookup performance |
{ | ||
"name": "@begin/data", | ||
"version": "4.0.0-RC.1", | ||
"version": "4.0.0-RC.2", | ||
"description": "Begin Data is a durable and fast key/value document store built on top of DynamoDB", | ||
"main": "index.js", | ||
"main": "src/index.js", | ||
"scripts": { | ||
@@ -23,2 +23,5 @@ "lint": "eslint --fix .", | ||
}, | ||
"files": [ | ||
"src/*" | ||
], | ||
"dependencies": { | ||
@@ -31,6 +34,6 @@ "@begin/hashid": "^1.0.0", | ||
"@architect/eslint-config": "^2.0.1", | ||
"@architect/sandbox": "^5.0.0-RC.9", | ||
"eslint": "^8.8.0", | ||
"@architect/sandbox": "^5.1.0-RC.0", | ||
"eslint": "^8.10.0", | ||
"tap-spec": "^5.0.0", | ||
"tape": "^5.5.0", | ||
"tape": "^5.5.2", | ||
"tiny-json-http": "^7.3.1" | ||
@@ -37,0 +40,0 @@ }, |
@@ -16,4 +16,6 @@ /** | ||
module.exports = function count ({ table }, callback) { | ||
if (!table) | ||
if (!table) { | ||
throw ReferenceError('Missing params.table') | ||
} | ||
let promise | ||
@@ -27,2 +29,3 @@ if (!callback) { | ||
} | ||
let { scopeID, dataID } = getKey({ table, key: 'UNKNOWN' }) | ||
@@ -55,7 +58,6 @@ waterfall([ | ||
if (err) callback(err) | ||
else { | ||
callback(null, result.ScannedCount) | ||
} | ||
else callback(null, result.ScannedCount) | ||
}) | ||
return promise | ||
} |
@@ -1,3 +0,4 @@ | ||
let aws = require('aws-sdk') | ||
let https = require('https') | ||
let getPorts = require('./_get-ports') | ||
let db, doc | ||
@@ -9,43 +10,61 @@ /** | ||
if (!type) throw ReferenceError('Must supply Dynamo service interface type') | ||
let { ARC_ENV, ARC_SANDBOX, AWS_REGION } = process.env | ||
let testing = ARC_ENV === 'testing' | ||
let local | ||
if (testing) { | ||
let { ports } = JSON.parse(ARC_SANDBOX) | ||
let port = ports.tables | ||
local = { | ||
endpoint: new aws.Endpoint(`http://localhost:${port}`), | ||
region: AWS_REGION || 'us-west-2' // Do not assume region is set! | ||
} | ||
// We really only want to load aws-sdk if absolutely necessary | ||
// eslint-disable-next-line | ||
let dynamo = require('aws-sdk/clients/dynamodb') | ||
let { ARC_ENV, AWS_REGION } = process.env | ||
let local = ARC_ENV === 'testing' | ||
let DB = dynamo | ||
let Doc = dynamo.DocumentClient | ||
if (db && type === 'db') { | ||
return callback(null, db) | ||
} | ||
let DB = aws.DynamoDB | ||
let Doc = aws.DynamoDB.DocumentClient | ||
let dynamo // Assigned below | ||
if (doc && type === 'doc') { | ||
return callback(null, doc) | ||
} | ||
if (!testing) { | ||
if (!local) { | ||
let agent = new https.Agent({ | ||
keepAlive: true, | ||
maxSockets: 50, | ||
maxSockets: 50, // Node can set to Infinity; AWS maxes at 50; check back on this every once in a while | ||
rejectUnauthorized: true, | ||
}) | ||
aws.config.update({ | ||
// TODO? migrate to using `AWS_NODEJS_CONNECTION_REUSE_ENABLED`? | ||
let config = { | ||
httpOptions: { agent } | ||
} | ||
if (type === 'db') { | ||
db = new DB(config) | ||
return callback(null, db) | ||
} | ||
if (type === 'doc') { | ||
doc = new Doc(config) | ||
return callback(null, doc) | ||
} | ||
} | ||
else { | ||
getPorts((err, ports) => { | ||
if (err) callback(err) | ||
else { | ||
let port = ports.tables | ||
if (!port) { | ||
return callback(ReferenceError('Sandbox tables port not found')) | ||
} | ||
let config = { | ||
endpoint: `http://localhost:${port}`, | ||
region: AWS_REGION || 'us-west-2' // Do not assume region is set! | ||
} | ||
if (type === 'db') { | ||
db = new DB(config) | ||
return callback(null, db) | ||
} | ||
if (type === 'doc') { | ||
doc = new Doc(config) | ||
return callback(null, doc) | ||
} | ||
} | ||
}) | ||
// TODO? migrate to using `AWS_NODEJS_CONNECTION_REUSE_ENABLED`? | ||
} | ||
if (type === 'db') { | ||
dynamo = testing | ||
? new DB(local) | ||
: new DB | ||
} | ||
if (type === 'doc') { | ||
dynamo = testing | ||
? new Doc(local) | ||
: new Doc | ||
} | ||
callback(null, dynamo) | ||
} | ||
@@ -52,0 +71,0 @@ |
@@ -1,44 +0,52 @@ | ||
let aws = require('aws-sdk') | ||
let http = require('http') | ||
let toLogicalID = require('./_to-logical-id') | ||
let getPorts = require('./_get-ports') | ||
let tablename = false | ||
module.exports = function getTableName (callback) { | ||
let { ARC_APP_NAME, ARC_ENV, ARC_SANDBOX, AWS_REGION, BEGIN_DATA_TABLE_NAME } = process.env | ||
let { ARC_APP_NAME: app, ARC_ENV, AWS_REGION, BEGIN_DATA_TABLE_NAME } = process.env | ||
if (BEGIN_DATA_TABLE_NAME) { | ||
callback(null, BEGIN_DATA_TABLE_NAME) | ||
return callback(null, BEGIN_DATA_TABLE_NAME) | ||
} | ||
// Use cached value | ||
else if (tablename) { | ||
callback(null, tablename) | ||
if (tablename) { | ||
return callback(null, tablename) | ||
} | ||
else { | ||
let isLocal = ARC_ENV === 'testing' | ||
let config | ||
if (isLocal) { | ||
// If running in Sandbox, use its SSM service discovery mock | ||
let { ports } = JSON.parse(ARC_SANDBOX) | ||
let port = ports._arc | ||
config = { | ||
endpoint: new aws.Endpoint(`http://localhost:${port}/_arc/ssm`), | ||
// We really only want to load aws-sdk if absolutely necessary, and only the client we need | ||
// eslint-disable-next-line | ||
let SSM = require('aws-sdk/clients/ssm') | ||
let local = ARC_ENV === 'testing' | ||
if (!local && !app) { | ||
return callback(ReferenceError('ARC_APP_NAME env var not found')) | ||
} | ||
if (local && !app) { | ||
app = 'arc-app' | ||
} | ||
let Name = `/${toLogicalID(`${app}-${ARC_ENV}`)}/tables/data` | ||
if (local) { | ||
getPorts((err, ports) => { | ||
if (err) callback(err) | ||
else go({ | ||
endpoint: `http://localhost:${ports._arc}/_arc/ssm`, | ||
region: AWS_REGION || 'us-west-2', | ||
httpOptions: { agent: new http.Agent() } | ||
} | ||
} | ||
let ssm = new aws.SSM(config) | ||
let appName = toLogicalID(`${ARC_APP_NAME}-${ARC_ENV}`) | ||
let Path = `/${appName}` | ||
ssm.getParametersByPath({ Path, Recursive: true }, function done (err, result) { | ||
}) | ||
}) | ||
} | ||
else go() | ||
function go (config) { | ||
let ssm = new SSM(config) | ||
ssm.getParameter({ Name }, function done (err, result) { | ||
if (err) callback(err) | ||
else { | ||
let table = param => param.Name.split('/')[2] === 'tables' | ||
let tables = result.Parameters.filter(table).reduce((a, b) => { | ||
a[b.Name.split('/')[3]] = b.Value | ||
return a | ||
}, {}) | ||
if (!tables.data) { | ||
callback(ReferenceError('begin/data requires a table named data')) | ||
let table = result.Parameter | ||
if (!table) { | ||
callback(ReferenceError('@begin/data requires a table named data')) | ||
} | ||
else { | ||
tablename = tables.data | ||
tablename = table.Value | ||
callback(null, tablename) | ||
@@ -50,15 +58,1 @@ } | ||
} | ||
function toLogicalID (str) { | ||
str = str.replace(/([A-Z])/g, ' $1') | ||
if (str.length === 1) { | ||
return str.toUpperCase() | ||
} | ||
str = str.replace(/^[\W_]+|[\W_]+$/g, '').toLowerCase() | ||
str = str.charAt(0).toUpperCase() + str.slice(1) | ||
str = str.replace(/[\W_]+(\w|$)/g, (_, ch) => ch.toUpperCase()) | ||
if (str === 'Get') { | ||
return 'GetIndex' | ||
} | ||
return str | ||
} |
@@ -12,5 +12,5 @@ let get = require('./get') | ||
module.exports = function page (props) { | ||
if (!props.table) | ||
if (!props.table) { | ||
throw ReferenceError('Missing params.table') | ||
} | ||
@@ -21,3 +21,2 @@ let cursor = false | ||
function next () { | ||
// signal completion | ||
@@ -24,0 +23,0 @@ if (finished) { |
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
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
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
38320
1009
1
6