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.10.3 to 0.10.4

73

index.d.ts

@@ -6,4 +6,5 @@ declare const WhereSymbol: unique symbol;

readonly required?: boolean;
readonly get?: (val: boolean, schema: any) => boolean | undefined;
readonly set?: (val: boolean, schema: any) => boolean | undefined;
readonly hidden?: boolean;
readonly get?: (val: boolean, item: any) => boolean | undefined;
readonly set?: (val: boolean | undefined, item: any) => boolean | undefined;
readonly default?: boolean | (() => boolean);

@@ -13,2 +14,3 @@ readonly validate?: ((val: boolean) => boolean) | ((val: boolean) => void) | ((val: boolean) => string | void);

readonly label?: string;
readonly watch?: ReadonlyArray<string>;
}

@@ -19,4 +21,5 @@

readonly required?: boolean;
readonly get?: (val: number, schema: any) => number | undefined;
readonly set?: (val: number, schema: any) => number | undefined;
readonly hidden?: boolean;
readonly get?: (val: number, item: any) => number | undefined;
readonly set?: (val: number | undefined, item: any) => number | undefined;
readonly default?: number | (() => number);

@@ -26,2 +29,3 @@ readonly validate?: ((val: number) => boolean) | ((val: number) => void) | ((val: number) => string | void);

readonly label?: string;
readonly watch?: ReadonlyArray<string>;
}

@@ -32,4 +36,5 @@

readonly required?: boolean;
readonly get?: (val: string, schema: any) => string | undefined;
readonly set?: (val: string, schema: any) => string | undefined;
readonly hidden?: boolean;
readonly get?: (val: string, item: any) => string | undefined;
readonly set?: (val: string | undefined, item: any) => string | undefined;
readonly default?: string | (() => string);

@@ -39,2 +44,3 @@ readonly validate?: ((val: string) => boolean) | ((val: string) => void) | ((val: string) => string | void);

readonly label?: string;
readonly watch?: ReadonlyArray<string>;
}

@@ -45,4 +51,5 @@

readonly required?: boolean;
readonly get?: (val: string, schema: any) => string | undefined;
readonly set?: (val: string, schema: any) => string | undefined;
readonly hidden?: boolean;
readonly get?: (val: string, item: any) => string | undefined;
readonly set?: (val: string | undefined, item: any) => string | undefined;
readonly default?: string | (() => string);

@@ -52,2 +59,3 @@ readonly validate?: ((val: string) => boolean) | ((val: string) => void) | ((val: string) => string | void);

readonly label?: string;
readonly watch?: ReadonlyArray<string>;
}

@@ -58,4 +66,5 @@

readonly required?: boolean;
readonly get?: (val: any, schema: any) => any | undefined;
readonly set?: (val: any, schema: any) => any | undefined;
readonly hidden?: boolean;
readonly get?: (val: any, item: any) => any | undefined;
readonly set?: (val: any | undefined, item: any) => any | undefined;
readonly default?: () => any;

@@ -65,2 +74,3 @@ readonly validate?: ((val: any) => boolean) | ((val: any) => void) | ((val: any) => string | void);

readonly label?: string;
readonly watch?: ReadonlyArray<string>;
}

@@ -137,2 +147,10 @@

type HiddenAttributes<A extends string, F extends A, C extends string, S extends Schema<A,F,C>> = ExtractKeysOfValueType<{
[a in keyof S["attributes"]]: S["attributes"][a]["hidden"] extends infer R
? R extends true
? true
: false
: never;
}, true>
type ExtractKeysOfValueType<T, K> = {

@@ -215,2 +233,5 @@ [I in keyof T]: T[I] extends K ? I : never

type ResponseItem<A extends string, F extends A, C extends string, S extends Schema<A,F,C>> =
Omit<TableItem<A,F,C,S>, HiddenAttributes<A,F,C,S>>
/* Seems to be a TypeScript defect? Can't add this type onto an Entity without it breaking Services */

@@ -351,3 +372,3 @@ // type PutItem<A extends string, F extends A, C extends string, S extends Schema<A,F,C>> =

? [keyof SK] extends [never]
? RecordsActionOptions<A,F,C,S, TableItem<A,F,C,S>[], AllTableIndexFacets<A,F,C,S>>
? RecordsActionOptions<A,F,C,S, ResponseItem<A,F,C,S>[], AllTableIndexFacets<A,F,C,S>>
// If there is no SK, dont show query operations (When no PK is specified)

@@ -359,6 +380,6 @@ : S["indexes"][I] extends IndexWithSortKey

Omit<Partial<IndexSKAttributes<A,F,C,S,I>>, keyof Facets>,
TableItem<A,F,C,S>,
ResponseItem<A,F,C,S>,
AllTableIndexFacets<A,F,C,S>
>
: RecordsActionOptions<A,F,C,S, TableItem<A,F,C,S>[], AllTableIndexFacets<A,F,C,S>>
: RecordsActionOptions<A,F,C,S, ResponseItem<A,F,C,S>[], AllTableIndexFacets<A,F,C,S>>
: never

@@ -392,18 +413,18 @@ }

constructor(schema: S, config?: EntityConfiguration);
get(key: AllTableIndexFacets<A,F,C,S>): SingleRecordOperationOptions<A,F,C,S, TableItem<A,F,C,S>>;
get(key: AllTableIndexFacets<A,F,C,S>[]): BulkRecordOperationOptions<A,F,C,S, [AllTableIndexFacets<A,F,C,S>[], TableItem<A,F,C,S>[]]>;
delete(key: AllTableIndexFacets<A,F,C,S>): SingleRecordOperationOptions<A,F,C,S, TableItem<A,F,C,S>>;
get(key: AllTableIndexFacets<A,F,C,S>): SingleRecordOperationOptions<A,F,C,S, ResponseItem<A,F,C,S>>;
get(key: AllTableIndexFacets<A,F,C,S>[]): BulkRecordOperationOptions<A,F,C,S, [AllTableIndexFacets<A,F,C,S>[], ResponseItem<A,F,C,S>[]]>;
delete(key: AllTableIndexFacets<A,F,C,S>): SingleRecordOperationOptions<A,F,C,S, ResponseItem<A,F,C,S>>;
delete(key: AllTableIndexFacets<A,F,C,S>[]): BulkRecordOperationOptions<A,F,C,S, AllTableIndexFacets<A,F,C,S>[]>;
update(key: AllTableIndexFacets<A,F,C,S>): {
set: SetRecord<A,F,C,S, SetItem<A,F,C,S>, TableIndexFacets<A,F,C,S>, TableItem<A,F,C,S>>
set: SetRecord<A,F,C,S, SetItem<A,F,C,S>, TableIndexFacets<A,F,C,S>, ResponseItem<A,F,C,S>>
};
patch(key: AllTableIndexFacets<A,F,C,S>): {
set: SetRecord<A,F,C,S, SetItem<A,F,C,S>, TableIndexFacets<A,F,C,S>, TableItem<A,F,C,S>>
set: SetRecord<A,F,C,S, SetItem<A,F,C,S>, TableIndexFacets<A,F,C,S>, ResponseItem<A,F,C,S>>
};
put(record: PutItem<A,F,C,S>): SingleRecordOperationOptions<A,F,C,S, TableItem<A,F,C,S>>;
put(record: PutItem<A,F,C,S>): SingleRecordOperationOptions<A,F,C,S, ResponseItem<A,F,C,S>>;
put(record: PutItem<A,F,C,S>[]): BulkRecordOperationOptions<A,F,C,S, AllTableIndexFacets<A,F,C,S>[]>;
create(record: PutItem<A,F,C,S>): SingleRecordOperationOptions<A,F,C,S, TableItem<A,F,C,S>>;
find(record: Partial<Item<A,F,C,S>>): RecordsActionOptions<A,F,C,S, TableItem<A,F,C,S>[], AllTableIndexFacets<A,F,C,S>>;
create(record: PutItem<A,F,C,S>): SingleRecordOperationOptions<A,F,C,S, ResponseItem<A,F,C,S>>;
find(record: Partial<Item<A,F,C,S>>): RecordsActionOptions<A,F,C,S, ResponseItem<A,F,C,S>[], AllTableIndexFacets<A,F,C,S>>;
setIdentifier(type: "model" | "version", value: string): void;
scan: RecordsActionOptions<A,F,C,S, Item<A,F,C,S>[], TableIndexFacets<A,F,C,S>>
scan: RecordsActionOptions<A,F,C,S, ResponseItem<A,F,C,S>[], TableIndexFacets<A,F,C,S>>
query: Queries<A,F,C,S>;

@@ -512,3 +533,3 @@ }

? E[EntityResultName] extends Entity<infer A, infer F, infer C, infer S>
? TableItem<A,F,C,S>[]
? ResponseItem<A,F,C,S>[]
: never

@@ -530,7 +551,7 @@ : never

? E[EntityResultName] extends Entity<infer A, infer F, infer C, infer S>
? TableItem<A,F,C,S>[]
? ResponseItem<A,F,C,S>[]
: never
: never
},
TableIndexFacets<A,F,C,S>>>
TableIndexFacets<A,F,C,S>>>
: never

@@ -555,3 +576,3 @@ : never

E extends Entity<infer A, infer F, infer C, infer S>
? TableItem<A, F, C, S>
? ResponseItem<A, F, C, S>
: never;

@@ -558,0 +579,0 @@

{
"name": "electrodb",
"version": "0.10.3",
"version": "0.10.4",
"description": "A library to more easily create and interact with multiple entities and heretical relationships in dynamodb",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -58,2 +58,12 @@ "use strict";

ownsItem(item) {
return (
item &&
this.getName() === item[this.identifiers.entity] &&
this.getVersion() === item[this.identifiers.version] &&
validations.isStringHasLength(item[this.identifiers.entity]) &&
validations.isStringHasLength(item[this.identifiers.version])
)
}
find(facets = {}) {

@@ -165,3 +175,6 @@ let match = this._findBestIndexKeyMatch(facets);

async go(method, parameters = {}, config = {}) {
let stackTrace = new e.ElectroError(e.ErrorCodes.AWSError);
let stackTrace;
if (!config.originalErr) {
stackTrace = new e.ElectroError(e.ErrorCodes.AWSError);
}
try {

@@ -177,3 +190,3 @@ switch (method) {

} catch (err) {
if (config.originalErr) {
if (config.originalErr || stackTrace === undefined) {
return Promise.reject(err);

@@ -331,6 +344,8 @@ } else {

formatResponse(index, response, config = {}) {
let stackTrace = new Error();
let stackTrace;
if (!config.originalErr) {
stackTrace = new e.ElectroError(e.ErrorCodes.AWSError);
}
try {
let results;
let results = {};
if (config.raw && !config.pager) {

@@ -346,18 +361,16 @@ if (response.TableName) {

} else {
let data = {};
if (response.Item) {
data = this.cleanseRetrievedData(response.Item, config);
if (this.ownsItem(response.Item)) {
results = this.model.schema.formatItemForRetrieval(response.Item, config);
}
} else if (response.Items) {
data = response.Items.map((item) =>
this.cleanseRetrievedData(item, config),
);
results = [];
for (let item of response.Items) {
if (this.ownsItem(item)) {
results.push(
this.model.schema.formatItemForRetrieval(item, config)
);
}
}
}
if (Array.isArray(data)) {
results = data.map((item) =>
this.model.schema.applyAttributeGetters(item),
);
} else {
results = this.model.schema.applyAttributeGetters(data);
}
}

@@ -377,3 +390,3 @@

} catch (err) {
if (config.originalErr) {
if (config.originalErr || stackTrace === undefined) {
throw err;

@@ -816,5 +829,17 @@ } else {

_removeAttributes(item, keys) {
let copy = {...item};
for (let key of (Object.keys(keys))) {
delete copy[key];
}
return copy;
}
/* istanbul ignore next */
_makeUpdateParams({ set } = {}, pk = {}, sk = {}) {
let setAttributes = this.model.schema.applyAttributeSetters(set);
let withoutKeyFacets = this._removeAttributes(set, {...pk, ...sk});
// We need to remove the pk/sk facets from before applying the Attribute setters because these values didnt
// change, and we also don't want to trigger the setters of any attributes watching these facets because that
// should only happen when an attribute is changed.
let setAttributes = this.model.schema.applyAttributeSetters(withoutKeyFacets);
let { indexKey, updatedKeys } = this._getUpdatedKeys(pk, sk, setAttributes);

@@ -821,0 +846,0 @@ let translatedFields = this.model.schema.translateToFields(setAttributes);

@@ -106,2 +106,8 @@ // # Errors:

},
InvalidAttributeWatchDefinition: {
code: 1016,
section: "invalid-attribute-watch-definition",
name: "InvalidAttributeWatchDefinition",
sym: ErrorCode
},
MissingAttribute: {

@@ -108,0 +114,0 @@ code: 2001,

@@ -1,2 +0,2 @@

const { KeyTypes, CastTypes, AttributeTypes } = require("./types");
const { KeyTypes, CastTypes, AttributeTypes, AttributeMutationMethods } = require("./types");
const AttributeTypeNames = Object.keys(AttributeTypes);

@@ -12,2 +12,3 @@ const ValidFacetTypes = [AttributeTypes.string, AttributeTypes.number, AttributeTypes.boolean, AttributeTypes.enum];

this.readOnly = !!definition.readOnly;
this.hidden = !!definition.hidden;
this.required = !!definition.required;

@@ -20,2 +21,7 @@ this.cast = this._makeCast(definition.name, definition.cast);

this.indexes = [...(definition.indexes || [])];
let {isWatched, isWatcher, watchedBy, watching} = Attribute._destructureWatcher(definition);
this._isWatched = isWatched
this._isWatcher = isWatcher;
this.watchedBy = watchedBy;
this.watching = watching;
let { type, enumArray } = this._makeType(this.name, definition.type);

@@ -26,2 +32,26 @@ this.type = type;

static _destructureWatcher(definition) {
let watchedByArr = [...(definition.watchedBy || [])];
let watchingArr = [...(definition.watching || [])];
let isWatched = watchedByArr.length > 0;
let isWatcher = watchingArr.length > 0;
let watchedBy = {};
let watching = {};
for (let watched of watchedByArr) {
watchedBy[watched] = watched;
}
for (let attribute of watchingArr) {
watching[attribute] = attribute;
}
return {
isWatched,
isWatcher,
watchedBy,
watching
}
}
_makeGet(name, get) {

@@ -124,2 +154,18 @@ if (typeof get === "function") {

isWatcher() {
return this._isWatcher;
}
isWatched() {
return this._isWatched;
}
isWatching(attribute) {
return this.watching[attribute] !== undefined;
}
isWatchedBy(attribute) {
return this.watchedBy[attribute] !== undefined;
}
_isType(value) {

@@ -210,2 +256,6 @@ if (value === undefined) {

this.translationForRetrieval = schema.translationForRetrieval;
this.hiddenAttributes = schema.hiddenAttributes;
this.readOnlyAttributes = schema.readOnlyAttributes;
this.requiredAttributes = schema.requiredAttributes;
this.translationForWatching = this._formatWatchTranslations(this.attributes);
}

@@ -215,2 +265,22 @@

_formatWatchTranslations(attributes) {
let watchersToAttributes = {};
let attributesToWatchers = {};
let hasWatchers = false;
for (let name of Object.keys(attributes)) {
if (attributes[name].isWatcher()) {
hasWatchers = true;
watchersToAttributes[name] = attributes[name].watching;
} else {
attributesToWatchers[name] = attributesToWatchers[name] || {};
attributesToWatchers[name] = attributes[name].watchedBy;
}
}
return {
hasWatchers,
watchersToAttributes,
attributesToWatchers
};
}
_normalizeAttributes(attributes = {}, facets = {}) {

@@ -223,2 +293,7 @@ let invalidProperties = [];

let translationForRetrieval = {};
let watchedAttributes = {};
let requiredAttributes = {};
let hiddenAttributes = new Set();
let readOnlyAttributes = new Set();
let definitions = {};
for (let name in attributes) {

@@ -243,6 +318,6 @@ let attribute = attributes[name];

field: attribute.field || name,
hide: !!attribute.hide,
default: attribute.default,
validate: attribute.validate,
readOnly: !!attribute.readOnly || isKey,
hidden: !!attribute.hidden,
indexes: facets.byAttr[name] || [],

@@ -252,4 +327,17 @@ type: attribute.type,

set: attribute.set,
watching: Array.isArray(attribute.watch) ? attribute.watch : []
};
if (definition.readOnly) {
readOnlyAttributes.add(name);
}
if (definition.hidden) {
hiddenAttributes.add(name);
}
if (definition.required) {
requiredAttributes[name] = name;
}
if (facets.byAttr[definition.name] !== undefined && (!ValidFacetTypes.includes(definition.type) && !Array.isArray(definition.type))) {

@@ -275,4 +363,41 @@ let assignedIndexes = facets.byAttr[name].map(assigned => assigned.index === "" ? "Table Index" : assigned.index);

translationForRetrieval[definition.field] = definition.name;
for (let watched of definition.watching) {
watchedAttributes[watched] = watchedAttributes[watched] || [];
watchedAttributes[watched].push(name);
}
definitions[name] = definition;
}
for (let name of Object.keys(definitions)) {
let definition = definitions[name];
definition.watchedBy = Array.isArray(watchedAttributes[name])
? watchedAttributes[name]
: []
normalized[name] = new Attribute(definition);
}
let watchedWatchers = [];
let watchingUnknownAttributes = [];
for (let watched of Object.keys(watchedAttributes)) {
if (normalized[watched] === undefined) {
for (let attribute of watchedAttributes[watched]) {
watchingUnknownAttributes.push({attribute, watched});
}
} else if (normalized[watched].isWatcher()) {
for (let attribute of watchedAttributes[watched]) {
watchedWatchers.push({attribute, watched});
}
}
}
if (watchingUnknownAttributes.length > 0) {
throw new e.ElectroError(e.ErrorCodes.InvalidAttributeWatchDefinition, `Attribute Validation Error. The following attributes are defined to "watch" invalid/unknown attributes: ${watchingUnknownAttributes.map(({watched, attribute}) => `"${attribute}"->"${watched}"`).join(", ")}.`);
}
if (watchedWatchers.length > 0) {
throw new e.ElectroError(e.ErrorCodes.InvalidAttributeWatchDefinition, `Attribute Validation Error. Attributes may only "watch" other attributes also watch attributes. The following attributes are defined with ineligible attributes to watch: ${watchedWatchers.map(({attribute, watched}) => `"${attribute}"->"${watched}"`).join(", ")}.`)
}
let missingFacetAttributes = facets.attributes

@@ -287,3 +412,3 @@ .filter(({ name }) => {

if (invalidProperties.length) {
let message = invalidProperties.map((prop) => `Schema Validation Error: Attribute "${prop.name}" property "${prop.property}". Received: "${prop.value}", Expected: "${prop.expected}"`);
let message = invalidProperties.map((prop) => `Schema Validation Error. Attribute "${prop.name}" property "${prop.property}". Received: "${prop.value}", Expected: "${prop.expected}"`);
throw new e.ElectroError(e.ErrorCodes.InvalidAttributeDefinition, message);

@@ -293,2 +418,5 @@ } else {

enums,
hiddenAttributes,
readOnlyAttributes,
requiredAttributes,
translationForTable,

@@ -355,24 +483,57 @@ translationForRetrieval,

applyAttributeGetters(payload = {}) {
let attributes = { ...payload };
for (let [name, value] of Object.entries(attributes)) {
if (this.attributes[name] === undefined) {
attributes[name] = value;
} else {
attributes[name] = this.attributes[name].get(value, { ...payload });
_applyAttributeMutation(method, include, avoid, payload) {
let data = { ...payload };
for (let attribute of Object.keys(include)) {
// this.attributes[attribute] !== undefined | Attribute exists as actual attribute. If `includeKeys` is turned on for example this will include values that do not have a presence in the model and therefore will not have a `.get()` method
// avoid[attribute] === undefined | Attribute shouldn't be in the avoided
if (this.attributes[attribute] !== undefined && avoid[attribute] === undefined) {
data[attribute] = this.attributes[attribute][method](payload[attribute], {...payload});
}
}
return attributes;
return data;
}
_fulfillAttributeMutationMethod(method, payload) {
let watchersToTrigger = {};
// include: payload | We want to hit the getters/setters for any attributes coming in to be changed
// avoid: watchersToAttributes | We want to avoid anything that is a watcher, even if it was included
let data = this._applyAttributeMutation(method, payload, this.translationForWatching.watchersToAttributes, payload);
// `data` here will include all the original payload values, but with the mutations applied to on non-watchers
if (!this.translationForWatching.hasWatchers) {
// exit early, why not
return data;
}
for (let attribute of Object.keys(data)) {
let watchers = this.translationForWatching.attributesToWatchers[attribute];
// Any of the attributes on data have a watcher?
if (watchers !== undefined) {
watchersToTrigger = {...watchersToTrigger, ...watchers}
}
}
// include: ...data, ...watchersToTrigger | We want to hit attributes that were watching an attribute included in data, and include an properties that were skipped because they were a watcher
// avoid: attributesToWatchers | We want to avoid hit anything that was not a watcher because they were already hit once above
return this._applyAttributeMutation(method, {...data, ...watchersToTrigger}, this.translationForWatching.attributesToWatchers, data);
}
applyAttributeGetters(payload = {}) {
return this._fulfillAttributeMutationMethod(AttributeMutationMethods.get, payload);
}
applyAttributeSetters(payload = {}) {
let attributes = { ...payload };
for (let [name, value] of Object.entries(attributes)) {
if (this.attributes[name] !== undefined) {
attributes[name] = this.attributes[name].set(value, { ...payload });
} else {
attributes[name] = value;
return this._fulfillAttributeMutationMethod(AttributeMutationMethods.set, payload);
}
translateFromFields(item = {}, options = {}) {
let { includeKeys } = options;
let data = {};
let names = this.translationForRetrieval;
for (let [attr, value] of Object.entries(item)) {
let name = names[attr];
if (name) {
data[name] = value;
} else if (includeKeys) {
data[attr] = value;
}
}
return attributes;
return data;
}

@@ -416,6 +577,17 @@

getReadOnly() {
return Object.values(this.attributes)
.filter((attribute) => attribute.readOnly)
.map((attribute) => attribute.name);
return Array.from(this.readOnlyAttributes);
}
formatItemForRetrieval(item, config) {
let remapped = this.translateFromFields(item, config);
let data = this._fulfillAttributeMutationMethod("get", remapped);
if (this.hiddenAttributes.size > 0) {
for (let attribute of Object.keys(data)) {
if (this.hiddenAttributes.has(attribute)) {
delete data[attribute];
}
}
}
return data;
}
}

@@ -422,0 +594,0 @@

@@ -86,2 +86,7 @@ const KeyTypes = {

const AttributeMutationMethods = {
get: "get",
set: "set"
}
module.exports = {

@@ -99,2 +104,3 @@ KeyTypes,

ElectroInstanceTypes,
AttributeMutationMethods,
};

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

},
hidden: {
type: "boolean"
},
watch: {
type: "array",
items: {
type: "string",
}
},
label: {

@@ -147,3 +156,3 @@ type: "string",

},
required: ["model", "attributes"]
required: ["model", "attributes", "indexes"]
};

@@ -150,0 +159,0 @@

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

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