-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: extract model/json:api hooks installation into meta package
- Loading branch information
Showing
11 changed files
with
246 additions
and
222 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { getOwner, setOwner } from '@ember/application'; | ||
import { assert } from '@ember/debug'; | ||
|
||
import { setCacheFor, setRecordIdentifier, type Store, StoreMap } from '@ember-data/store/-private'; | ||
import type { Cache } from '@ember-data/types/cache/cache'; | ||
import type { DSModel, DSModelSchema, ModelStore } from '@ember-data/types/q/ds-model'; | ||
import type { StableRecordIdentifier } from '@ember-data/types/q/identifier'; | ||
|
||
import { getModelFactory } from './schema-definition-service'; | ||
import { normalizeModelName } from './util'; | ||
|
||
export function instantiateRecord( | ||
this: ModelStore, | ||
identifier: StableRecordIdentifier, | ||
createRecordArgs: { [key: string]: unknown } | ||
): DSModel { | ||
const type = identifier.type; | ||
|
||
const cache = this.cache; | ||
// TODO deprecate allowing unknown args setting | ||
const createOptions = { | ||
_createProps: createRecordArgs, | ||
// TODO @deprecate consider deprecating accessing record properties during init which the below is necessary for | ||
_secretInit: { | ||
identifier, | ||
cache, | ||
store: this, | ||
cb: secretInit, | ||
}, | ||
}; | ||
|
||
// ensure that `getOwner(this)` works inside a model instance | ||
setOwner(createOptions, getOwner(this)!); | ||
const factory = getModelFactory(this, this._modelFactoryCache, type); | ||
|
||
assert(`No model was found for '${type}'`, factory); | ||
return factory.class.create(createOptions); | ||
} | ||
|
||
export function teardownRecord(record: DSModel): void { | ||
assert( | ||
`expected to receive an instance of DSModel. If using a custom model make sure you implement teardownRecord`, | ||
'destroy' in record | ||
); | ||
record.destroy(); | ||
} | ||
|
||
export function modelFor(this: ModelStore, modelName: string): DSModelSchema | void { | ||
assert(`You need to pass a model name to the store's modelFor method`, modelName); | ||
assert( | ||
`Please pass a proper model name to the store's modelFor method`, | ||
typeof modelName === 'string' && modelName.length | ||
); | ||
const type = normalizeModelName(modelName); | ||
const maybeFactory = getModelFactory(this, this._modelFactoryCache, type); | ||
const klass = maybeFactory && maybeFactory.class ? maybeFactory.class : null; | ||
|
||
const ignoreType = !klass || !klass.isModel || this._forceShim; | ||
if (!ignoreType) { | ||
return klass; | ||
} | ||
assert( | ||
`No model was found for '${type}' and no schema handles the type`, | ||
this.getSchemaDefinitionService().doesTypeExist(type) | ||
); | ||
} | ||
|
||
function secretInit(record: DSModel, cache: Cache, identifier: StableRecordIdentifier, store: Store): void { | ||
setRecordIdentifier(record, identifier); | ||
StoreMap.set(record, store); | ||
setCacheFor(record, cache); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import { getOwner } from '@ember/application'; | ||
|
||
import type { DSModelSchema, FactoryCache, ModelFactory, ModelStore } from '@ember-data/types/q/ds-model'; | ||
import type { RecordIdentifier } from '@ember-data/types/q/identifier'; | ||
import type { AttributesSchema, RelationshipsSchema } from '@ember-data/types/q/record-data-schemas'; | ||
|
||
import _modelForMixin from './model-for-mixin'; | ||
import { normalizeModelName } from './util'; | ||
|
||
export class ModelSchemaDefinitionService { | ||
declare store: ModelStore; | ||
declare _relationshipsDefCache: Record<string, RelationshipsSchema>; | ||
declare _attributesDefCache: Record<string, AttributesSchema>; | ||
|
||
constructor(store: ModelStore) { | ||
this.store = store; | ||
this._relationshipsDefCache = Object.create(null) as Record<string, RelationshipsSchema>; | ||
this._attributesDefCache = Object.create(null) as Record<string, AttributesSchema>; | ||
} | ||
|
||
// Following the existing RD implementation | ||
attributesDefinitionFor(identifier: RecordIdentifier | { type: string }): AttributesSchema { | ||
const { type } = identifier; | ||
let attributes: AttributesSchema; | ||
|
||
attributes = this._attributesDefCache[type]; | ||
|
||
if (attributes === undefined) { | ||
let modelClass = this.store.modelFor(type); | ||
let attributeMap = modelClass.attributes; | ||
|
||
attributes = Object.create(null) as AttributesSchema; | ||
attributeMap.forEach((meta, name) => (attributes[name] = meta)); | ||
this._attributesDefCache[type] = attributes; | ||
} | ||
|
||
return attributes; | ||
} | ||
|
||
// Following the existing RD implementation | ||
relationshipsDefinitionFor(identifier: RecordIdentifier | { type: string }): RelationshipsSchema { | ||
const { type } = identifier; | ||
let relationships: RelationshipsSchema; | ||
|
||
relationships = this._relationshipsDefCache[type]; | ||
|
||
if (relationships === undefined) { | ||
let modelClass = this.store.modelFor(type) as DSModelSchema; | ||
relationships = modelClass.relationshipsObject || null; | ||
this._relationshipsDefCache[type] = relationships; | ||
} | ||
|
||
return relationships; | ||
} | ||
|
||
doesTypeExist(modelName: string): boolean { | ||
const type = normalizeModelName(modelName); | ||
const factory = getModelFactory(this.store, this.store._modelFactoryCache, type); | ||
|
||
return factory !== null; | ||
} | ||
} | ||
|
||
export function getModelFactory(store: ModelStore, cache: FactoryCache, type: string): ModelFactory | null { | ||
let factory: ModelFactory | undefined = cache[type]; | ||
|
||
if (!factory) { | ||
const owner = getOwner(store)!; | ||
factory = owner.factoryFor(`model:${type}`) as ModelFactory | undefined; | ||
|
||
if (!factory) { | ||
//Support looking up mixins as base types for polymorphic relationships | ||
factory = _modelForMixin(store, type); | ||
} | ||
|
||
if (!factory) { | ||
// we don't cache misses in case someone wants to register a missing model | ||
return null; | ||
} | ||
|
||
let klass = factory.class; | ||
|
||
if (klass.isModel) { | ||
let hasOwnModelNameSet = klass.modelName && Object.prototype.hasOwnProperty.call(klass, 'modelName'); | ||
if (!hasOwnModelNameSet) { | ||
Object.defineProperty(klass, 'modelName', { value: type }); | ||
} | ||
} | ||
|
||
cache[type] = factory; | ||
} | ||
|
||
return factory; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.