electrodb
Advanced tools
Comparing version 2.4.2 to 2.5.0
const { Entity } = require("./src/entity"); | ||
const { Service } = require("./src/service"); | ||
const { createGetTransaction, createWriteTransaction } = require('./src/transaction'); | ||
const { createCustomAttribute, CustomAttributeType, createSchema } = require('./src/schema'); | ||
@@ -14,2 +15,4 @@ const { ElectroError, ElectroValidationError, ElectroUserValidationError, ElectroAttributeValidationError } = require('./src/errors'); | ||
ElectroValidationError, | ||
createGetTransaction, | ||
createWriteTransaction, | ||
}; |
{ | ||
"name": "electrodb", | ||
"version": "2.4.2", | ||
"version": "2.5.0", | ||
"description": "A library to more easily create and interact with multiple entities and heretical relationships in dynamodb", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -1,2 +0,2 @@ | ||
const { QueryTypes, MethodTypes, ItemOperations, ExpressionTypes, TableIndex, TerminalOperation, KeyTypes, IndexTypes } = require("./types"); | ||
const { QueryTypes, MethodTypes, ItemOperations, ExpressionTypes, TransactionCommitSymbol, TransactionOperations, TerminalOperation, KeyTypes, IndexTypes } = require("./types"); | ||
const {AttributeOperationProxy, UpdateOperations, FilterOperationNames} = require("./operations"); | ||
@@ -31,3 +31,3 @@ const {UpdateExpression} = require("./update"); | ||
name: "index", | ||
children: ["get", "delete", "update", "query", "upsert", "put", "scan", "collection", "clusteredCollection", "create", "remove", "patch", "batchPut", "batchDelete", "batchGet"], | ||
children: ["check", "get", "delete", "update", "query", "upsert", "put", "scan", "collection", "clusteredCollection", "create", "remove", "patch", "batchPut", "batchDelete", "batchGet"], | ||
}, | ||
@@ -160,4 +160,12 @@ clusteredCollection: { | ||
}, | ||
children: ["params", "go"], | ||
children: ["params", "go", "commit"], | ||
}, | ||
check: { | ||
name: 'check', | ||
action(...params) { | ||
return clauses.get.action(...params) | ||
.setMethod(MethodTypes.check); | ||
}, | ||
children: ["commit"], | ||
}, | ||
batchGet: { | ||
@@ -195,3 +203,3 @@ name: "batchGet", | ||
}, | ||
children: ["where", "params", "go"], | ||
children: ["where", "params", "go", "commit"], | ||
}, | ||
@@ -226,3 +234,3 @@ remove: { | ||
}, | ||
children: ["where", "params", "go"], | ||
children: ["where", "params", "go", "commit"], | ||
}, | ||
@@ -252,3 +260,3 @@ upsert: { | ||
}, | ||
children: ["params", "go", "where"], | ||
children: ["params", "go", "where", "commit"], | ||
}, | ||
@@ -279,3 +287,3 @@ put: { | ||
}, | ||
children: ["params", "go"], | ||
children: ["params", "go", "commit"], | ||
}, | ||
@@ -316,3 +324,3 @@ batchPut: { | ||
}, | ||
children: ["params", "go"], | ||
children: ["params", "go", "commit"], | ||
}, | ||
@@ -346,3 +354,3 @@ patch: { | ||
}, | ||
children: ["set", "append","updateRemove", "updateDelete", "add", "subtract", "data"], | ||
children: ["set", "append","updateRemove", "updateDelete", "add", "subtract", "data", "commit"], | ||
}, | ||
@@ -370,3 +378,3 @@ update: { | ||
}, | ||
children: ["data", "set", "append", "add", "updateRemove", "updateDelete", "go", "params", "subtract"], | ||
children: ["data", "set", "append", "add", "updateRemove", "updateDelete", "go", "params", "subtract", "commit"], | ||
}, | ||
@@ -401,3 +409,3 @@ data: { | ||
}, | ||
children: ["data", "set", "append", "add", "updateRemove", "updateDelete", "go", "params", "subtract"], | ||
children: ["data", "set", "append", "add", "updateRemove", "updateDelete", "go", "params", "subtract", "commit"], | ||
}, | ||
@@ -419,3 +427,3 @@ set: { | ||
}, | ||
children: ["data", "set", "append", "add", "updateRemove", "updateDelete", "go", "params", "subtract"], | ||
children: ["data", "set", "append", "add", "updateRemove", "updateDelete", "go", "params", "subtract", "commit"], | ||
}, | ||
@@ -437,3 +445,3 @@ append: { | ||
}, | ||
children: ["data", "set", "append", "add", "updateRemove", "updateDelete", "go", "params", "subtract"], | ||
children: ["data", "set", "append", "add", "updateRemove", "updateDelete", "go", "params", "subtract", "commit"], | ||
}, | ||
@@ -458,3 +466,3 @@ updateRemove: { | ||
}, | ||
children: ["data", "set", "append", "add", "updateRemove", "updateDelete", "go", "params", "subtract"], | ||
children: ["data", "set", "append", "add", "updateRemove", "updateDelete", "go", "params", "subtract", "commit"], | ||
}, | ||
@@ -476,3 +484,3 @@ updateDelete: { | ||
}, | ||
children: ["data", "set", "append", "add", "updateRemove", "updateDelete", "go", "params", "subtract"], | ||
children: ["data", "set", "append", "add", "updateRemove", "updateDelete", "go", "params", "subtract", "commit"], | ||
}, | ||
@@ -494,3 +502,3 @@ add: { | ||
}, | ||
children: ["data", "set", "append", "add", "updateRemove", "updateDelete", "go", "params", "subtract"], | ||
children: ["data", "set", "append", "add", "updateRemove", "updateDelete", "go", "params", "subtract", "commit"], | ||
}, | ||
@@ -512,3 +520,3 @@ subtract: { | ||
}, | ||
children: ["data", "set", "append", "add", "updateRemove", "updateDelete", "go", "params", "subtract"], | ||
children: ["data", "set", "append", "add", "updateRemove", "updateDelete", "go", "params", "subtract", "commit"], | ||
}, | ||
@@ -681,2 +689,31 @@ query: { | ||
}, | ||
commit: { | ||
name: 'commit', | ||
action(entity, state, options) { | ||
if (state.getError() !== null) { | ||
throw state.error; | ||
} | ||
const results = clauses.params.action(entity, state, { | ||
...options, | ||
_returnOptions: true, | ||
_isTransaction: true, | ||
}); | ||
const method = TransactionOperations[state.query.method]; | ||
if (!method) { | ||
throw new Error('Invalid commit method'); | ||
} | ||
return { | ||
[method]: results.params, | ||
[TransactionCommitSymbol]: () => { | ||
return { | ||
entity, | ||
} | ||
}, | ||
} | ||
}, | ||
children: [], | ||
}, | ||
params: { | ||
@@ -693,3 +730,6 @@ name: "params", | ||
const method = state.getMethod(); | ||
const normalizedOptions = entity._normalizeExecutionOptions({ provided: [ state.getOptions(), state.query.options, options ] }); | ||
const normalizedOptions = entity._normalizeExecutionOptions({ | ||
provided: [ state.getOptions(), state.query.options, options ], | ||
context: { operation: options._isTransaction ? MethodTypes.transactWrite : undefined } | ||
}); | ||
state.applyWithOptions(normalizedOptions); | ||
@@ -696,0 +736,0 @@ let results; |
const lib = require('@aws-sdk/lib-dynamodb') | ||
const util = require('@aws-sdk/lib-dynamodb/dist-cjs/commands/utils') | ||
const { isFunction } = require('./validations'); | ||
const { ElectroError, ErrorCodes } = require('./errors'); | ||
const DocumentClientVersions = { | ||
@@ -10,2 +10,3 @@ v2: 'v2', | ||
}; | ||
const unmarshallOutput = util.unmarshallOutput || ((val) => val); | ||
@@ -19,2 +20,95 @@ const v3Methods = ['send']; | ||
class DocumentClientV2Wrapper { | ||
static init(client) { | ||
return new DocumentClientV2Wrapper(client, lib); | ||
} | ||
constructor(client, lib) { | ||
this.client = client; | ||
this.lib = lib; | ||
this.__v = 'v2'; | ||
} | ||
get(params) { | ||
return this.client.get(params); | ||
} | ||
put(params) { | ||
return this.client.put(params); | ||
} | ||
update(params) { | ||
return this.client.update(params); | ||
} | ||
delete(params) { | ||
return this.client.delete(params); | ||
} | ||
batchWrite(params) { | ||
return this.client.batchWrite(params); | ||
} | ||
batchGet(params) { | ||
return this.client.batchGet(params); | ||
} | ||
scan(params) { | ||
return this.client.scan(params); | ||
} | ||
query(params) { | ||
return this.client.query(params); | ||
} | ||
_transact(transactionRequest) { | ||
let cancellationReasons; | ||
transactionRequest.on('extractError', (response) => { | ||
try { | ||
cancellationReasons = JSON.parse(response.httpResponse.body.toString()).CancellationReasons; | ||
} catch (err) {} | ||
}); | ||
return { | ||
async promise() { | ||
return transactionRequest.promise() | ||
.catch((err) => { | ||
if (err) { | ||
if (Array.isArray(cancellationReasons)) { | ||
return { | ||
canceled: cancellationReasons | ||
.map(reason => { | ||
if (reason.Item) { | ||
return unmarshallOutput(reason, [{ key: "Item" }]); | ||
} | ||
return reason; | ||
}) | ||
}; | ||
} | ||
throw err; | ||
} | ||
}); | ||
} | ||
} | ||
} | ||
transactWrite(params) { | ||
const transactionRequest = this.client.transactWrite(params); | ||
return this._transact(transactionRequest); | ||
} | ||
transactGet(params) { | ||
const transactionRequest = this.client.transactGet(params); | ||
return this._transact(transactionRequest); | ||
} | ||
createSet(value, ...rest) { | ||
if (Array.isArray(value)) { | ||
return this.client.createSet(value, ...rest); | ||
} else { | ||
return this.client.createSet([value], ...rest); | ||
} | ||
} | ||
} | ||
class DocumentClientV3Wrapper { | ||
@@ -28,2 +122,3 @@ static init(client) { | ||
this.lib = lib; | ||
this.__v = 'v3'; | ||
} | ||
@@ -87,6 +182,23 @@ | ||
} | ||
transactWrite(params) { | ||
return this.promiseWrap(async () => { | ||
const command = new this.lib.TransactWriteCommand(params); | ||
return this.client.send(command); | ||
return this.client.send(command) | ||
.then((result) => { | ||
return result; | ||
}) | ||
.catch(err => { | ||
if (err.CancellationReasons) { | ||
return { | ||
canceled: err.CancellationReasons.map(reason => { | ||
if (reason.Item) { | ||
return unmarshallOutput(reason, [{ key: "Item" }]); | ||
} | ||
return reason; | ||
}) | ||
} | ||
} | ||
throw err; | ||
}); | ||
}); | ||
@@ -97,3 +209,19 @@ } | ||
const command = new this.lib.TransactGetCommand(params); | ||
return this.client.send(command); | ||
return this.client.send(command) | ||
.then((result) => { | ||
return result; | ||
}) | ||
.catch(err => { | ||
if (err.CancellationReasons) { | ||
return { | ||
canceled: err.CancellationReasons.map(reason => { | ||
if (reason.Item) { | ||
return unmarshallOutput(reason, [{ key: "Item" }]); | ||
} | ||
return reason; | ||
}) | ||
} | ||
} | ||
throw err; | ||
}); | ||
}); | ||
@@ -111,3 +239,5 @@ } | ||
function identifyClientVersion(client = {}) { | ||
if (client instanceof DocumentClientV3Wrapper) return DocumentClientVersions.electro; | ||
if (client instanceof DocumentClientV3Wrapper || client instanceof DocumentClientV2Wrapper) { | ||
return DocumentClientVersions.electro; | ||
} | ||
for (const [version, methods] of Object.entries(supportedClientVersions)) { | ||
@@ -130,2 +260,3 @@ const hasMethods = methods.every(method => { | ||
case DocumentClientVersions.v2: | ||
return DocumentClientV2Wrapper.init(client); | ||
case DocumentClientVersions.electro: | ||
@@ -146,2 +277,3 @@ return client; | ||
module.exports = { | ||
util, | ||
v2Methods, | ||
@@ -155,2 +287,3 @@ v3Methods, | ||
DocumentClientV3Wrapper, | ||
DocumentClientV2Wrapper, | ||
}; |
@@ -79,3 +79,3 @@ const e = require("./errors"); | ||
let [name, { children }] = clause; | ||
return children.includes("go"); | ||
return children.find(child => ['go', 'commit'].includes(child)); | ||
}) | ||
@@ -90,3 +90,3 @@ .map(([name]) => name); | ||
action: this.buildClause(filter), | ||
children: ["params", "go", "filter", ...modelFilters], | ||
children: ["params", "go", "commit", "filter", ...modelFilters], | ||
}; | ||
@@ -100,3 +100,3 @@ } | ||
}, | ||
children: ["params", "go", "filter", ...modelFilters], | ||
children: ["params", "go", "commit", "filter", ...modelFilters], | ||
}; | ||
@@ -103,0 +103,0 @@ for (let parent of filterParents) { |
@@ -1,8 +0,7 @@ | ||
const { Entity } = require("./entity"); | ||
const { Entity, getEntityIdentifiers, matchToEntityAlias } = require("./entity"); | ||
const { clauses } = require("./clauses"); | ||
const { KeyCasing, ServiceVersions, Pager, ElectroInstance, ElectroInstanceTypes, ModelVersions, IndexTypes } = require("./types"); | ||
const { TableIndex, TransactionMethods, KeyCasing, ServiceVersions, Pager, ElectroInstance, ElectroInstanceTypes, ModelVersions, IndexTypes } = require("./types"); | ||
const { FilterFactory } = require("./filters"); | ||
const { FilterOperations } = require("./operations"); | ||
const { WhereFactory } = require("./where"); | ||
const { getInstanceType, getModelVersion, applyBetaModelOverrides } = require("./util"); | ||
const v = require("./validations"); | ||
@@ -12,2 +11,4 @@ const c = require('./client'); | ||
const u = require("./util"); | ||
const txn = require("./transaction"); | ||
const { getInstanceType, getModelVersion, applyBetaModelOverrides } = require("./util"); | ||
@@ -72,2 +73,18 @@ const ConstructorTypes = { | ||
this.identifiers = {}; | ||
this.transaction = { | ||
get: (fn) => { | ||
return txn.createTransaction({ | ||
fn, | ||
getEntities: () => this.entities, | ||
method: TransactionMethods.transactGet, | ||
}); | ||
}, | ||
write: (fn) => { | ||
return txn.createTransaction({ | ||
fn, | ||
getEntities: () => this.entities, | ||
method: TransactionMethods.transactWrite, | ||
}); | ||
} | ||
}; | ||
this._instance = ElectroInstance.service; | ||
@@ -99,2 +116,18 @@ this._instanceType = ElectroInstanceTypes.service; | ||
this.identifiers = {}; | ||
this.transaction = { | ||
get: (fn) => { | ||
return txn.createTransaction({ | ||
fn, | ||
getEntities: () => this.entities, | ||
method: TransactionMethods.transactGet, | ||
}); | ||
}, | ||
write: (fn) => { | ||
return txn.createTransaction({ | ||
fn, | ||
getEntities: () => this.entities, | ||
method: TransactionMethods.transactWrite, | ||
}); | ||
} | ||
}; | ||
this._instance = ElectroInstance.service; | ||
@@ -276,39 +309,24 @@ this._instanceType = ElectroInstanceTypes.service; | ||
_getEntityIdentifiers(entities) { | ||
let identifiers = []; | ||
for (let alias of Object.keys(entities)) { | ||
let entity = entities[alias]; | ||
let name = entity.model.entity; | ||
let version = entity.model.version; | ||
identifiers.push({ | ||
name, | ||
alias, | ||
version, | ||
entity, | ||
nameField: entity.identifiers.entity, | ||
versionField: entity.identifiers.version | ||
}); | ||
} | ||
return identifiers; | ||
} | ||
cleanseRetrievedData(collection = "", entities, data = {}, config = {}) { | ||
cleanseRetrievedData(index = TableIndex, entities, data = {}, config = {}) { | ||
if (config.raw) { | ||
return data; | ||
} | ||
const identifiers = getEntityIdentifiers(entities); | ||
data.Items = data.Items || []; | ||
let index = this.collectionSchema[collection].index; | ||
let results = {}; | ||
let identifiers = this._getEntityIdentifiers(entities); | ||
const results = {}; | ||
for (let {alias} of identifiers) { | ||
results[alias] = []; | ||
} | ||
for (let record of data.Items) { | ||
let entityAlias; | ||
for (let {name, version, nameField, versionField, alias} of identifiers) { | ||
if (record[nameField] !== undefined && record[nameField] === name && record[versionField] !== undefined && record[versionField] === version) { | ||
entityAlias = alias; | ||
break; | ||
} | ||
for (let i = 0; i < data.Items.length; i++) { | ||
const record = data.Items[i]; | ||
if (!record) { | ||
continue; | ||
} | ||
const entityAlias = matchToEntityAlias({identifiers, record}); | ||
if (!entityAlias) { | ||
@@ -318,3 +336,3 @@ continue; | ||
// pager=false because we don't want the entity trying to parse the lastEvaluatedKey | ||
let items = this.collectionSchema[collection].entities[entityAlias].formatResponse({Item: record}, index, { | ||
let formatted = entities[entityAlias].formatResponse({Item: record}, index, { | ||
...config, | ||
@@ -324,3 +342,4 @@ pager: false, | ||
}); | ||
results[entityAlias].push(items.data); | ||
results[entityAlias].push(formatted.data); | ||
} | ||
@@ -373,3 +392,3 @@ return results; | ||
}, facets = {}) { | ||
const { entities, attributes, identifiers, indexType } = this.collectionSchema[name]; | ||
const { entities, attributes, identifiers, indexType, index } = this.collectionSchema[name]; | ||
const compositeAttributes = this.compositeAttributes[name]; | ||
@@ -391,3 +410,6 @@ const allEntities = Object.values(entities); | ||
parse: (options, data) => { | ||
return this.cleanseRetrievedData(name, entities, data, options); | ||
if (options.raw) { | ||
return data; | ||
} | ||
return this.cleanseRetrievedData(index, entities, data, options); | ||
}, | ||
@@ -746,2 +768,4 @@ formatCursor: { | ||
module.exports = { Service }; | ||
module.exports = { | ||
Service, | ||
}; |
@@ -26,2 +26,3 @@ const KeyTypes = { | ||
const MethodTypes = { | ||
check: "check", | ||
put: "put", | ||
@@ -39,4 +40,23 @@ get: "get", | ||
upsert: "upsert", | ||
transactWrite: "transactWrite", | ||
transactGet: "transactGet", | ||
}; | ||
const TransactionMethods = { | ||
transactWrite: MethodTypes.transactWrite, | ||
transactGet: MethodTypes.transactGet, | ||
} | ||
const TransactionOperations = { | ||
[MethodTypes.get]: "Get", | ||
[MethodTypes.check]: "ConditionCheck", | ||
[MethodTypes.put]: "Put", | ||
[MethodTypes.create]: "Put", | ||
[MethodTypes.upsert]: "Update", | ||
[MethodTypes.update]: "Update", | ||
[MethodTypes.patch]: "Update", | ||
[MethodTypes.remove]: "Delete", | ||
[MethodTypes.delete]: "Delete", | ||
} | ||
const MethodTypeTranslation = { | ||
@@ -55,2 +75,4 @@ put: "put", | ||
upsert: "update", | ||
transactWrite: 'transactWrite', | ||
transactGet: 'transactGet', | ||
} | ||
@@ -204,2 +226,3 @@ | ||
const AttributeProxySymbol = Symbol("attribute_proxy"); | ||
const TransactionCommitSymbol = Symbol('transaction_commit'); | ||
@@ -332,2 +355,5 @@ const BuilderTypes = { | ||
ResultOrderParam, | ||
TransactionCommitSymbol, | ||
TransactionOperations, | ||
TransactionMethods, | ||
}; |
@@ -79,2 +79,3 @@ const {MethodTypes, ExpressionTypes, BuilderTypes} = require("./types"); | ||
case MethodTypes.get: | ||
case MethodTypes.check: | ||
return ExpressionTypes.ConditionExpression | ||
@@ -112,3 +113,3 @@ default: | ||
let [name, { children }] = clause; | ||
return children.includes("go"); | ||
return children.find(child => ['go', 'commit'].includes(child)); | ||
}) | ||
@@ -123,3 +124,3 @@ .map(([name]) => name); | ||
action: this.buildClause(filter), | ||
children: ["params", "go", "where", ...modelFilters], | ||
children: ["params", "go", "commit", "where", ...modelFilters], | ||
}; | ||
@@ -133,3 +134,3 @@ } | ||
}, | ||
children: ["params", "go", "where", ...modelFilters], | ||
children: ["params", "go", "commit", "where", ...modelFilters], | ||
}; | ||
@@ -136,0 +137,0 @@ for (let parent of filterParents) { |
Sorry, the diff of this file is too big to display
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
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
429082
10930