Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

electrodb

Package Overview
Dependencies
Maintainers
1
Versions
163
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

electrodb - npm Package Compare versions

Comparing version 0.9.52 to 0.10.0

index.d.ts

24

package.json
{
"name": "electrodb",
"version": "0.9.52",
"version": "0.10.0",
"description": "A library to more easily create and interact with multiple entities and heretical relationships in dynamodb",

@@ -8,4 +8,6 @@ "main": "index.js",

"test": "mocha ./test/offline**.spec.js",
"test-ts": "mocha -r ts-node/register ./test/**.spec.ts",
"test-all": "mocha ./test/**.spec.js",
"test-all-local": "LOCAL_DYNAMO_ENDPOINT=http://localhost:8000 node ./test/init.js && LOCAL_DYNAMO_ENDPOINT=http://localhost:8000 mocha ./test/**.spec.js",
"test-all-local": "LOCAL_DYNAMO_ENDPOINT=http://localhost:8000 node ./test/init.js && LOCAL_DYNAMO_ENDPOINT=http://localhost:8000 mocha ./test/**.spec.js && npm run test-types && LOCAL_DYNAMO_ENDPOINT=http://localhost:8000 npm run test-ts",
"test-types": "node ./node_modules/tsd/dist/cli.js",
"coverage": "nyc npm run test-all && nyc report --reporter=text-lcov | coveralls",

@@ -26,11 +28,20 @@ "coverage-coveralls-local": "nyc npm run test-all-local && nyc report --reporter=text-lcov | coveralls",

"devDependencies": {
"@istanbuljs/nyc-config-typescript": "^1.0.1",
"@types/chai": "^4.2.12",
"@types/mocha": "^8.0.3",
"@types/node": "^15.6.0",
"@types/uuid": "^8.3.0",
"aws-sdk": "2.630.0",
"chai": "4.2.0",
"coveralls": "3.0.13",
"coveralls": "^3.1.0",
"istanbul": "0.4.5",
"jest": "25.4.0",
"mocha": "7.1.1",
"mocha-lcov-reporter": "1.3.0",
"mocha-lcov-reporter": "^1.3.0",
"moment": "2.24.0",
"nyc": "15.0.0",
"nyc": "^15.1.0",
"source-map-support": "^0.5.19",
"ts-node": "^9.0.0",
"tsd": "^0.14.0",
"typescript": "^4.2.4",
"uuid": "7.0.1"

@@ -44,2 +55,5 @@ },

],
"tsd": {
"directory": "test"
},
"dependencies": {

@@ -46,0 +60,0 @@ "jsonschema": "1.2.7"

@@ -19,7 +19,2 @@ const { QueryTypes, MethodTypes } = require("./types");

name: "index",
// action(entity, state, facets = {}) {
// // todo: maybe all key info is passed on the subsequent query identifiers?
// // todo: look for article/list of all dynamodb query limitations
// // return state;
// },
children: ["get", "delete", "update", "query", "put", "scan", "collection", "create", "patch", "batchPut", "batchDelete", "batchGet"],

@@ -384,3 +379,4 @@ },

let params = clauses.params.action(entity, state, options);
return entity.go(state.query.method, params, options)
let {config} = entity._applyParameterOptions({}, state.query.options, options);
return entity.go(state.query.method, params, config);
},

@@ -387,0 +383,0 @@ children: [],

@@ -39,2 +39,3 @@ "use strict";

this._instanceType = ElectroInstanceTypes.entity;
this.schema = model;
}

@@ -44,3 +45,3 @@

if (!this.identifiers[type]) {
throw new e.ElectroError(e.ErrorCodes.InvalidIdentifier, `Invalid identifier type: ${type}. Valid indentifiers include ${Object.keys(this.identifiers).join(", ")}`);
throw new e.ElectroError(e.ErrorCodes.InvalidIdentifier, `Invalid identifier type: "${type}". Valid identifiers include: ${Object.keys(this.identifiers).join(", ")}`);
} else {

@@ -51,2 +52,10 @@ this.identifiers[type] = identifier;

getName() {
return this.model.entity;
}
getVersion() {
return this.model.version;
}
find(facets = {}) {

@@ -79,7 +88,8 @@ let match = this._findBestIndexKeyMatch(facets);

collection(collection = "", clauses = {}, facets = {}, expressions = {}) {
collection(collection = "", clauses = {}, facets = {}, {expressions = {}, parse} = {}) {
let options = {
parse,
expressions: {
names: expressions.names || {},
values: expressions.values|| {},
values: expressions.values || {},
expression: expressions.expression || ""

@@ -89,9 +99,8 @@ },

};
let index = this.model.translations.collections.fromCollectionToIndex[
collection
];
let index = this.model.translations.collections.fromCollectionToIndex[collection];
if (index === undefined) {
throw new Error(`Invalid collection: ${collection}`);
}
return this._makeChain(index, this._clausesWithFilters, clauses.index, options).collection(
return this._makeChain(index, clauses, clauses.index, options).collection(
collection,

@@ -159,14 +168,3 @@ facets

async go(method, parameters = {}, options = {}) {
let config = {
includeKeys: options.includeKeys,
originalErr: options.originalErr,
raw: options.raw,
params: options.params || {},
page: options.page,
pager: !!options.pager,
lastEvaluatedKeyRaw: !!options.lastEvaluatedKeyRaw,
table: options.table,
concurrent: options.concurrent
};
async go(method, parameters = {}, config = {}) {
let stackTrace = new e.ElectroError(e.ErrorCodes.AWSError);

@@ -216,2 +214,9 @@ try {

let response = await this._exec(MethodTypes.batchWrite, params);
if (validations.isFunction(config.parse)) {
let parsed = await config.parse(config, response);
if (parsed) {
results.push(parsed);
}
return;
}
let unprocessed = this.formatBulkWriteResponse(params.IndexName, response, config);

@@ -239,2 +244,6 @@ for (let u of unprocessed) {

let response = await this._exec(MethodTypes.batchGet, params);
if (validations.isFunction(config.parse)) {
resultsAll.push(await config.parse(config, response));
return;
}
let [results, unprocessed] = this.formatBulkGetResponse(params.IndexName, response, config);

@@ -253,4 +262,6 @@ for (let r of results) {

async executeQuery(method, parameters, config) {
// let params = Object.assign({}, parameters);
let response = await this._exec(method, parameters);
if (validations.isFunction(config.parse)) {
return config.parse(config, response);
}
if (method === MethodTypes.put || method === MethodTypes.create) {

@@ -263,3 +274,2 @@ return this.formatResponse(parameters.IndexName, parameters, config);

cleanseRetrievedData(item = {}, options = {}) {

@@ -340,3 +350,2 @@ let { includeKeys } = options;

} else {
let data = {};

@@ -389,2 +398,8 @@ if (response.Item) {

_setClient(client) {
if (client) {
this.client = client;
}
}
_chain(state, clauses, clause) {

@@ -531,13 +546,46 @@ let current = {};

page: {},
pager: false
pager: false,
lastEvaluatedKeyRaw: false,
table: undefined,
concurrent: undefined,
parse: undefined
};
config = options.reduce((config, option) => {
if (option.includeKeys) config.includeKeys = true;
if (option.originalErr) config.originalErr = true;
if (option.raw) config.raw = true;
if (option.pager) config.pager = true;
if (option.lastEvaluatedKeyRaw === true) config.lastEvaluatedKeyRaw = true;
if (option.limit) config.params.Limit = option.limit;
if (option.table) config.params.TableName = option.table;
if (option.includeKeys === true) {
config.includeKeys = true;
}
if (option.originalErr === true) {
config.originalErr = true;
}
if (option.raw === true) {
config.raw = true;
}
if (option.pager) {
config.pager = true;
}
if (option.lastEvaluatedKeyRaw === true) {
config.lastEvaluatedKeyRaw = true;
}
if (!isNaN(option.limit)) {
config.params.Limit = option.limit;
}
if (validations.isStringHasLength(option.table)) {
config.params.TableName = option.table;
}
if (option.concurrent !== undefined) {
config.concurrent = option.concurrent;
}
if (validations.isFunction(option.parse)) {
config.parse = option.parse;
}
config.page = Object.assign({}, config.page, option.page);

@@ -564,3 +612,3 @@ config.params = Object.assign({}, config.params, option.params);

return parameters;
return {parameters, config};
}

@@ -614,3 +662,3 @@

let { keys = {}, method = "", put = {}, update = {}, filter = {}, options = {} } = state.query;
let conlidatedQueryFacets = this._consolidateQueryFacets(keys.sk);
let consolidatedQueryFacets = this._consolidateQueryFacets(keys.sk);
let params = {};

@@ -620,3 +668,3 @@ switch (method) {

case MethodTypes.delete:
params = this._makeSimpleIndexParams(keys.pk, ...conlidatedQueryFacets);
params = this._makeSimpleIndexParams(keys.pk, ...consolidatedQueryFacets);
break;

@@ -632,3 +680,3 @@ case MethodTypes.put:

keys.pk,
...conlidatedQueryFacets,
...consolidatedQueryFacets,
);

@@ -643,4 +691,4 @@ break;

}
params = this._applyParameterOptions(params, options, config);
return this._applyParameterExpressionTypes(params, filter);
let applied = this._applyParameterOptions(params, options, config);
return this._applyParameterExpressionTypes(applied.parameters, filter);
}

@@ -717,13 +765,15 @@

getIdentifierExpressions() {
getIdentifierExpressions(alias = this.getName()) {
let name = this.getName();
let version = this.getVersion();
return {
names: {
[`#${this.identifiers.entity}_${this.model.entity}`]: this.identifiers.entity,
[`#${this.identifiers.version}_${this.model.entity}`]: this.identifiers.version,
[`#${this.identifiers.entity}_${alias}`]: this.identifiers.entity,
[`#${this.identifiers.version}_${alias}`]: this.identifiers.version,
},
values: {
[`:${this.identifiers.entity}_${this.model.entity}`]: this.model.entity,
[`:${this.identifiers.version}_${this.model.entity}`]: this.model.version,
[`:${this.identifiers.entity}_${alias}`]: name,
[`:${this.identifiers.version}_${alias}`]: version,
},
expression: `(#${this.identifiers.entity}_${this.model.entity} = :${this.identifiers.entity}_${this.model.entity} AND #${this.identifiers.version}_${this.model.entity} = :${this.identifiers.version}_${this.model.entity})`
expression: `(#${this.identifiers.entity}_${alias} = :${this.identifiers.entity}_${alias} AND #${this.identifiers.version}_${alias} = :${this.identifiers.version}_${alias})`
}

@@ -756,4 +806,4 @@ }

params.ExpressionAttributeNames["#" + this.identifiers.version] = this.identifiers.version;
params.ExpressionAttributeValues[":" + this.identifiers.entity] = this.model.entity;
params.ExpressionAttributeValues[":" + this.identifiers.version] = this.model.version;
params.ExpressionAttributeValues[":" + this.identifiers.entity] = this.getName();
params.ExpressionAttributeValues[":" + this.identifiers.version] = this.getVersion();
params.FilterExpression = `${params.FilterExpression} AND #${this.identifiers.entity} = :${this.identifiers.entity} AND #${this.identifiers.version} = :${this.identifiers.version}`;

@@ -813,4 +863,4 @@ if (hasSortKey) {

...updatedKeys,
[this.identifiers.entity]: this.model.entity,
[this.identifiers.version]: this.model.version,
[this.identifiers.entity]: this.getName(),
[this.identifiers.version]: this.getVersion(),
},

@@ -917,3 +967,3 @@ TableName: this._getTableName(),

_queryParams(state = {}, options = {}) {
let conlidatedQueryFacets = this._consolidateQueryFacets(
let consolidatedQueryFacets = this._consolidateQueryFacets(
state.query.keys.sk,

@@ -923,7 +973,6 @@ );

if (state.query.type === QueryTypes.is) {
indexKeys = this._makeIndexKeys(state.query.index, state.query.keys.pk, ...conlidatedQueryFacets);
indexKeys = this._makeIndexKeys(state.query.index, state.query.keys.pk, ...consolidatedQueryFacets);
} else {
indexKeys = this._makeIndexKeysWithoutTail(state.query.index, state.query.keys.pk, ...conlidatedQueryFacets);
indexKeys = this._makeIndexKeysWithoutTail(state.query.index, state.query.keys.pk, ...consolidatedQueryFacets);
}
let parameters = {};

@@ -971,5 +1020,6 @@ switch (state.query.type) {

default:
throw new Error(`Invalid method: ${method}`);
throw new Error(`Invalid query type: ${state.query.type}`);
}
return this._applyParameterOptions(parameters, options);
let applied = this._applyParameterOptions(parameters, state.query.options, options);
return applied.parameters;
}

@@ -1575,5 +1625,5 @@

if (indexName === "") {
throw new e.ElectroError(e.ErrorCodes.DuplicateIndexes, `Duplicate index defined in model: ${accessPattern} ${indexName || "(PRIMARY INDEX)"}. This could be because you forgot to specify the index name of a secondary index defined in your model.`);
throw new e.ElectroError(e.ErrorCodes.DuplicateIndexes, `Duplicate index defined in model found in Access Pattern '${accessPattern}': '${indexName || "(PRIMARY INDEX)"}'. This could be because you forgot to specify the index name of a secondary index defined in your model.`);
} else {
throw new e.ElectroError(e.ErrorCodes.DuplicateIndexes, `Duplicate index defined in model: ${accessPattern} ${indexName || "(PRIMARY INDEX)"}`);
throw new e.ElectroError(e.ErrorCodes.DuplicateIndexes, `Duplicate index defined in model found in Access Pattern '${accessPattern}': '${indexName}'`);
}

@@ -1585,3 +1635,3 @@ }

if (!hasSk && inCollection) {
throw new e.ElectroError(e.ErrorCodes.CollectionNoSK, `Invalid index definition: Access pattern, ${accessPattern} ${indexName || "(PRIMARY INDEX)"}, contains a collection definition without a defined SK. Collections can only be defined on indexes with a defined SK.`);
throw new e.ElectroError(e.ErrorCodes.CollectionNoSK, `Invalid Access pattern definition for '${accessPattern}': '${indexName || "(PRIMARY INDEX)"}', contains a collection definition without a defined SK. Collections can only be defined on indexes with a defined SK.`);
}

@@ -1637,5 +1687,5 @@ let collection = index.collection || "";

if (sk.field === pk.field) {
throw new e.ElectroError(e.ErrorCodes.DuplicateIndexFields, `The Access Pattern '${accessPattern}' references the field '${pk.field}' as the field name for both the PK and SK. Fields used for indexes need to be unique to avoid conflicts.`);
throw new e.ElectroError(e.ErrorCodes.DuplicateIndexFields, `The Access Pattern '${accessPattern}' references the field '${sk.field}' as the field name for both the PK and SK. Fields used for indexes need to be unique to avoid conflicts.`);
} else if (seenIndexFields[sk.field] !== undefined) {
throw new e.ElectroError(e.ErrorCodes.DuplicateIndexFields, `Sort Key (sk) on Access Pattern '${accessPattern}' references the field '${pk.field}' which is already referenced by the Access Pattern '${seenIndexFields[pk.field]}'. Fields used for indexes need to be unique to avoid conflicts.`);
throw new e.ElectroError(e.ErrorCodes.DuplicateIndexFields, `Sort Key (sk) on Access Pattern '${accessPattern}' references the field '${sk.field}' which is already referenced by the Access Pattern '${seenIndexFields[sk.field]}'. Fields used for indexes need to be unique to avoid conflicts.`);
}else {

@@ -1771,3 +1821,3 @@ seenIndexFields[sk.field] = accessPattern;

let modelVersion = utilities.getModelVersion(model);
let service, entity, version, table;
let service, entity, version, table, name;
switch(modelVersion) {

@@ -1779,2 +1829,3 @@ case ModelVersions.beta:

table = config.table || model.table;
name = entity;
break;

@@ -1786,2 +1837,3 @@ case ModelVersions.v1:

table = config.table || model.table;
name = entity;
break;

@@ -1813,13 +1865,14 @@ default:

return {
modelVersion,
service,
version,
entity,
name,
table,
schema,
facets,
entity,
service,
indexes,
version,
filters,
prefixes,
collections,
modelVersion,
lookup: {

@@ -1826,0 +1879,0 @@ indexHasSortKeys,

@@ -5,2 +5,8 @@ const e = require("./errors");

let FilterTypes = {
ne: {
template: function eq(name, value) {
return `${name} <> ${value}`;
},
strict: false,
},
eq: {

@@ -7,0 +13,0 @@ template: function eq(name, value) {

@@ -5,2 +5,3 @@ const { Entity } = require("./entity");

const { FilterFactory, FilterTypes } = require("./filters");
const { WhereFactory } = require("./where");
const { getInstanceType, getModelVersion, applyBetaModelOverrides } = require("./util");

@@ -10,27 +11,70 @@ const v = require("./validations");

const ConstructorTypes = {
beta: "beta",
v1: "v1",
v1Map: "v1Map",
unknown: "unknown"
}
function inferConstructorType(service) {
if (v.isNameEntityRecordType(service) || v.isNameModelRecordType(service)) {
return ConstructorTypes.v1Map;
} else if (v.isBetaServiceConfig(service)) {
return ConstructorTypes.beta;
} else if (v.isStringHasLength(service)) {
return ConstructorTypes.v1;
} else {
return ConstructorTypes.unknown;
}
}
function inferJoinValues(alias, instance, config) {
let hasAlias = true;
let args = {alias, instance, config, hasAlias};
if (typeof alias !== "string") {
args.config = instance;
args.instance = alias;
args.hasAlias = false;
}
return args;
}
class Service {
constructor(service = "", config = {}) {
_betaConstructor(service, config) {
this.service = {};
/** start beta/v1 condition **/
this._modelOverrides = {};
// Unique to Beta
this._modelVersion = ModelVersions.beta;
this._modelOverrides = {
table: service.table,
service: service.service,
version: service.version,
};
this.service.name = service.name || service.service;
this.service.table = service.table;
this.service.version = service.version;
// Unique to Beta
this.config = config;
this.client = config.client;
this.entities = {};
this.find = {};
this.collectionSchema = {};
this.collections = {};
this._instance = ElectroInstance.service;
this._instanceType = ElectroInstanceTypes.service;
}
_v1Constructor(service, config) {
this.service = {};
this._modelOverrides = {};
// Unique to V1
this._modelVersion = ModelVersions.v1;
if (v.isObjectHasLength(service)) {
this._modelVersion = ModelVersions.beta;
this._modelOverrides = {
table: service.table,
service: service.service,
version: service.version,
};
this.service.name = service.name || service.service;
this.service.table = service.table || config.table;
this.service.version = service.version;
} else if (v.isStringHasLength(service)) {
this._modelVersion = ModelVersions.v1;
this.service.name = service;
this.service.table = config.table;
this._modelOverrides.table = config.table;
} else {
throw new e.ElectroError(e.ErrorCodes.InvalidJoin, `Invalid service name: ${JSON.stringify(service)}. Service name must have length greater than zero`);
}
/** end beta/v1 condition **/
this.service.name = service;
this.service.table = config.table;
this._modelOverrides.table = config.table;
// Unique to V1
this.config = config;

@@ -46,9 +90,47 @@ this.client = config.client;

join(instance = {}, config = {}) {
let options = { ...config, ...this.config };
_v1MapConstructor(service, config) {
let entityNames = Object.keys(service);
let serviceName = this._inferServiceNameFromEntityMap(service);
this._v1Constructor(serviceName, config);
for (let name of entityNames) {
let entity = service[name];
this.join(name, entity, config);
}
}
constructor(service = "", config = {}) {
let type = inferConstructorType(service);
switch(type) {
case ConstructorTypes.v1Map:
this._v1MapConstructor(service, config);
break;
case ConstructorTypes.beta:
this._betaConstructor(service, config);
break;
case ConstructorTypes.v1:
this._v1Constructor(service, config);
break;
default:
throw new e.ElectroError(e.ErrorCodes.InvalidJoin, `Invalid service name: ${JSON.stringify(service)}. Service name must have length greater than zero`);
}
}
_inferServiceNameFromEntityMap(service) {
let names = Object.keys(service);
let entity = names
.map(name => service[name])
.map(instance => this._inferJoinEntity(instance))
.find(entity => entity && entity.model && entity.model.service)
if (!entity || !entity.model || !entity.model.service) {
throw new e.ElectroError(e.ErrorCodes.InvalidJoin, `Invalid service name: Entities/Models provided do not contain property for Service Name`);
}
return entity.model.service;
}
_inferJoinEntity(instance, options) {
let entity = {};
let type = getInstanceType(instance);
/** start beta/v1 condition **/
let modelVersion = getModelVersion(instance);
/** end beta/v1 condition **/
switch(type) {

@@ -74,4 +156,20 @@ case ElectroInstanceTypes.model:

}
return entity;
}
let name = entity.model.entity;
/**
* Join
* @param {string} alias
* @param instance
* @param config
* @returns {Service}
*/
join(...args) {
let {alias, instance, config, hasAlias} = inferJoinValues(...args);
let options = { ...config, ...this.config };
let entity = this._inferJoinEntity(instance, options);
let name = hasAlias ? alias : entity.getName();
if (this.service.name.toLowerCase() !== entity.model.service.toLowerCase()) {

@@ -82,6 +180,10 @@ throw new Error(`Service name defined on joined instance, ${entity.model.service}, does not match the name of this Service: ${this.service.name}. Verify or update the service name on the Entity/Model to match the name defined on this service.`);

if (this._getTableName()) {
entity.table = this._getTableName();
entity._setTableName(this._getTableName());
}
if (this.service.version) {
if (options.client) {
entity._setClient(options.client);
}
if (this._modelVersion === ModelVersions.beta && this.service.version) {
entity.model.version = this.service.version;

@@ -95,3 +197,3 @@ }

let { entities, attributes, identifiers } = this.collectionSchema[collection];
return this._makeCollectionChain(collection, attributes, clauses, identifiers, Object.values(entities)[0], ...facets);
return this._makeCollectionChain(collection, attributes, clauses, identifiers, entities, Object.values(entities)[0], ...facets);
};

@@ -103,11 +205,37 @@ }

cleanseRetrievedData(collection = "", data = {}, config = {}) {
cleanseRetrievedData(collection = "", entities, data = {}, config = {}) {
if (config.raw) {
return data;
}
data.Items = data.Items || [];
let results = {};
let entityIdentifiers = [];
for (let alias of Object.keys(entities)) {
let entity = entities[alias];
let name = entity.model.entity;
let version = entity.model.version;
results[alias] = [];
entityIdentifiers.push({
name,
alias,
version,
nameIdentifier: entity.identifiers.entity,
versionIdentifier: entity.identifiers.version
});
}
for (let record of data.Items) {
let entity = record.__edb_e__;
if (entity) {
results[entity] = results[entity] || [];
results[entity].push(this.collectionSchema[collection].entities[entity].cleanseRetrievedData(record, config));
let entityAlias;
for (let {name, version, nameIdentifier, versionIdentifier, alias} of entityIdentifiers) {
if (record[nameIdentifier] !== undefined && record[nameIdentifier] === name && record[versionIdentifier] !== undefined && record[versionIdentifier] === version) {
entityAlias = alias;
break;
}
}
if (!entityAlias) {
continue;
}
let index = this.collectionSchema[collection].index;
results[entityAlias].push(
this.collectionSchema[collection].entities[entityAlias].formatResponse(index, {Item: record}, config)
);
}

@@ -128,19 +256,14 @@ return results;

_makeCollectionChain(name = "", attributes = {}, clauses = {}, identifiers = {}, entity = {}, facets = {}) {
_makeCollectionChain(name = "", attributes = {}, clauses = {}, expressions = {}, entities = {}, entity = {}, facets = {}) {
let filterBuilder = new FilterFactory(attributes, FilterTypes);
let whereBuilder = new WhereFactory(attributes, FilterTypes);
clauses = filterBuilder.injectFilterClauses(clauses);
return new Proxy(entity.collection(name, clauses, facets, identifiers), {
get: (target, prop) => {
if (prop === "go") {
return (options = {}) => {
let config = { ...options, raw: true };
return target[prop](config).then((data) => {
return this.cleanseRetrievedData(name, data, options);
});
};
} else {
return target[prop];
}
},
});
clauses = whereBuilder.injectWhereClauses(clauses);
let options = {
// expressions, // DynamoDB doesnt return what I expect it would when provided with these entity filters
parse: (options, data) => {
return this.cleanseRetrievedData(name, entities, data, options);
}
}
return entity.collection(name, clauses, facets, options);
}

@@ -172,7 +295,3 @@

collectionDifferences.push(
`Partition Key Facets provided "${providedIndex.pk.facets.join(
", ",
)}" do not match established facets "${definition.pk.facets.join(
", ",
)}"`,
`Partition Key Facets provided "${providedIndex.pk.facets.join(", ")}" do not match established facets "${definition.pk.facets.join(", ")}"`,
);

@@ -253,13 +372,37 @@ }

expression: ""
}
},
index: undefined,
table: ""
};
if (this.collectionSchema[collection].entities[name] !== undefined) {
throw new e.ElectroError(e.ErrorCodes.InvalidJoin, `Entity with name ${name} has already been joined to this service.`);
throw new e.ElectroError(e.ErrorCodes.InvalidJoin, `Entity with name '${name}' has already been joined to this service.`);
}
if (this.collectionSchema[collection].table !== "") {
if (this.collectionSchema[collection].table !== entity._getTableName()) {
throw new e.ElectroError(e.ErrorCodes.InvalidJoin, `Entity with name '${name}' is defined to use a different Table than what is defined on other Service Entities and/or the Service itself. Entity '${name}' is defined with table name '${entity._getTableName()}' but the Service has been defined to use table name '${this.collectionSchema[collection].table}'. All Entities in a Service must reference the same DynamoDB table. To ensure all Entities will use the same DynamoDB table, it is possible to apply the property 'table' to the Service constructor's configuration parameter.`);
}
} else {
this.collectionSchema[collection].table = entity._getTableName();
}
this.collectionSchema[collection].keys = this._processEntityKeys(this.collectionSchema[collection].keys, providedIndex);
this.collectionSchema[collection].attributes = this._processEntityAttributes(this.collectionSchema[collection].attributes, entity.model.schema.attributes);
this.collectionSchema[collection].entities[name] = entity;
this.collectionSchema[collection].identifiers = this._processEntityIdentifiers(this.collectionSchema[collection].identifiers, entity.getIdentifierExpressions());
this.collectionSchema[collection].identifiers = this._processEntityIdentifiers(this.collectionSchema[collection].identifiers, entity.getIdentifierExpressions(name));
this.collectionSchema[collection].index = this._processEntityCollectionIndex(this.collectionSchema[collection].index, providedIndex.index, name, collection);
}
_processEntityCollectionIndex(existing, provided, name, collection) {
if (typeof provided !== "string") {
throw new e.ElectroError(e.ErrorCodes.InvalidJoin, `Entity with name '${name}' does not have collection ${collection} defined on it's model`);
} else if (existing === undefined) {
return provided;
} else if (provided !== existing) {
throw new e.ElectroError(e.ErrorCodes.InvalidJoin, `Entity with name '${name}' defines collection ${collection} on index `);
} else {
return existing;
}
}
_processEntityIdentifiers(existing = {}, {names, values, expression} = {}) {

@@ -266,0 +409,0 @@ let identifiers = {};

@@ -255,2 +255,27 @@ const e = require("./errors");

function isNameEntityRecordType(entityRecord) {
return isObjectHasLength(entityRecord) && Object.values(entityRecord).find(value => {
return value._instance !== undefined;
})
}
function isNameModelRecordType(modelRecord) {
return isObjectHasLength(modelRecord) && Object.values(modelRecord).find(value => {
return value.model
&& isStringHasLength(value.model.entity)
&& isStringHasLength(value.model.version)
&& isStringHasLength(value.model.service)
});
}
function isBetaServiceConfig(serviceConfig) {
return isObjectHasLength(serviceConfig)
&& (isStringHasLength(serviceConfig.service) || isStringHasLength(serviceConfig.name))
&& isStringHasLength(serviceConfig.version)
}
function isFunction(value) {
return typeof value === "function";
}
module.exports = {

@@ -260,4 +285,8 @@ model: validateModel,

isArrayHasLength,
isNameModelRecordType,
isStringHasLength,
isObjectHasLength,
isFunction,
isBetaServiceConfig,
isNameEntityRecordType
};

@@ -54,9 +54,9 @@ const __is_clause__ = Symbol("IsWhereClause");

for (let value of values) {
let valueCount = getValueCount(attr);
let attrValue = `:${attr}_w${valueCount}`;
if (template.length > 1) {
setValue(attrValue, value);
attrValues.push(attrValue);
}
}
let valueCount = getValueCount(attr);
let attrValue = `:${attr}_w${valueCount}`;
if (template.length > 1) {
setValue(attrValue, value);
attrValues.push(attrValue);
}
}
let expression = template(path, ...attrValues);

@@ -63,0 +63,0 @@ return expression.trim();

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc