electrodb
Advanced tools
Comparing version 0.10.3 to 0.10.4
@@ -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
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
375533
6438
3328