electrodb
Advanced tools
Comparing version 0.9.12 to 0.9.13
{ | ||
"name": "electrodb", | ||
"version": "0.9.12", | ||
"version": "0.9.13", | ||
"description": "A library to more easily create and interact with multiple entities and heretical relationships in dynamodb", | ||
@@ -34,4 +34,4 @@ "main": "index.js", | ||
"dependencies": { | ||
"jsonschema": "1.2.5" | ||
"jsonschema": "1.2.7" | ||
} | ||
} |
"use strict"; | ||
const { Schema } = require("./schema"); | ||
const { KeyTypes, QueryTypes, MethodTypes, Comparisons } = require("./types"); | ||
const { KeyTypes, QueryTypes, MethodTypes, Comparisons, ExpressionTypes } = require("./types"); | ||
const { FilterFactory, FilterTypes } = require("./filters"); | ||
const { WhereFactory } = require("./where"); | ||
const validations = require("./validations"); | ||
@@ -39,2 +40,6 @@ const { clauses } = require("./clauses"); | ||
); | ||
this._whereBuilder = new WhereFactory( | ||
this.model.schema.attributes, | ||
FilterTypes | ||
) | ||
this._clausesWithFilters = this._filterBuilder.injectFilterClauses( | ||
@@ -44,2 +49,4 @@ clauses, | ||
); | ||
this._clausesWithFilters = this._whereBuilder.injectWhereClauses(this._clausesWithFilters); | ||
this.scan = this._makeChain("", this._clausesWithFilters, clauses.index).scan(); | ||
@@ -91,3 +98,3 @@ this.query = {}; | ||
} | ||
return this._makeChain(index, clauses, clauses.index).collection( | ||
return this._makeChain(index, this._clausesWithFilters, clauses.index).collection( | ||
collection, | ||
@@ -109,3 +116,3 @@ facets, | ||
let index = ""; | ||
return this._makeChain(index, clauses, clauses.index).delete(facets); | ||
return this._makeChain(index, this._clausesWithFilters, clauses.index).delete(facets); | ||
} | ||
@@ -115,3 +122,3 @@ | ||
let index = ""; | ||
return this._makeChain(index, clauses, clauses.index).put(attributes); | ||
return this._makeChain(index, this._clausesWithFilters, clauses.index).put(attributes); | ||
} | ||
@@ -126,3 +133,3 @@ | ||
} | ||
return this._makeChain(index, clauses, clauses.index, options).create(attributes); | ||
return this._makeChain(index, this._clausesWithFilters, clauses.index, options).create(attributes); | ||
} | ||
@@ -132,3 +139,3 @@ | ||
let index = ""; | ||
return this._makeChain(index, clauses, clauses.index).update(facets); | ||
return this._makeChain(index, this._clausesWithFilters, clauses.index).update(facets); | ||
} | ||
@@ -143,3 +150,3 @@ | ||
} | ||
return this._makeChain(index, clauses, clauses.index, options).patch(facets); | ||
return this._makeChain(index, this._clausesWithFilters, clauses.index, options).patch(facets); | ||
} | ||
@@ -303,3 +310,2 @@ | ||
let parameters = Object.assign({}, params); | ||
let stackTrace = new Error(); | ||
@@ -339,2 +345,21 @@ try { | ||
} | ||
_applyParameterExpressionTypes(params, filter) { | ||
if (typeof filter[ExpressionTypes.ConditionExpression] === "string" && filter[ExpressionTypes.ConditionExpression].length > 0) { | ||
if (typeof params[ExpressionTypes.ConditionExpression] === "string" && params[ExpressionTypes.ConditionExpression].length > 0) { | ||
params[ExpressionTypes.ConditionExpression] = `${params[ExpressionTypes.ConditionExpression]} AND ${filter[ExpressionTypes.ConditionExpression]}` | ||
} else { | ||
params[ExpressionTypes.ConditionExpression] = filter[ExpressionTypes.ConditionExpression]; | ||
} | ||
if (Object.keys(filter.ExpressionAttributeNames).length > 0) { | ||
params.ExpressionAttributeNames = params.ExpressionAttributeNames || {}; | ||
params.ExpressionAttributeNames = Object.assign({}, filter.ExpressionAttributeNames, params.ExpressionAttributeNames); | ||
} | ||
if (Object.keys(filter.ExpressionAttributeValues).length > 0) { | ||
params.ExpressionAttributeValues = params.ExpressionAttributeValues || {}; | ||
params.ExpressionAttributeValues = Object.assign({}, filter.ExpressionAttributeValues, params.ExpressionAttributeValues); | ||
} | ||
} | ||
return params; | ||
} | ||
/* istanbul ignore next */ | ||
@@ -369,3 +394,4 @@ _params({ keys = {}, method = "", put = {}, update = {}, filter = {}, options = {} }, config = {}) { | ||
} | ||
return this._applyParameterOptions(params, options, config); | ||
params = this._applyParameterOptions(params, options, config); | ||
return this._applyParameterExpressionTypes(params, filter); | ||
} | ||
@@ -372,0 +398,0 @@ |
@@ -1,14 +0,3 @@ | ||
let queryChildren = [ | ||
"eq", | ||
"gt", | ||
"lt", | ||
"gte", | ||
"lte", | ||
"between", | ||
"begins", | ||
"exists", | ||
"notExists", | ||
"contains", | ||
"notContains", | ||
]; | ||
const {MethodTypes, ExpressionTypes} = require("./types"); | ||
let FilterTypes = { | ||
@@ -103,2 +92,15 @@ eq: { | ||
getExpressionType(methodType) { | ||
switch (methodType) { | ||
case MethodTypes.put: | ||
case MethodTypes.create: | ||
case MethodTypes.update: | ||
case MethodTypes.patch: | ||
case MethodTypes.delete: | ||
return ExpressionTypes.ConditionExpression | ||
default: | ||
return ExpressionTypes.FilterExpression | ||
} | ||
} | ||
_buildFilterAttributes(setName, setValue, getValueCount) { | ||
@@ -146,5 +148,2 @@ let attributes = {}; | ||
} | ||
// if (newNeedsParens) { | ||
// newExpression = `(${newExpression})`; | ||
// } | ||
return `${existingExpression} AND ${newExpression}`; | ||
@@ -158,2 +157,3 @@ } else { | ||
return (entity, state, ...params) => { | ||
let expressionType = this.getExpressionType(state.query.method); | ||
state.query.filter.ExpressionAttributeNames = | ||
@@ -183,4 +183,4 @@ state.query.filter.ExpressionAttributeNames || {}; | ||
} | ||
state.query.filter.FilterExpression = this._concatFilterExpression( | ||
state.query.filter.FilterExpression, | ||
state.query.filter[expressionType] = this._concatFilterExpression( | ||
state.query.filter[expressionType], | ||
expression, | ||
@@ -187,0 +187,0 @@ ); |
@@ -306,44 +306,44 @@ const { KeyTypes, CastTypes, AttributeTypes } = require("./types"); | ||
_getPartDetail(part = "") { | ||
let detail = { | ||
expression: "", | ||
name: "", | ||
value: "", | ||
}; | ||
if (part.includes("[")) { | ||
if (!part.match(/\[\d\]/gi)) { | ||
throw new Error(`Invalid path: Part "${part}" has bracket containing non-numeric characters.`); | ||
} | ||
let [name] = part.match(/.*(?=\[)/gi); | ||
detail.name = `#${name}`; | ||
detail.value = name; | ||
} else { | ||
detail.name = `#${part}`; | ||
detail.value = part; | ||
} | ||
detail.expression = `#${part}`; | ||
return detail; | ||
} | ||
// _getPartDetail(part = "") { | ||
// let detail = { | ||
// expression: "", | ||
// name: "", | ||
// value: "", | ||
// }; | ||
// if (part.includes("[")) { | ||
// if (!part.match(/\[\d\]/gi)) { | ||
// throw new Error(`Invalid path: Part "${part}" has bracket containing non-numeric characters.`); | ||
// } | ||
// let [name] = part.match(/.*(?=\[)/gi); | ||
// detail.name = `#${name}`; | ||
// detail.value = name; | ||
// } else { | ||
// detail.name = `#${part}`; | ||
// detail.value = part; | ||
// } | ||
// detail.expression = `#${part}`; | ||
// return detail; | ||
// } | ||
parseAttributePath(path = "") { | ||
if (typeof path !== "string" || !path.length) { | ||
throw new Error("Invalid path: Path must be a string with a non-zero length"); | ||
} | ||
let parts = path.split(/\./gi); | ||
let attr = this._getPartDetail(parts[0]); | ||
let target = this._getPartDetail(parts[parts.length-1]).value; | ||
if (this.attributes[attr.value] === undefined) { | ||
throw new Error(`Invalid path: Target attribute "${attr.value}" does not exist in model`); | ||
} else if (attr.expression.includes("[") && this.attributes[attr.value].type !== AttributeTypes.list) { | ||
throw new Error(`Invalid path: Target attribute "${attr.value}" is not of type "${AttributeTypes.list}"`); | ||
} | ||
let names = {}; | ||
let expressions = []; | ||
for (let part of parts) { | ||
let detail = this._getPartDetail(part); | ||
names[detail.name] = detail.value; | ||
expressions.push(detail.expression); | ||
} | ||
return {path, names, target, attr: attr.value, expression: expressions.join(".")}; | ||
} | ||
// parseAttributePath(path = "") { | ||
// if (typeof path !== "string" || !path.length) { | ||
// throw new Error("Invalid path: Path must be a string with a non-zero length"); | ||
// } | ||
// let parts = path.split(/\./gi); | ||
// let attr = this._getPartDetail(parts[0]); | ||
// let target = this._getPartDetail(parts[parts.length-1]).value; | ||
// if (this.attributes[attr.value] === undefined) { | ||
// throw new Error(`Invalid path: Target attribute "${attr.value}" does not exist in model`); | ||
// } else if (attr.expression.includes("[") && this.attributes[attr.value].type !== AttributeTypes.list) { | ||
// throw new Error(`Invalid path: Target attribute "${attr.value}" is not of type "${AttributeTypes.list}"`); | ||
// } | ||
// let names = {}; | ||
// let expressions = []; | ||
// for (let part of parts) { | ||
// let detail = this._getPartDetail(part); | ||
// names[detail.name] = detail.value; | ||
// expressions.push(detail.expression); | ||
// } | ||
// return {path, names, target, attr: attr.value, expression: expressions.join(".")}; | ||
// } | ||
@@ -350,0 +350,0 @@ applyAttributeGetters(payload = {}) { |
@@ -50,2 +50,7 @@ const KeyTypes = { | ||
const ExpressionTypes = { | ||
ConditionExpression: "ConditionExpression", | ||
FilterExpression: "FilterExpression" | ||
} | ||
module.exports = { | ||
@@ -58,2 +63,3 @@ KeyTypes, | ||
AttributeTypes, | ||
ExpressionTypes, | ||
}; |
@@ -396,3 +396,9 @@ const { Entity, clauses } = require("../src/entity"); | ||
message: `Invalid value for attribute "data": Expected value to be an Array or javascript Set to fulfill attribute type "set".` | ||
}, | ||
},{ | ||
input: { | ||
type: "invalid_type" | ||
}, | ||
fail: true, | ||
message: `Invalid "type" property for attribute: "data". Acceptable types include string, number, boolean, enum, map, set, list, any` | ||
} | ||
]; | ||
@@ -428,8 +434,14 @@ let schema = { | ||
let data = test.input.value; | ||
let entity = new Entity(schema); | ||
if (test.fail) { | ||
expect(() => entity.put({id, data}).params()).to.throw(test.message); | ||
expect(() => { | ||
let entity = new Entity(schema); | ||
entity.put({id, data}).params() | ||
}).to.throw(test.message); | ||
} else { | ||
expect(() => entity.put({id, data}).params()).to.not.throw(); | ||
expect(() => { | ||
let entity = new Entity(schema); | ||
entity.put({id, data}).params() | ||
}).to.not.throw(); | ||
} | ||
@@ -654,5 +666,7 @@ } | ||
let del = MallStores.delete({ id }); | ||
expect(del).to.have.keys("go", "params"); | ||
expect(del).to.have.keys("go", "params", "where", "filter", "rentsLeaseEndFilter"); | ||
let update = MallStores.update({ id }).set({ rent, category }); | ||
expect(update).to.have.keys("go", "params", "set"); | ||
expect(update).to.have.keys("go", "params", "set", "filter", "where", "rentsLeaseEndFilter"); | ||
let patch = MallStores.patch({ id }).set({ rent, category }); | ||
expect(patch).to.have.keys("go", "params", "set", "filter", "where", "rentsLeaseEndFilter"); | ||
let put = MallStores.put({ | ||
@@ -667,3 +681,13 @@ store, | ||
}); | ||
expect(put).to.have.keys("go", "params"); | ||
expect(put).to.have.keys("go", "params", "where", "filter", "rentsLeaseEndFilter"); | ||
let create = MallStores.create({ | ||
store, | ||
mall, | ||
building, | ||
rent, | ||
category, | ||
leaseEnd, | ||
unit, | ||
}); | ||
expect(create).to.have.keys("go", "params", "where", "filter", "rentsLeaseEndFilter"); | ||
let queryUnitsBetween = MallStores.query | ||
@@ -673,2 +697,3 @@ .units({ mall }) | ||
expect(queryUnitsBetween).to.have.keys( | ||
"where", | ||
"filter", | ||
@@ -682,2 +707,3 @@ "go", | ||
expect(queryUnitGt).to.have.keys( | ||
"where", | ||
"filter", | ||
@@ -691,2 +717,3 @@ "go", | ||
expect(queryUnitsGte).to.have.keys( | ||
"where", | ||
"filter", | ||
@@ -700,2 +727,3 @@ "go", | ||
expect(queryUnitsLte).to.have.keys( | ||
"where", | ||
"filter", | ||
@@ -709,2 +737,3 @@ "go", | ||
expect(queryUnitsLt).to.have.keys( | ||
"where", | ||
"filter", | ||
@@ -716,2 +745,16 @@ "go", | ||
); | ||
let find = MallStores.query.units({ mall }); | ||
expect(find).to.have.keys( | ||
"between", | ||
"gt", | ||
"gte", | ||
"lt", | ||
"lte", | ||
"where", | ||
"filter", | ||
"go", | ||
"params", | ||
"page", | ||
"rentsLeaseEndFilter", | ||
); | ||
}); | ||
@@ -1822,2 +1865,18 @@ it("Should make scan parameters", () => { | ||
let leaseEnd = "123"; | ||
it("Should decide to scan", () => { | ||
let { index, keys, shouldScan} = MallStores._findBestIndexKeyMatch({ leaseEnd }); | ||
let params = MallStores.find({leaseEnd}).params(); | ||
expect(params).to.be.deep.equal({ | ||
TableName: 'StoreDirectory', | ||
ExpressionAttributeNames: { '#leaseEnd': 'leaseEnd', '#pk': 'pk' }, | ||
ExpressionAttributeValues: { | ||
':leaseEnd1': '123', | ||
':pk': '$mallstoredirectory_1$mallstores#id_' | ||
}, | ||
FilterExpression: '(begins_with(#pk, :pk) AND #leaseEnd = :leaseEnd1' | ||
}); | ||
expect(shouldScan).to.be.true; | ||
expect(keys).to.be.deep.equal([]); | ||
expect(index).to.be.equal(""); | ||
}); | ||
it("Should match on the primary index", () => { | ||
@@ -1824,0 +1883,0 @@ let { index, keys } = MallStores._findBestIndexKeyMatch({ id }); |
Sorry, the diff of this file is too big to display
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
362657
24
8011
2257
5
+ Addedjsonschema@1.2.7(transitive)
- Removedjsonschema@1.2.5(transitive)
Updatedjsonschema@1.2.7