Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
if (typeof type === 'object') {
options = type;
type = undefined;
}
assert(
`The first argument to hasMany must be a string representing a model type key, not an instance of ${inspect(
type
)}. E.g., to define a relation to the Comment model, use hasMany('comment')`,
typeof type === 'string' || typeof type === 'undefined'
);
options = options || {};
if (typeof type === 'string') {
type = normalizeModelName(type);
}
// Metadata about relationships is stored on the meta of
// the relationship. This is used for introspection and
// serialization. Note that `key` is populated lazily
// the first time the CP is called.
let meta = {
type,
options,
isRelationship: true,
kind: 'hasMany',
name: 'Has Many',
key: null,
};
return computed({
addRecordData(recordData: RelationshipRecordData) {
if (this.members.has(recordData)) {
return;
}
// TODO Igor cleanup
assertPolymorphicType(this.recordData, this.relationshipMeta, recordData, this.store);
if (this.inverseRecordData) {
this.removeRecordData(this.inverseRecordData);
}
this.inverseRecordData = recordData;
super.addRecordData(recordData);
this.notifyBelongsToChange();
}
addRecordData(recordData: RelationshipRecordData, idx?: number) {
if (this.members.has(recordData)) {
return;
}
// TODO Type this
assertPolymorphicType(this.recordData, this.relationshipMeta, recordData, this.store);
super.addRecordData(recordData, idx);
// make lazy later
if (idx === undefined) {
idx = this.currentState.length;
}
this.currentState.splice(idx, 0, recordData);
// TODO Igor consider making direct to remove the indirection
// We are not lazily accessing the manyArray here because the change is coming from app side
// this.manyArray.flushCanonical(this.currentState);
this.notifyHasManyChange();
}
const StoreTypesMap = new WeakMap();
export function typesMapFor(store) {
let typesMap = StoreTypesMap.get(store);
if (typesMap === undefined) {
typesMap = new Map();
StoreTypesMap.set(store, typesMap);
}
return typesMap;
}
// override _createRecordData to add the known models to the typesMap
const __createRecordData = Store.prototype._createRecordData;
Store.prototype._createRecordData = function(identifier) {
const typesMap = typesMapFor(this);
if (!typesMap.has(identifier.type)) {
typesMap.set(identifier.type, false);
}
return __createRecordData.call(this, identifier);
};
export default {
name: '@ember-data/data-adapter',
initialize() {},
};
const StoreTypesMap = new WeakMap();
export function typesMapFor(store) {
let typesMap = StoreTypesMap.get(store);
if (typesMap === undefined) {
typesMap = new Map();
StoreTypesMap.set(store, typesMap);
}
return typesMap;
}
// override _createRecordData to add the known models to the typesMap
const __createRecordData = Store.prototype._createRecordData;
Store.prototype._createRecordData = function(identifier) {
const typesMap = typesMapFor(this);
if (!typesMap.has(identifier.type)) {
typesMap.set(identifier.type, false);
}
return __createRecordData.call(this, identifier);
};
export default {
name: '@ember-data/data-adapter',
initialize() {},
};
}
export function keyForCache(query) {
/*eslint no-unused-vars: ["error", { "ignoreRestSiblings": true }]*/
// we want to ignore size, page, responsePath, and pageFilter in the cacheKey
const { size, page, responsePath, pageFilter, ...queryForCache } = query;
const cacheKeyObject = Object.keys(queryForCache)
.sort()
.reduce((result, key) => {
result[key] = queryForCache[key];
return result;
}, {});
return JSON.stringify(cacheKeyObject);
}
export default Store.extend({
// this is a map of map that stores the caches
lazyCaches: computed(function() {
return new Map();
}),
setLazyCacheForModel(modelName, key, value) {
const cacheKey = keyForCache(key);
const cache = this.lazyCacheForModel(modelName) || new Map();
cache.set(cacheKey, value);
const lazyCaches = this.lazyCaches;
const modelKey = normalizeModelName(modelName);
lazyCaches.set(modelKey, cache);
},
getLazyCacheForModel(modelName, key) {
const cacheKey = keyForCache(key);
/**
@module @ember-data/model
*/
/**
A PromiseBelongsTo is a PromiseObject that also proxies certain method calls
to the underlying belongsTo model.
Right now we proxy:
* `reload()`
@class PromiseBelongsTo
@extends PromiseObject
@private
*/
const PromiseBelongsTo = PromiseObject.extend({
// we don't proxy meta because we would need to proxy it to the relationship state container
// however, meta on relationships does not trigger change notifications.
// if you need relationship meta, you should do `record.belongsTo(relationshipName).meta()`
meta: computed(function() {
assert(
'You attempted to access meta on the promise for the async belongsTo relationship ' +
`${this.get('_belongsToState').modelName}:${this.get('_belongsToState').key}'.` +
'\nUse `record.belongsTo(relationshipName).meta()` instead.',
false
);
}),
reload(options) {
assert('You are trying to reload an async belongsTo before it has been created', this.get('content') !== undefined);
let { key, store, originatingInternalModel } = this._belongsToState;
return store.reloadBelongsTo(this, originatingInternalModel, key, options).then(() => this);
store.findRecord('model', 1).then(function(model) {
model.get('id'); // '1'
});
```
@property id
@type {String}
*/
/**
@property currentState
@private
@type {Object}
*/
currentState: RootState.empty, // defined here to avoid triggering setUnknownProperty
/**
@property _internalModel
@private
@type {Object}
*/
_internalModel: null, // defined here to avoid triggering setUnknownProperty
/**
@property recordData
@private
@type undefined (reserved)
*/
// will be defined here to avoid triggering setUnknownProperty
/**
flushCanonical(toSet, isInitialized = true) {
// It’s possible the parent side of the relationship may have been unloaded by this point
if (!_objectIsAlive(this)) {
return;
}
// diff to find changes
let diff = diffArray(this.currentState, toSet);
if (diff.firstChangeIndex !== null) {
// it's null if no change found
// we found a change
this.arrayContentWillChange(diff.firstChangeIndex, diff.removedCount, diff.addedCount);
this.set('length', toSet.length);
this.currentState = toSet.slice();
this.arrayContentDidChange(diff.firstChangeIndex, diff.removedCount, diff.addedCount);
if (isInitialized && diff.addedCount > 0) {
//notify only on additions
//TODO only notify if unloaded
this.internalModel.manyArrayRecordAdded(this.get('key'));
}
flushCanonical(toSet, isInitialized = true) {
// It’s possible the parent side of the relationship may have been unloaded by this point
if (!_objectIsAlive(this)) {
return;
}
// diff to find changes
let diff = diffArray(this.currentState, toSet);
if (diff.firstChangeIndex !== null) {
// it's null if no change found
// we found a change
this.arrayContentWillChange(diff.firstChangeIndex, diff.removedCount, diff.addedCount);
this.set('length', toSet.length);
this.currentState = toSet.slice();
this.arrayContentDidChange(diff.firstChangeIndex, diff.removedCount, diff.addedCount);
if (isInitialized && diff.addedCount > 0) {
//notify only on additions
//TODO only notify if unloaded
this.internalModel.manyArrayRecordAdded(this.get('key'));
}
}
},