electrodb
Advanced tools
Comparing version 0.8.10 to 0.8.11
{ | ||
"name": "electrodb", | ||
"version": "0.8.10", | ||
"version": "0.8.11", | ||
"description": "A library to more easily create and interact with multiple entities and heretical relationships in dynamodb", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
110
README.md
@@ -27,2 +27,4 @@ # ElectroDB | ||
- [Facets](#facets) | ||
- [Facet Arrays](#facet-arrays) | ||
- [Facet Templates](#facet-templates) | ||
- [Filters](#filters) | ||
@@ -243,3 +245,3 @@ - [Defined on the model](#defined-on-the-model) | ||
| `sk` | `object` | no | Configuration for the sk of that index or table | | ||
`sk.facets` | `boolean` | no | An array that represents the order in which attributes are concatenated to facets the key (see [Facets](#facets) below for more on this functionality). | | ||
`sk.facets` | `array | string` | no | Either an Array that represents the order in which attributes are concatenated to facets the key, or a String for a facet template. (see [Facets](#facets) below for more on this functionality). | | ||
`sk.field` | `string` | yes | The name of the attribute as it exists dynamo, if named differently in the schema attributes. | | ||
@@ -251,5 +253,48 @@ `index` | `string` | yes | Used only when the `Index` defined is a *Global Secondary Index*; this is left blank for the table's primary index. | ||
There are two ways to provide facets: | ||
1. As a [Facet Array](#facet-arrays) | ||
2. As a [Facet Template](#facet-templates) | ||
For example, in the following **Access Pattern**, "`locations`" is made up of the facets `storeId`, `mallId`, `buildingId` and `unitId` which map to defined attributes in the `schema`: | ||
``` | ||
// Input | ||
{ | ||
storeId: "STOREVALUE", | ||
mallId: "MALLVALUE", | ||
buildingId: "BUILDINGVALUE", | ||
unitId: "UNITVALUE" | ||
}; | ||
// Output: | ||
{ | ||
pk: '$mallstoredirectory_1#storeId_storevalue', | ||
sk: '$mallstores#mallid_mallvalue#buildingid_buildingvalue#unitid_unitvalue' | ||
} | ||
``` | ||
For `PK` values, the `service` and `version` values from the model are prefixed onto the key. | ||
For `SK` values, the `entity` value from the model is prefixed onto the key. | ||
### Facet Arrays | ||
In a Facet Array, each element is the name of the corresponding Attribute defined in the Model. If the Attribute has a `label` property, that will be used to prefix the facets, otherwise the full Attribute name will be used. | ||
```javascript | ||
attributes: { | ||
storeId: { | ||
type: "string", | ||
label: "sid", | ||
}, | ||
mallId: { | ||
type: "string", | ||
label: "mid", | ||
}, | ||
buildingId: { | ||
type: "string", | ||
label: "bid", | ||
}, | ||
unitId: { | ||
type: "string", | ||
label: "uid", | ||
} | ||
}, | ||
indexes: { | ||
@@ -267,4 +312,67 @@ locations: { | ||
} | ||
// Input | ||
{ | ||
storeId: "STOREVALUE", | ||
mallId: "MALLVALUE", | ||
buildingId: "BUILDINGVALUE", | ||
unitId: "UNITVALUE" | ||
}; | ||
// Output: | ||
{ | ||
pk: '$mallstoredirectory_1#sid_storevalue', | ||
sk: '$mallstores#mid_mallvalue#bid_buildingvalue#uid_unitvalue' | ||
} | ||
``` | ||
### Facet Templates | ||
In a Facet Template, you provide a formatted template for ElectroDB to use when making keys. | ||
The syntax to a Facet Template is simple using the following rules: | ||
1. Only alphanumeric, underscore, colons, and hash symbols are valid. the following regex is used to determine validity: `/^[A-Z1-9:#_]+$/gi` | ||
2. Attributes are identified by a prefixed colon and the attributes name. For example, the syntax `:storeId` will matches `storeId` attribute in the `model` | ||
3. Convention for a composing a key use the `#` symbol to separate attributes, and for labels to attach with underscore. For example, when composing both the `mallId` and `buildingId` would be expressed as `mid_:mallId#bid_:buildingId`. | ||
```javascript | ||
attributes: { | ||
storeId: { | ||
type: "string" | ||
}, | ||
mallId: { | ||
type: "string" | ||
}, | ||
buildingId: { | ||
type: "string" | ||
}, | ||
unitId: { | ||
type: "string" | ||
} | ||
}, | ||
indexes: { | ||
locations: { | ||
pk: { | ||
field: "pk", | ||
facets: "sid_:storeId" | ||
}, | ||
sk: { | ||
field: "sk", | ||
facets: "mid_:mallId#bid_:buildingId#uid_:unitId"] | ||
} | ||
} | ||
} | ||
// Input | ||
{ | ||
storeId: "STOREVALUE", | ||
mallId: "MALLVALUE", | ||
buildingId: "BUILDINGVALUE", | ||
unitId: "UNITVALUE" | ||
}; | ||
// Output: | ||
{ | ||
pk: '$mallstoredirectory_1#sid_storevalue', | ||
sk: '$mallstores#mid_mallvalue#bid_buildingvalue#uid_unitvalue' | ||
} | ||
``` | ||
## Filters | ||
@@ -271,0 +379,0 @@ Building thoughtful indexes can make queries simple and performant. Sometimes you need to filter results down further. By adding Filters to your model, you can extend your queries with custom filters. Below is the traditional way you would add a filter to Dynamo's DocumentClient directly along side how you would accomplish the same using a Filter function. |
@@ -1065,2 +1065,38 @@ "use strict"; | ||
_parseComposedKey(key = "") { | ||
if (!key.match(/^[A-Z1-9:#_]+$/gi)) { | ||
throw new Error(`Invalid key facet template. Allowed characters include only "A-Z", "a-z", "1-9", ":", "_", "#". Received: ${key}`); | ||
} | ||
let facets = {}; | ||
let names = key.match(/:[A-Z1-9]+/gi); | ||
if (!names) { | ||
throw new Error(`Invalid key facet template. No facets provided, expected at least one facet with the format ":attributeName". Received: ${key}`) | ||
} | ||
let labels = key.split(/:[A-Z1-9]+/gi); | ||
for (let i = 0; i < names.length; i++) { | ||
let name = names[i].replace(":", ""); | ||
let label = labels[i]; | ||
if (name !== "") { | ||
facets[name] = label.replace(/#|_/gi, ""); | ||
} | ||
} | ||
return facets; | ||
} | ||
_parseFacets(facets) { | ||
if (Array.isArray(facets)) { | ||
return { | ||
facetLabels: {}, | ||
facetArray: facets, | ||
} | ||
} else { | ||
let facetLabels = this._parseComposedKey(facets); | ||
return { | ||
facetLabels, | ||
facetArray: Object.keys(facetLabels), | ||
} | ||
} | ||
} | ||
_normalizeIndexes(indexes = {}) { | ||
@@ -1083,2 +1119,3 @@ let normalized = {}; | ||
attributes: [], | ||
labels: {}, | ||
}; | ||
@@ -1094,8 +1131,11 @@ | ||
indexHasSortKeys[indexName] = hasSk; | ||
let {facetArray, facetLabels} = this._parseFacets(index.pk.facets); | ||
facets.labels = Object.assign({}, facets.labels, facetLabels); | ||
let pk = { | ||
accessPattern, | ||
facetLabels, | ||
index: indexName, | ||
type: KeyTypes.pk, | ||
field: index.pk.field || "", | ||
facets: [...index.pk.facets], | ||
facets: [...facetArray], | ||
}; | ||
@@ -1105,3 +1145,6 @@ let sk = {}; | ||
if (hasSk) { | ||
let {facetArray, facetLabels} = this._parseFacets(index.sk.facets); | ||
facets.labels = Object.assign({}, facets.labels, facetLabels); | ||
sk = { | ||
facetLabels, | ||
accessPattern, | ||
@@ -1111,3 +1154,3 @@ index: indexName, | ||
field: index.sk.field || "", | ||
facets: [...index.sk.facets], | ||
facets: [...facetArray], | ||
}; | ||
@@ -1174,2 +1217,19 @@ facets.fields.push(sk.field); | ||
_normalizeFilters(filters = {}) { | ||
let normalized = {}; | ||
let invalidFilterNames = ["go", "params", "filter"]; | ||
for (let [name, fn] of Object.entries(filters)) { | ||
if (invalidFilterNames.includes(name)) { | ||
throw new Error( | ||
`Invalid filter name. Filter cannot be named "go", "params", or "filter"`, | ||
); | ||
} else { | ||
normalized[name] = fn; | ||
} | ||
} | ||
return normalized; | ||
} | ||
_parseModel(model = {}) { | ||
@@ -1186,3 +1246,3 @@ let { service, entity, table, version = "1" } = model; | ||
let schema = new Schema(model.attributes, facets); | ||
let filters = model.filters || {}; | ||
let filters = this._normalizeFilters(model.filters); | ||
return { | ||
@@ -1189,0 +1249,0 @@ service, |
@@ -218,2 +218,3 @@ const { KeyTypes } = require("./types"); | ||
name, | ||
label: facets.labels[name] || attribute.label, | ||
required: !!attribute.required, | ||
@@ -246,5 +247,11 @@ field: attribute.field || name, | ||
} | ||
let missingFacetAttributes = facets.attributes.filter(({name}) => { | ||
return !normalized[name] | ||
}).map(facet => `"${facet.type}: ${facet.name}"`); | ||
if (missingFacetAttributes.length) { | ||
throw new Error(`Invalid key facet template. The following facet attributes were described in the key facet template but were not included model's attributes: ${missingFacetAttributes.join(", ")}`); | ||
} | ||
if (invalidProperties.length) { | ||
let message = invalidProperties.map( | ||
prop => | ||
prop => | ||
`Schema Validation Error: Attribute "${prop.name}" property "${prop.property}". Received: "${prop.value}", Expected: "${prop.expected}"`, | ||
@@ -251,0 +258,0 @@ ); |
@@ -72,3 +72,3 @@ const Validator = require("jsonschema").Validator; | ||
facets: { | ||
type: "array", | ||
type: ["array", "string"], | ||
minItems: 1, | ||
@@ -91,3 +91,3 @@ items: { | ||
facets: { | ||
type: "array", | ||
type: ["array", "string"], | ||
minItems: 1, | ||
@@ -167,10 +167,11 @@ required: true, | ||
let message = `${err.property}`; | ||
if (err.argument === "isFunction") { | ||
return `${message} must be a function`; | ||
} else if (err.argument === "isFunctionOrString") { | ||
return `${message} must be either a function or string`; | ||
} else if (err.argument === "isFunctionOrRegexp") { | ||
return `${message} must be either a function or Regexp`; | ||
} else { | ||
return `${message} ${err.message}`; | ||
switch (err.argument) { | ||
case "isFunction": | ||
return `${message} must be a function`; | ||
case "isFunctionOrString": | ||
return `${message} must be either a function or string`; | ||
case "isFunctionOrRegexp": | ||
return `${message} must be either a function or Regexp`; | ||
default: | ||
return `${message} ${err.message}`; | ||
} | ||
@@ -177,0 +178,0 @@ }) |
@@ -276,2 +276,159 @@ const { Entity } = require("../src/entity"); | ||
}); | ||
describe("Getters/Setters", async () => { | ||
let db = new Entity( | ||
{ | ||
service: "testing", | ||
entity: "tester", | ||
table: "electro", | ||
version: "1", | ||
attributes: { | ||
id: { | ||
type: "string", | ||
default: () => uuidv4(), | ||
}, | ||
date: { | ||
type: "string", | ||
default: () => moment.utc().format(), | ||
}, | ||
prop1: { | ||
type: "string", | ||
field: "prop1Field", | ||
set: (prop1, { id }) => { | ||
if (id) { | ||
return `${prop1} SET ${id}`; | ||
} else { | ||
return `${prop1} SET`; | ||
} | ||
}, | ||
get: prop1 => `${prop1} GET`, | ||
}, | ||
prop2: { | ||
type: "string", | ||
field: "prop2Field", | ||
get: (prop2, { id }) => `${prop2} GET ${id}`, | ||
}, | ||
}, | ||
indexes: { | ||
record: { | ||
pk: { | ||
field: "pk", | ||
facets: ["date"], | ||
}, | ||
sk: { | ||
field: "sk", | ||
facets: ["id"], | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ client }, | ||
); | ||
it("Should show getter/setter values on put", async () => { | ||
let date = moment.utc().format(); | ||
let id = uuidv4(); | ||
let prop1 = "aaa"; | ||
let prop2 = "bbb"; | ||
let record = await db.put({ date, id, prop1, prop2 }).go(); | ||
expect(record).to.deep.equal({ | ||
id, | ||
date, | ||
prop1: `${prop1} SET ${id} GET`, | ||
prop2: `${prop2} GET ${id}`, | ||
}); | ||
let fetchedRecord = await db.get({ date, id }).go(); | ||
expect(fetchedRecord).to.deep.equal({ | ||
id, | ||
date, | ||
prop1: `${prop1} SET ${id} GET`, | ||
prop2: `${prop2} GET ${id}`, | ||
}); | ||
let updatedProp1 = "ZZZ"; | ||
let updatedRecord = await db | ||
.update({ date, id }) | ||
.set({ prop1: updatedProp1 }) | ||
.go(); | ||
expect(updatedRecord).to.deep.equal({}); | ||
let getUpdatedRecord = await db.get({ date, id }).go(); | ||
expect(getUpdatedRecord).to.deep.equal({ | ||
id, | ||
date, | ||
prop1: "ZZZ SET GET", | ||
prop2: "bbb GET " + id, | ||
}); | ||
}); | ||
}); | ||
describe("Query Options", async () => { | ||
let db = new Entity( | ||
{ | ||
service: "testing", | ||
entity: "tester", | ||
table: "electro", | ||
version: "1", | ||
attributes: { | ||
id: { | ||
type: "string", | ||
}, | ||
date: { | ||
type: "string", | ||
}, | ||
someValue: { | ||
type: "string", | ||
required: true, | ||
set: val => val + " wham", | ||
get: val => val + " bam", | ||
}, | ||
}, | ||
indexes: { | ||
record: { | ||
pk: { | ||
field: "pk", | ||
facets: ["date"], | ||
}, | ||
sk: { | ||
field: "sk", | ||
facets: ["id"], | ||
}, | ||
}, | ||
}, | ||
}, | ||
{ client }, | ||
); | ||
it("Should return the originally returned results", async () => { | ||
let id = uuidv4(); | ||
let date = moment.utc().format(); | ||
let someValue = "ABDEF"; | ||
let putRecord = await db.put({ id, date, someValue }).go({ raw: true }); | ||
expect(putRecord).to.deep.equal({}); | ||
let getRecord = await db.get({ id, date }).go({ raw: true }); | ||
expect(getRecord).to.deep.equal({ | ||
Item: { | ||
id, | ||
date, | ||
someValue: someValue + " wham", | ||
sk: `$tester#id_${id}`.toLowerCase(), | ||
pk: `$testing_1#date_${date}`.toLowerCase(), | ||
}, | ||
}); | ||
let updateRecord = await db | ||
.update({ id, date }) | ||
.set({ someValue }) | ||
.go({ raw: true }); | ||
expect(updateRecord).to.deep.equal({}); | ||
let queryRecord = await db.query.record({ id, date }).go({ raw: true }); | ||
expect(queryRecord).to.deep.equal({ | ||
Items: [ | ||
{ | ||
id, | ||
date, | ||
someValue: someValue + " wham", | ||
sk: `$tester#id_${id}`.toLowerCase(), | ||
pk: `$testing_1#date_${date}`.toLowerCase(), | ||
}, | ||
], | ||
Count: 1, | ||
ScannedCount: 1, | ||
}); | ||
}); | ||
}); | ||
describe("Filters", async () => { | ||
@@ -372,2 +529,4 @@ it("Should filter results with custom user filter", async () => { | ||
let property = "ABDEF"; | ||
let recordParams = db.put({ date, property }).params(); | ||
expect(recordParams.Item.propertyVal).to.equal(property); | ||
let record = await db.put({ date, property }).go(); | ||
@@ -378,4 +537,9 @@ let found = await db.query | ||
.go(); | ||
console.log("RECORD", record); | ||
console.log("FOUND", found); | ||
let foundParams = db.query | ||
.record({ date }) | ||
.filter(attr => attr.property.eq(property)) | ||
.params(); | ||
expect(foundParams.ExpressionAttributeNames["#property"]).to.equal( | ||
"propertyVal", | ||
); | ||
expect(found) | ||
@@ -382,0 +546,0 @@ .to.be.an("array") |
@@ -133,5 +133,22 @@ const { Entity, clauses } = require("../src/entity"); | ||
describe("Entity", () => { | ||
describe("Schema parsing", () => { | ||
describe("'client' validation", () => { | ||
let mall = "EastPointe"; | ||
let store = "LatteLarrys"; | ||
let building = "BuildingA"; | ||
let category = "food/coffee"; | ||
let unit = "B54"; | ||
let leaseEnd = "2020-01-20"; | ||
let rent = "0.00"; | ||
let MallStores = new Entity(schema); | ||
// console.log(JSON.stringify(MallStores.schema)); | ||
expect(() => | ||
MallStores.put({ | ||
store, | ||
mall, | ||
building, | ||
rent, | ||
category, | ||
leaseEnd, | ||
unit, | ||
}).go(), | ||
).to.throw("No client defined on model"); | ||
}); | ||
@@ -588,2 +605,222 @@ describe("Schema validation", () => { | ||
}); | ||
it("Should allow facets to be a facet template (string)", () => { | ||
const schema = { | ||
service: "MallStoreDirectory", | ||
entity: "MallStores", | ||
table: "StoreDirectory", | ||
version: "1", | ||
attributes: { | ||
id: { | ||
type: "string", | ||
field: "storeLocationId", | ||
}, | ||
date: { | ||
type: "string", | ||
field: "dateTime" | ||
}, | ||
prop1: { | ||
type: "string", | ||
}, | ||
prop2: { | ||
type: "string", | ||
} | ||
}, | ||
indexes: { | ||
record: { | ||
pk: { | ||
field: "pk", | ||
facets: `id_:id#p1_:prop1` | ||
}, | ||
sk: { | ||
field: "sk", | ||
facets: `d_:date#p2_:prop2` | ||
} | ||
} | ||
} | ||
} | ||
let mallStore = new Entity(schema); | ||
let putParams = mallStore.put({ | ||
id: "IDENTIFIER", | ||
date: "DATE", | ||
prop1: "PROPERTY1", | ||
prop2: "PROPERTY2" | ||
}).params(); | ||
expect(putParams).to.deep.equal({ | ||
Item: { | ||
storeLocationId: 'IDENTIFIER', | ||
dateTime: 'DATE', | ||
prop1: 'PROPERTY1', | ||
prop2: 'PROPERTY2', | ||
pk: '$mallstoredirectory_1#id_identifier#p1_property1', | ||
sk: '$mallstores#d_date#p2_property2' | ||
}, | ||
TableName: 'StoreDirectory' | ||
}); | ||
}); | ||
it("Should throw on invalid characters in facet template (string)", () => { | ||
const schema = { | ||
service: "MallStoreDirectory", | ||
entity: "MallStores", | ||
table: "StoreDirectory", | ||
version: "1", | ||
attributes: { | ||
id: { | ||
type: "string", | ||
field: "storeLocationId", | ||
}, | ||
date: { | ||
type: "string", | ||
field: "dateTime" | ||
}, | ||
prop1: { | ||
type: "string", | ||
}, | ||
prop2: { | ||
type: "string", | ||
} | ||
}, | ||
indexes: { | ||
record: { | ||
pk: { | ||
field: "pk", | ||
facets: `id_:id#p1_:prop1` | ||
}, | ||
sk: { | ||
field: "sk", | ||
facets: `d_:date|p2_:prop2` | ||
} | ||
} | ||
} | ||
} | ||
expect(() => new Entity(schema)).to.throw(`Invalid key facet template. Allowed characters include only "A-Z", "a-z", "1-9", ":", "_", "#". Received: d_:date|p2_:prop2`); | ||
}); | ||
it("Should default labels to facet attribute names in facet template (string)", () => { | ||
const schema = { | ||
service: "MallStoreDirectory", | ||
entity: "MallStores", | ||
table: "StoreDirectory", | ||
version: "1", | ||
attributes: { | ||
id: { | ||
type: "string", | ||
field: "storeLocationId", | ||
}, | ||
date: { | ||
type: "string", | ||
field: "dateTime" | ||
}, | ||
prop1: { | ||
type: "string", | ||
}, | ||
prop2: { | ||
type: "string", | ||
} | ||
}, | ||
indexes: { | ||
record: { | ||
pk: { | ||
field: "pk", | ||
facets: `id_:id#:prop1` | ||
}, | ||
sk: { | ||
field: "sk", | ||
facets: `:date#p2_:prop2` | ||
} | ||
} | ||
} | ||
} | ||
let mallStore = new Entity(schema); | ||
let putParams = mallStore.put({ | ||
id: "IDENTIFIER", | ||
date: "DATE", | ||
prop1: "PROPERTY1", | ||
prop2: "PROPERTY2" | ||
}).params(); | ||
expect(putParams).to.deep.equal({ | ||
Item: { | ||
storeLocationId: 'IDENTIFIER', | ||
dateTime: 'DATE', | ||
prop1: 'PROPERTY1', | ||
prop2: 'PROPERTY2', | ||
pk: '$mallstoredirectory_1#id_identifier#prop1_property1', | ||
sk: '$mallstores#date_date#p2_property2' | ||
}, | ||
TableName: 'StoreDirectory' | ||
}) | ||
}); | ||
it("Should throw on invalid characters in facet template (string)", () => { | ||
const schema = { | ||
service: "MallStoreDirectory", | ||
entity: "MallStores", | ||
table: "StoreDirectory", | ||
version: "1", | ||
attributes: { | ||
id: { | ||
type: "string", | ||
field: "storeLocationId", | ||
}, | ||
date: { | ||
type: "string", | ||
field: "dateTime" | ||
}, | ||
prop1: { | ||
type: "string", | ||
}, | ||
prop2: { | ||
type: "string", | ||
} | ||
}, | ||
indexes: { | ||
record: { | ||
pk: { | ||
field: "pk", | ||
facets: `id_:id#p1_:prop1` | ||
}, | ||
sk: { | ||
field: "sk", | ||
facets: `dbsfhdfhsdshfshf` | ||
} | ||
} | ||
} | ||
} | ||
expect(() => new Entity(schema)).to.throw(`Invalid key facet template. No facets provided, expected at least one facet with the format ":attributeName". Received: dbsfhdfhsdshfshf`); | ||
}); | ||
it("Should throw when defined facets are not in attributes: facet template and facet array", () => { | ||
const schema = { | ||
service: "MallStoreDirectory", | ||
entity: "MallStores", | ||
table: "StoreDirectory", | ||
version: "1", | ||
attributes: { | ||
id: { | ||
type: "string", | ||
field: "storeLocationId", | ||
}, | ||
date: { | ||
type: "string", | ||
field: "dateTime" | ||
}, | ||
prop1: { | ||
type: "string", | ||
}, | ||
prop2: { | ||
type: "string", | ||
} | ||
}, | ||
indexes: { | ||
record: { | ||
pk: { | ||
field: "pk", | ||
facets: ["id", "prop5"] | ||
}, | ||
sk: { | ||
field: "sk", | ||
facets: `:date#p3_:prop3#p4_:prop4` | ||
} | ||
} | ||
} | ||
} | ||
expect(() => new Entity(schema)).to.throw(`Invalid key facet template. The following facet attributes were described in the key facet template but were not included model's attributes: "pk: prop5", "sk: prop3", "sk: prop4"`); | ||
}); | ||
}); | ||
@@ -590,0 +827,0 @@ |
@@ -182,3 +182,39 @@ const moment = require("moment"); | ||
}); | ||
it("Should not allow filters named 'go', 'params', or 'filter'", () => { | ||
let schema = { | ||
service: "MallStoreDirectory", | ||
entity: "MallStores", | ||
table: "StoreDirectory", | ||
version: "1", | ||
attributes: { | ||
id: { | ||
type: "string", | ||
default: () => uuidV4(), | ||
facets: "storeLocationId", | ||
}, | ||
}, | ||
indexes: { | ||
record: { | ||
pk: { | ||
field: "pk", | ||
facets: ["id"], | ||
}, | ||
}, | ||
}, | ||
filters: {}, | ||
}; | ||
schema.filters = { go: () => "" }; | ||
expect(() => new Entity(schema)).to.throw( | ||
`Invalid filter name. Filter cannot be named "go", "params", or "filter"`, | ||
); | ||
schema.filters = { params: () => "" }; | ||
expect(() => new Entity(schema)).to.throw( | ||
`Invalid filter name. Filter cannot be named "go", "params", or "filter"`, | ||
); | ||
schema.filters = { filter: () => "" }; | ||
expect(() => new Entity(schema)).to.throw( | ||
`Invalid filter name. Filter cannot be named "go", "params", or "filter"`, | ||
); | ||
}); | ||
}); | ||
}); |
@@ -6,6 +6,3 @@ tests: | ||
entity | ||
- test for connected delete test w/ sortKey | ||
- test for each option | ||
- raw | ||
- original error | ||
@@ -19,8 +16,4 @@ - includeKeys | ||
- test for bad "isValid" attribute result | ||
features: | ||
- if no client passed, no calling "go" method | ||
- find method | ||
- scan method | ||
- go, params, filter as invalid filter names | ||
- scan method |
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
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
214913
3843
1020