electrodb
Advanced tools
Comparing version 0.8.5 to 0.8.6
@@ -1,3 +0,3 @@ | ||
const {Entity} = require("./src/electro"); | ||
const { Entity } = require("./src/entity"); | ||
module.exports = {Entity}; | ||
module.exports = { Entity }; |
{ | ||
"name": "electrodb", | ||
"version": "0.8.5", | ||
"version": "0.8.6", | ||
"description": "A library to more easily create and interact with multiple entities and heretical relationships in dynamodb", | ||
@@ -22,2 +22,4 @@ "main": "index.js", | ||
"chai": "^4.2.0", | ||
"mocha": "7.1.1", | ||
"moment": "^2.24.0", | ||
"nyc": "^15.0.0", | ||
@@ -24,0 +26,0 @@ "uuid": "^7.0.1" |
@@ -1,420 +0,332 @@ | ||
const {Entity} = require("../src/electro"); | ||
const { Entity } = require("../src/entity"); | ||
const { expect } = require("chai"); | ||
const uuidv4 = require("uuid").v4; | ||
const moment = require("moment"); | ||
const DynamoDB = require("aws-sdk/clients/dynamodb"); | ||
const DocumentClient = new DynamoDB.DocumentClient({ | ||
const client = new DynamoDB.DocumentClient({ | ||
region: "us-east-1", | ||
}); | ||
function makeContact({ email, user, contact } = {}) { | ||
let emailAddress = email || uuidv4(); | ||
let userId = user || uuidv4(); | ||
let contactId = contact || uuidv4(); | ||
let data = { | ||
emailAddress, | ||
contactId, | ||
userId, | ||
name: "blah", | ||
description: "blah", | ||
category: "blah", | ||
type: "message", | ||
priority: "low", | ||
contactFrequency: 50, | ||
hasChildren: true, | ||
isFreeWeekdays: true, | ||
isFreeWeekEnds: true, | ||
note: "blah", | ||
requiresReminding: true, | ||
}; | ||
return { | ||
emailAddress, | ||
contactId, | ||
userId, | ||
data, | ||
}; | ||
} | ||
let schema = { | ||
service: "tinkertamper", | ||
entity: "emailcontact", | ||
let model = { | ||
service: "MallStoreDirectory", | ||
entity: "MallStores", | ||
table: "electro", | ||
version: "1", | ||
attributes: { | ||
emailAddress: { | ||
id: { | ||
type: "string", | ||
required: true, | ||
default: () => uuidv4(), | ||
field: "storeLocationId", | ||
}, | ||
contactId: { | ||
sector: { | ||
type: "string", | ||
required: true, | ||
}, | ||
userId: { | ||
mall: { | ||
type: "string", | ||
required: true, | ||
field: "mallId", | ||
}, | ||
name: { | ||
store: { | ||
type: "string", | ||
required: true, | ||
field: "storeId", | ||
}, | ||
description: { | ||
building: { | ||
type: "string", | ||
required: true, | ||
field: "buildingId", | ||
}, | ||
category: { | ||
unit: { | ||
type: "string", | ||
required: true, | ||
field: "unitId", | ||
}, | ||
type: { | ||
type: ["message", "alert"], | ||
category: { | ||
type: [ | ||
"food/coffee", | ||
"food/meal", | ||
"clothing", | ||
"electronics", | ||
"department", | ||
"misc", | ||
], | ||
required: true, | ||
}, | ||
priority: { | ||
type: ["high", "medium", "low"], | ||
required: true, | ||
}, | ||
contactFrequency: { | ||
type: "number", | ||
required: true, | ||
}, | ||
hasChildren: { | ||
type: "boolean", | ||
required: true, | ||
}, | ||
isFreeWeekdays: { | ||
type: "boolean", | ||
required: true, | ||
}, | ||
isFreeWeekEnds: { | ||
type: "boolean", | ||
required: true, | ||
}, | ||
note: { | ||
leaseEnd: { | ||
type: "string", | ||
required: true, | ||
validate: date => | ||
moment(date, "YYYY-MM-DD").isValid() ? "" : "Invalid date format", | ||
}, | ||
requiresReminding: { | ||
type: "boolean", | ||
required: true, | ||
attr: "remind", | ||
}, | ||
notRequired: { | ||
rent: { | ||
type: "string", | ||
required: false, | ||
default: "0.00", | ||
}, | ||
notRequiredButMapsToDifferentAttr: { | ||
adjustments: { | ||
type: "string", | ||
attr: "nrbmtda", | ||
required: false, | ||
}, | ||
notRequiredButDefaults: { | ||
default: () => "DEFAULT_VALUE", | ||
}, | ||
}, | ||
indexes: { | ||
contactEmail: { | ||
store: { | ||
pk: { | ||
attr: "pk", | ||
compose: "email_:emailAddress", | ||
field: "pk", | ||
facets: ["sector"], | ||
}, | ||
sk: { | ||
attr: "sk", | ||
compose: "user:userId#cid_:contactId", | ||
field: "sk", | ||
facets: ["id"], | ||
}, | ||
}, | ||
sharedContact: { | ||
units: { | ||
index: "gsi1pk-gsi1sk-index", | ||
pk: { | ||
attr: "gsi1pk", | ||
compose: "cid_:contactId", | ||
field: "gsi1pk", | ||
facets: ["mall"], | ||
}, | ||
sk: { | ||
attr: "gsi1sk", | ||
compose: "user:userId#email_:emailAddress", | ||
field: "gsi1sk", | ||
facets: ["building", "unit", "store"], | ||
}, | ||
}, | ||
userContact: { | ||
leases: { | ||
index: "gsi2pk-gsi2sk-index", | ||
pk: { | ||
attr: "gsi2pk", | ||
compose: "user:userId", | ||
field: "gsi2pk", | ||
facets: ["mall"], | ||
}, | ||
sk: { | ||
attr: "gsi2sk", | ||
compose: "cid_:contactId#email_:emailAddress", | ||
field: "gsi2sk", | ||
facets: ["leaseEnd", "store", "building", "unit"], | ||
}, | ||
}, | ||
categories: { | ||
index: "gsi3pk-gsi3sk-index", | ||
pk: { | ||
field: "gsi3pk", | ||
facets: ["mall"], | ||
}, | ||
sk: { | ||
field: "gsi3sk", | ||
facets: ["category", "building", "unit", "store"], | ||
}, | ||
}, | ||
shops: { | ||
index: "gsi4pk-gsi4sk-index", | ||
pk: { | ||
field: "gsi4pk", | ||
facets: ["store"], | ||
}, | ||
sk: { | ||
field: "gsi4sk", | ||
facets: ["mall", "building", "unit"], | ||
}, | ||
}, | ||
}, | ||
filters: { | ||
maxRent({ rent }, max) { | ||
return rent.lte(max); | ||
}, | ||
}, | ||
}; | ||
describe("database interactions", async () => { | ||
it("Should create a new record", async () => { | ||
let electro = new Entity(schema, DocumentClient); | ||
let emailAddress = "friend@email.com"; | ||
let userId = "9999"; | ||
let contactId = "0001"; | ||
let data = { | ||
emailAddress, | ||
contactId, | ||
userId, | ||
name: "blah", | ||
description: "blah", | ||
category: "blah", | ||
type: "message", | ||
priority: "high", | ||
contactFrequency: 50, | ||
hasChildren: true, | ||
isFreeWeekdays: true, | ||
isFreeWeekEnds: true, | ||
note: "blah", | ||
requiresReminding: true, | ||
}; | ||
let results = await electro | ||
.contactEmail(emailAddress) | ||
.put(userId, contactId) | ||
.data(data) | ||
.go(); | ||
expect(results).to.be.deep.equal({ | ||
emailAddress: "friend@email.com", | ||
contactId: "0001", | ||
userId: "9999", | ||
name: "blah", | ||
description: "blah", | ||
category: "blah", | ||
type: "message", | ||
priority: "high", | ||
contactFrequency: 50, | ||
hasChildren: true, | ||
isFreeWeekdays: true, | ||
isFreeWeekEnds: true, | ||
note: "blah", | ||
requiresReminding: true, | ||
notRequiredButDefaults: "DEFAULT_VALUE", | ||
}); | ||
}).timeout(10000); | ||
it("Should perform an entire record crud lifecycle", async () => { | ||
let electro = new Entity(schema, DocumentClient); | ||
let contact1 = makeContact(); | ||
describe("Entity", async () => { | ||
let MallStores = new Entity(model, { client }); | ||
describe("Simple crud", async () => { | ||
let mall = "EastPointe"; | ||
let store = "LatteLarrys"; | ||
let sector = "A1"; | ||
let category = "food/coffee"; | ||
let leaseEnd = "2020-01-20"; | ||
let rent = "0.00"; | ||
let letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||
let building = "BuildingZ"; | ||
let unit = "G1"; | ||
it("Should return the created item", async () => { | ||
let putOne = await MallStores.put({ | ||
sector, | ||
store, | ||
mall, | ||
rent, | ||
category, | ||
leaseEnd, | ||
unit, | ||
building, | ||
}).go(); | ||
expect(putOne).to.deep.equal({ | ||
id: putOne.id, | ||
sector, | ||
mall, | ||
store, | ||
building, | ||
unit, | ||
category, | ||
leaseEnd, | ||
rent, | ||
}); | ||
}).timeout(20000); | ||
it("Should not collide with other keys", async () => { | ||
let sector = uuidv4(); | ||
let malls = [uuidv4(), uuidv4()]; | ||
let storeNames = [ | ||
"ABC", | ||
"DEF", | ||
"GHI", | ||
"JKL", | ||
"MNO", | ||
"PQR", | ||
"STU", | ||
"WXY", | ||
"ZYX", | ||
"WUT", | ||
]; | ||
let stores = []; | ||
for (let i = 0; i < storeNames.length; i++) { | ||
let mall = malls[i % 2]; | ||
stores.push( | ||
MallStores.put({ | ||
sector, | ||
mall, | ||
rent, | ||
category, | ||
leaseEnd, | ||
store: storeNames[i], | ||
unit: `B${i + 1}`, | ||
building: `Building${letters[i]}`, | ||
}).go(), | ||
); | ||
} | ||
stores = await Promise.all(stores); | ||
expect(stores) | ||
.to.be.an("array") | ||
.and.have.length(10); | ||
await electro | ||
.contactEmail(contact1.emailAddress) | ||
.put(contact1.userId, contact1.contactId) | ||
.data(contact1.data) | ||
.go(); | ||
let mallOne = malls[0]; | ||
let mallOneIds = stores | ||
.filter(store => store.mall === mallOne) | ||
.map(store => store.id); | ||
await electro | ||
.userContact(contact1.userId) | ||
.update(contact1.contactId, contact1.emailAddress) | ||
.set({ | ||
requiresReminding: false, | ||
hasChildren: false, | ||
priority: "high", | ||
}) | ||
.go(); | ||
let mallOneStores = await MallStores.query | ||
.units({ | ||
mall: mallOne, | ||
}) | ||
.go(); | ||
let getResults = await electro | ||
.sharedContact(contact1.contactId) | ||
.get(contact1.userId, contact1.emailAddress) | ||
.go(); | ||
let mallOneMatches = mallOneStores.every(store => | ||
mallOneIds.includes(store.id), | ||
); | ||
expect(getResults).to.be.deep.equal({ | ||
userId: contact1.userId, | ||
contactId: contact1.contactId, | ||
emailAddress: contact1.emailAddress, | ||
hasChildren: false, | ||
priority: "high", | ||
name: "blah", | ||
isFreeWeekEnds: true, | ||
note: "blah", | ||
contactFrequency: 50, | ||
requiresReminding: false, | ||
category: "blah", | ||
isFreeWeekdays: true, | ||
notRequiredButDefaults: "DEFAULT_VALUE", | ||
description: "blah", | ||
type: "message", | ||
}); | ||
expect(mallOneMatches); | ||
expect(mallOneStores) | ||
.to.be.an("array") | ||
.and.have.length(5); | ||
let deleteResults = await electro | ||
.sharedContact(contact1.contactId) | ||
.delete(contact1.userId, contact1.emailAddress) | ||
.go(); | ||
expect(deleteResults).to.be.an("object").that.is.empty; | ||
let first = stores[0]; | ||
let firstStore = await MallStores.get({ | ||
sector, | ||
id: first.id, | ||
}).go(); | ||
expect(firstStore).to.be.deep.equal(first); | ||
let noResults = await electro | ||
.sharedContact(contact1.contactId) | ||
.get(contact1.userId, contact1.emailAddress) | ||
.go(); | ||
let buildingsAfterB = await MallStores.query | ||
.categories({ category, mall: mallOne }) | ||
.gt({ building: "BuildingB" }) | ||
.go(); | ||
let buildingsAfterBStores = stores.filter(store => { | ||
return ( | ||
store.mall === mallOne && | ||
store.building !== "BuildingA" && | ||
store.building !== "BuildingB" | ||
); | ||
}); | ||
expect(buildingsAfterB).to.deep.equal(buildingsAfterBStores); | ||
expect(noResults).to.be.an("object").that.is.empty; | ||
// console.log("NO RESULTS", noResults); | ||
}).timeout(20000); | ||
let buildingsBetweenBH = await MallStores.query | ||
.categories({ category, mall: mallOne }) | ||
.between({ building: "BuildingB" }, { building: "BuildingH" }) | ||
.go(); | ||
it("Should perform an entire record crud lifecycle", async () => { | ||
let electro = new Entity(schema, DocumentClient); | ||
let user = uuidv4(); | ||
let contact1 = makeContact({ user }); | ||
let contact2 = makeContact({ user }); | ||
let contact3 = makeContact(); | ||
await Promise.all([ | ||
electro | ||
.contactEmail(contact1.emailAddress) | ||
.put(contact1.userId, contact1.contactId) | ||
.data(contact1.data) | ||
.go(), | ||
electro | ||
.contactEmail(contact2.emailAddress) | ||
.put(contact2.userId, contact2.contactId) | ||
.data(contact2.data) | ||
.go(), | ||
electro | ||
.contactEmail(contact3.emailAddress) | ||
.put(contact3.userId, contact3.contactId) | ||
.data(contact3.data) | ||
.go(), | ||
]); | ||
let userContacts = await electro | ||
.userContact(user) | ||
.find() | ||
.go(); | ||
expect(userContacts) | ||
.to.be.an("array") | ||
.and.to.have.lengthOf(2) | ||
.and.to.deep.include({ | ||
hasChildren: true, | ||
priority: "low", | ||
name: "blah", | ||
isFreeWeekEnds: true, | ||
note: "blah", | ||
contactId: contact1.contactId, | ||
contactFrequency: 50, | ||
emailAddress: contact1.emailAddress, | ||
userId: contact1.userId, | ||
requiresReminding: true, | ||
category: "blah", | ||
isFreeWeekdays: true, | ||
notRequiredButDefaults: "DEFAULT_VALUE", | ||
description: "blah", | ||
type: "message", | ||
}) | ||
.and.to.deep.include({ | ||
hasChildren: true, | ||
priority: "low", | ||
name: "blah", | ||
isFreeWeekEnds: true, | ||
note: "blah", | ||
contactId: contact2.contactId, | ||
contactFrequency: 50, | ||
emailAddress: contact2.emailAddress, | ||
userId: contact2.userId, | ||
requiresReminding: true, | ||
category: "blah", | ||
isFreeWeekdays: true, | ||
notRequiredButDefaults: "DEFAULT_VALUE", | ||
description: "blah", | ||
type: "message", | ||
let buildingsBetweenBHStores = stores.filter(store => { | ||
return ( | ||
store.mall === mallOne && | ||
store.building !== "BuildingA" && | ||
store.building !== "BuildingI" | ||
); | ||
}); | ||
}).timeout(20000); | ||
it("Should return raw dynamo results", async () => { | ||
let electro = new Entity(schema, DocumentClient); | ||
let { emailAddress, contactId, userId, data } = makeContact(); | ||
expect(buildingsBetweenBH) | ||
.to.be.an("array") | ||
.and.have.length(3) | ||
.and.to.be.deep.equal(buildingsBetweenBHStores); | ||
await electro | ||
.contactEmail(emailAddress) | ||
.put(userId, contactId) | ||
.data(data) | ||
.go(); | ||
let results = await electro | ||
.contactEmail(emailAddress) | ||
.get(userId, contactId) | ||
.go({ raw: true }); | ||
expect(results).to.deep.equal({ | ||
Item: { | ||
hasChildren: true, | ||
priority: "low", | ||
name: "blah", | ||
isFreeWeekEnds: true, | ||
note: "blah", | ||
contactId, | ||
contactFrequency: 50, | ||
emailAddress, | ||
userId, | ||
requiresReminding: true, | ||
category: "blah", | ||
isFreeWeekdays: true, | ||
notRequiredButDefaults: "DEFAULT_VALUE", | ||
description: "blah", | ||
type: "message", | ||
}, | ||
}); | ||
let secondStore = { sector, id: stores[1].id }; | ||
let secondStoreBeforeUpdate = await MallStores.get(secondStore).go(); | ||
let newRent = "5000.00"; | ||
expect(secondStoreBeforeUpdate.rent) | ||
.to.equal(rent) | ||
.and.to.not.equal(newRent); | ||
let updatedStore = await MallStores.update(secondStore) | ||
.set({ rent: newRent }) | ||
.go(); | ||
expect(updatedStore).to.deep.equal({}); | ||
let secondStoreAfterUpdate = await MallStores.get(secondStore).go(); | ||
expect(secondStoreAfterUpdate.rent).to.equal(newRent); | ||
}).timeout(20000); | ||
}); | ||
it("Should pull back records using the comparison operators", async () => { | ||
let electro = new Entity(schema, DocumentClient); | ||
let emailAddress = uuidv4(); | ||
let userId = uuidv4(); | ||
describe("Filters", async () => { | ||
it("Should filter results with custom user filter", async () => { | ||
let store = "LatteLarrys"; | ||
let category = "food/coffee"; | ||
let leaseEnd = "2020-01-20"; | ||
let building = "BuildingA"; | ||
let sector = uuidv4(); | ||
let malls = [uuidv4(), uuidv4()]; | ||
let mall = malls[0]; | ||
let rent = "0"; | ||
let storeNames = [ | ||
"ABC", | ||
"DEF", | ||
"GHI", | ||
"JKL", | ||
"MNO", | ||
"PQR", | ||
"STU", | ||
"WXY", | ||
"ZYX", | ||
"WUT", | ||
]; | ||
for (let i = 0; i < 10; i++) { | ||
let contactId = "0" + i; | ||
await electro | ||
.contactEmail(emailAddress) | ||
.put(userId, contactId) | ||
.data({ | ||
emailAddress, | ||
contactId, | ||
userId, | ||
name: "blah", | ||
description: "blah", | ||
category: "blah", | ||
type: "message", | ||
priority: "high", | ||
contactFrequency: 50, | ||
hasChildren: true, | ||
isFreeWeekdays: true, | ||
isFreeWeekEnds: true, | ||
note: "blah", | ||
requiresReminding: true, | ||
}) | ||
let stores = []; | ||
for (let i = 0; i < storeNames.length; i++) { | ||
let mall = malls[i % 2]; | ||
stores.push( | ||
MallStores.put({ | ||
mall, | ||
sector, | ||
building, | ||
category, | ||
leaseEnd, | ||
rent: i + rent, | ||
store: storeNames[i], | ||
unit: `B${i + 1}`, | ||
}).go(), | ||
); | ||
} | ||
stores = await Promise.all(stores); | ||
let max = "50"; | ||
let filteredStores = stores.filter(store => { | ||
return store.mall === mall && store.rent <= max; | ||
}); | ||
let belowMarketUnits = await MallStores.query | ||
.units({ mall, building }) | ||
.maxRent(max) | ||
.go(); | ||
} | ||
let queryGTE = electro | ||
.contactEmail(emailAddress) | ||
.query(userId) | ||
.gte("06") | ||
.go(); | ||
let queryGT = electro | ||
.contactEmail(emailAddress) | ||
.query(userId) | ||
.gt("01") | ||
.go(); | ||
let queryLTE = electro | ||
.contactEmail(emailAddress) | ||
.query(userId) | ||
.lte("04") | ||
.go(); | ||
let queryLT = electro | ||
.contactEmail(emailAddress) | ||
.query(userId) | ||
.lt("08") | ||
.go(); | ||
let [gte, gt, lte, lt] = await Promise.all([ | ||
queryGTE, | ||
queryGT, | ||
queryLTE, | ||
queryLT, | ||
]); | ||
expect(gte) | ||
.to.be.an("array") | ||
.and.to.have.lengthOf(4); | ||
expect(gt) | ||
.to.be.an("array") | ||
.and.to.have.lengthOf(8); | ||
expect(lte) | ||
.to.be.an("array") | ||
.and.to.have.lengthOf(5); | ||
expect(lt) | ||
.to.be.an("array") | ||
.and.to.have.lengthOf(8); | ||
}).timeout(10000); | ||
expect(belowMarketUnits) | ||
.to.be.an("array") | ||
.and.have.length(3) | ||
.and.deep.have.members(filteredStores); | ||
// console.log(belowMarketUnits); | ||
}).timeout(20000); | ||
}); | ||
}); |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
160605
15
3047
0
4
6
1