diff --git a/FEATURES.md b/FEATURES.md index 2d566c89c37..fd945910b0e 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -11,126 +11,4 @@ entry in `config/features.json`. ## Feature Flags -- `ds-improved-ajax` [#3099](https://github.com/emberjs/data/pull/3099) - - This feature allows to customize how a request is formed by overwriting - `methodForRequest`, `urlForRequest`, `headersForRequest` and `bodyForRequest` - in the `DS.RESTAdapter`. - -- `ds-pushpayload-return` [#4110](https://github.com/emberjs/data/pull/4110) - - Enables `pushPayload` to return the model(s) that are created or - updated via the internal `store.push`. - -- `ds-payload-type-hooks` [#4318](https://github.com/emberjs/data/pull/4318) - - Adds two new hooks `modelNameFromPayloadType` and `payloadTypeFromModelName` - hooks to the serializers. They are used to map a custom type in the payload - to the Ember-Data model name and vice versa. - - It also deprecates `modelNameFromPayloadKey` and `payloadKeyFromModelName` - for the JSONSerializer and JSONAPISerializer: those payloads don't have - _keys_ which represent a model name. Only the keys in the payload for a - RESTSerializer represent model names, so the `payloadKeyFromModelName` and - `modelNameFromPayloadKey` are available in that serializer. - - ```js - // rest response - { - "blog/post": { - "id": 1, - "user": 1, - "userType": "api::v1::administrator" - } - } - - // RESTSerializer invokes the following hooks - restSerializer.modelNameFromPayloadKey("blog/post"); - restSerializer.modelNameFromPayloadType("api::v1::administrator"); - ``` - - ```js - // json-api response - { - "data": { - "id": 1, - "type": "api::v1::administrator", - "relationships": { - "supervisor": { - "data": { - "id": 1, - "type": "api::v1::super-user" - } - } - } - } - } - - // JSONAPISerializer invokes the following hooks - jsonApiSerializer.modelNameFromPayloadType("api::v1::administrator"); - jsonApiSerializer.modelNameFromPayloadType("api::v1::super-user"); - ``` - -- `ds-overhaul-references` [#4398](https://github.com/emberjs/data/pull/4398) - - This tackles some inconsistencies within `push()` on references. It should - only be used to push a JSON-API payload. The following use cases are - addressed and deprecated: - - - `BelongsToReference#push()` accepts a `DS.Model` - - `HasManyReference#push()` accepts a plain array - - `HasManyReference#push()` accepts a pseudo-JSON-API format: - - ```js - { - data: [ - { data: { type: 'model', id: 1 } } - ] - } - ``` - -- `ds-check-should-serialize-relationships` [#4279](https://github.com/emberjs/data/pull/4279) - - Adds public method for `shouldSerializeHasMany`, used to determine if a - `hasMany` relationship can be serialized. - -- `ds-rollback-attribute` [#4246](https://github.com/emberjs/data/pull/4246) - - Adds a `rollbackAttribute` method to models. Similar to `rollbackAttributes`, - but for only a single attribute. - - ```js - // { firstName: 'Tom', lastName: 'Dale' } - let tom = store.peekRecord('person', 1); - - tom.setProperties({ - firstName: 'Yehuda', - lastName: 'Katz' - }); - - tom.rollbackAttribute('firstName') // { firstName: 'Tom', lastName: 'Katz' } - tom.get('hasDirtyAttributes') // true - - tom.rollbackAttribute('lastName') // { firstName: 'Tom', lastName: 'Dale' } - tom.get('hasDirtyAttributes') // false - ``` - -- `ds-serialize-id` [#4620](https://github.com/emberjs/data/pull/4620) - - Adds a `serializeId` method to JSONSerializer. - - ```js - // app/serializers/application.js - import DS from 'ember-data'; - - export default DS.JSONSerializer.extend({ - serializeId(snapshot, json, primaryKey) { - var id = snapshot.id; - json[primaryKey] = parseInt(id, 10); - } - }); - ``` -- `ds-deprecate-store-serialize` [#4654](https://github.com/emberjs/data/pull/4654) - - Adds a deprecation warning when using Store#serialize(record) method. - You can use record.serialize() instead. +- None currently. diff --git a/addon/-private/system/model/internal-model.js b/addon/-private/system/model/internal-model.js index e1043f11d8c..305e026474d 100644 --- a/addon/-private/system/model/internal-model.js +++ b/addon/-private/system/model/internal-model.js @@ -12,7 +12,6 @@ import { assert, inspect } from '@ember/debug'; import RootState from "./states"; import Relationships from "../relationships/state/create"; import Snapshot from "../snapshot"; -import isEnabled from '../../features'; import OrderedSet from "../ordered-set"; import { getOwner } from '../../utils'; @@ -1249,20 +1248,3 @@ export default class InternalModel { return reference; } } - -if (isEnabled('ds-rollback-attribute')) { - /* - Returns the latest truth for an attribute - the canonical value, or the - in-flight value. - - @method lastAcknowledgedValue - @private - */ - InternalModel.prototype.lastAcknowledgedValue = function lastAcknowledgedValue(key) { - if (key in this._inFlightAttributes) { - return this._inFlightAttributes[key]; - } else { - return this._data[key]; - } - }; -} diff --git a/addon/-private/system/model/model.js b/addon/-private/system/model/model.js index 5d2ecce2d28..9963195b06a 100644 --- a/addon/-private/system/model/model.js +++ b/addon/-private/system/model/model.js @@ -12,7 +12,6 @@ import { DEBUG } from '@glimmer/env'; import { assert, warn } from '@ember/debug'; import { PromiseObject } from "../promise-proxies"; import Errors from "../model/errors"; -import isEnabled from '../../features'; import RootState from '../model/states'; import { relationshipsByNameDescriptor, @@ -1842,31 +1841,6 @@ Model.reopenClass({ } }); -if (isEnabled('ds-rollback-attribute')) { - Model.reopen({ - /** - Discards any unsaved changes to the given attribute. This feature is not enabled by default. You must enable `ds-rollback-attribute` and be running a canary build. - - Example - - ```javascript - record.get('name'); // 'Untitled Document' - record.set('name', 'Doc 1'); - record.get('name'); // 'Doc 1' - record.rollbackAttribute('name'); - record.get('name'); // 'Untitled Document' - ``` - - @method rollbackAttribute - */ - rollbackAttribute(attributeName) { - if (attributeName in this._internalModel._attributes) { - this.set(attributeName, this._internalModel.lastAcknowledgedValue(attributeName)); - } - } - }); -} - if (DEBUG) { Model.reopen({ // This is a temporary solution until we refactor DS.Model to not diff --git a/addon/-private/system/references/belongs-to.js b/addon/-private/system/references/belongs-to.js index 440583e4c10..20a285bbb44 100644 --- a/addon/-private/system/references/belongs-to.js +++ b/addon/-private/system/references/belongs-to.js @@ -2,8 +2,6 @@ import { resolve } from 'rsvp'; import Model from '../model/model'; import Reference from './reference'; -import isEnabled from '../../features'; -import { deprecate } from '@ember/debug'; import { assertPolymorphicType } from 'ember-data/-debug'; /** @@ -241,12 +239,6 @@ export default class BelongsToReference extends Reference { let record; if (data instanceof Model) { - if (isEnabled('ds-overhaul-references')) { - deprecate("BelongsToReference#push(DS.Model) is deprecated. Update relationship via `model.set('relationshipName', value)` instead.", false, { - id: 'ds.references.belongs-to.push-record', - until: '4.0.0' - }); - } record = data; } else { record = this.store.push(data); diff --git a/addon/-private/system/references/has-many.js b/addon/-private/system/references/has-many.js index a14a1bcbc42..9af516d6d48 100644 --- a/addon/-private/system/references/has-many.js +++ b/addon/-private/system/references/has-many.js @@ -1,13 +1,9 @@ -import { A } from '@ember/array'; import { resolve } from 'rsvp'; import { get } from '@ember/object'; import Reference from './reference'; import { DEBUG } from '@glimmer/env'; -import { deprecate } from '@ember/debug'; import { assertPolymorphicType } from 'ember-data/-debug'; -import isEnabled from '../../features'; - /** A HasManyReference is a low level API that allows users and addon author to perform meta-operations on a has-many relationship. @@ -239,53 +235,21 @@ export default class HasManyReference extends Reference { return resolve(objectOrPromise).then((payload) => { let array = payload; - if (isEnabled("ds-overhaul-references")) { - deprecate("HasManyReference#push(array) is deprecated. Push a JSON-API document instead.", !Array.isArray(payload), { - id: 'ds.references.has-many.push-array', - until: '4.0.0' - }); - } - - let useLegacyArrayPush = true; if (typeof payload === "object" && payload.data) { array = payload.data; - useLegacyArrayPush = array.length && array[0].data; - - if (isEnabled('ds-overhaul-references')) { - deprecate("HasManyReference#push() expects a valid JSON-API document.", !useLegacyArrayPush, { - id: 'ds.references.has-many.push-invalid-json-api', - until: '4.0.0' - }); - } - } - - if (!isEnabled('ds-overhaul-references')) { - useLegacyArrayPush = true; } let internalModels; - if (useLegacyArrayPush) { - internalModels = array.map((obj) => { - let record = this.store.push(obj); - - if (DEBUG) { - let relationshipMeta = this.hasManyRelationship.relationshipMeta; - assertPolymorphicType(this.internalModel, relationshipMeta, record._internalModel); - } - - return record._internalModel; - }); - } else { - let records = this.store.push(payload); - internalModels = A(records).mapBy('_internalModel'); + internalModels = array.map((obj) => { + let record = this.store.push(obj); if (DEBUG) { - internalModels.forEach((internalModel) => { - let relationshipMeta = this.hasManyRelationship.relationshipMeta; - assertPolymorphicType(this.internalModel, relationshipMeta, internalModel); - }); + let relationshipMeta = this.hasManyRelationship.relationshipMeta; + assertPolymorphicType(this.internalModel, relationshipMeta, record._internalModel); } - } + + return record._internalModel; + }); this.hasManyRelationship.computeChanges(internalModels); diff --git a/addon/-private/system/store.js b/addon/-private/system/store.js index 885c83a4c0c..f01e233150a 100644 --- a/addon/-private/system/store.js +++ b/addon/-private/system/store.js @@ -51,7 +51,6 @@ import { getOwner } from '../utils'; import coerceId from "./coerce-id"; import RecordArrayManager from "./record-array-manager"; import InternalModel from "./model/internal-model"; -import isEnabled from '../features'; const badIdFormatAssertion = '`id` passed to `findRecord()` has to be non-empty string or number'; @@ -273,12 +272,11 @@ Store = Service.extend({ @param {Object} options an options hash */ serialize(record, options) { - if (isEnabled('ds-deprecate-store-serialize')) { - deprecate('Use of store.serialize is deprecated, use record.serialize instead.', false, { - id: 'ds.store.serialize', - until: '3.0' - }); - } + deprecate('Use of store.serialize is deprecated, use record.serialize instead.', false, { + id: 'ds.store.serialize', + until: '3.0' + }); + let snapshot = record._internalModel.createSnapshot(); return snapshot.serialize(options); }, @@ -2525,11 +2523,7 @@ Store = Service.extend({ let normalizedModelName = normalizeModelName(modelName); serializer = this.serializerFor(normalizedModelName); } - if (isEnabled('ds-pushpayload-return')) { - return serializer.pushPayload(this, payload); - } else { - serializer.pushPayload(this, payload); - } + serializer.pushPayload(this, payload); }, /** diff --git a/addon/adapters/json-api.js b/addon/adapters/json-api.js index d321e91659b..fa85c6a1e93 100644 --- a/addon/adapters/json-api.js +++ b/addon/adapters/json-api.js @@ -4,7 +4,6 @@ */ import { dasherize } from '@ember/string'; import RESTAdapter from "./rest"; -import { isEnabled } from '../-private'; import { deprecate } from '@ember/debug'; import { instrument } from 'ember-data/-debug'; import { pluralize } from 'ember-inflector'; @@ -248,12 +247,8 @@ const JSONAPIAdapter = RESTAdapter.extend({ coalesceFindRequests: false, findMany(store, type, ids, snapshots) { - if (isEnabled('ds-improved-ajax') && !this._hasCustomizedAjax()) { - return this._super(...arguments); - } else { - let url = this.buildURL(type.modelName, ids, snapshots, 'findMany'); - return this.ajax(url, 'GET', { data: { filter: { id: ids.join(',') } } }); - } + let url = this.buildURL(type.modelName, ids, snapshots, 'findMany'); + return this.ajax(url, 'GET', { data: { filter: { id: ids.join(',') } } }); }, pathForType(modelName) { @@ -263,18 +258,14 @@ const JSONAPIAdapter = RESTAdapter.extend({ // TODO: Remove this once we have a better way to override HTTP verbs. updateRecord(store, type, snapshot) { - if (isEnabled('ds-improved-ajax') && !this._hasCustomizedAjax()) { - return this._super(...arguments); - } else { - let data = {}; - let serializer = store.serializerFor(type.modelName); + let data = {}; + let serializer = store.serializerFor(type.modelName); - serializer.serializeIntoHash(data, type, snapshot, { includeId: true }); + serializer.serializeIntoHash(data, type, snapshot, { includeId: true }); - let url = this.buildURL(type.modelName, snapshot.id, snapshot, 'updateRecord'); + let url = this.buildURL(type.modelName, snapshot.id, snapshot, 'updateRecord'); - return this.ajax(url, 'PATCH', { data: data }); - } + return this.ajax(url, 'PATCH', { data: data }); }, _hasCustomizedAjax() { @@ -298,60 +289,4 @@ const JSONAPIAdapter = RESTAdapter.extend({ } }); -if (isEnabled('ds-improved-ajax')) { - - JSONAPIAdapter.reopen({ - - methodForRequest(params) { - if (params.requestType === 'updateRecord') { - return 'PATCH'; - } - - return this._super(...arguments); - }, - - dataForRequest(params) { - let { requestType, ids } = params; - - if (requestType === 'findMany') { - return { - filter: { id: ids.join(',') } - }; - } - - if (requestType === 'updateRecord') { - let { store, type, snapshot } = params; - let data = {}; - let serializer = store.serializerFor(type.modelName); - - serializer.serializeIntoHash(data, type, snapshot, { includeId: true }); - - return data; - } - - return this._super(...arguments); - }, - - headersForRequest() { - let headers = this._super(...arguments) || {}; - - headers['Accept'] = 'application/vnd.api+json'; - - return headers; - }, - - _requestToJQueryAjaxHash() { - let hash = this._super(...arguments); - - if (hash.contentType) { - hash.contentType = 'application/vnd.api+json'; - } - - return hash; - } - - }); - -} - export default JSONAPIAdapter; diff --git a/addon/adapters/rest.js b/addon/adapters/rest.js index c2d02d92cbd..d5f30682fa4 100644 --- a/addon/adapters/rest.js +++ b/addon/adapters/rest.js @@ -12,7 +12,6 @@ import Adapter from "../adapter"; import { parseResponseHeaders, BuildURLMixin, - isEnabled, AdapterError, InvalidError, UnauthorizedError, @@ -478,19 +477,10 @@ const RESTAdapter = Adapter.extend(BuildURLMixin, { @return {Promise} promise */ findRecord(store, type, id, snapshot) { - if (isEnabled('ds-improved-ajax') && !this._hasCustomizedAjax()) { - let request = this._requestFor({ - store, type, id, snapshot, - requestType: 'findRecord' - }); - - return this._makeRequest(request); - } else { - let url = this.buildURL(type.modelName, id, snapshot, 'findRecord'); - let query = this.buildQuery(snapshot); + let url = this.buildURL(type.modelName, id, snapshot, 'findRecord'); + let query = this.buildQuery(snapshot); - return this.ajax(url, 'GET', { data: query }); - } + return this.ajax(url, 'GET', { data: query }); }, /** @@ -509,24 +499,13 @@ const RESTAdapter = Adapter.extend(BuildURLMixin, { */ findAll(store, type, sinceToken, snapshotRecordArray) { let query = this.buildQuery(snapshotRecordArray); + let url = this.buildURL(type.modelName, null, snapshotRecordArray, 'findAll'); - if (isEnabled('ds-improved-ajax') && !this._hasCustomizedAjax()) { - let request = this._requestFor({ - store, type, sinceToken, query, - snapshots: snapshotRecordArray, - requestType: 'findAll' - }); - - return this._makeRequest(request); - } else { - let url = this.buildURL(type.modelName, null, snapshotRecordArray, 'findAll'); - - if (sinceToken) { - query.since = sinceToken; - } - - return this.ajax(url, 'GET', { data: query }); + if (sinceToken) { + query.since = sinceToken; } + + return this.ajax(url, 'GET', { data: query }); }, /** @@ -547,22 +526,13 @@ const RESTAdapter = Adapter.extend(BuildURLMixin, { @return {Promise} promise */ query(store, type, query) { - if (isEnabled('ds-improved-ajax') && !this._hasCustomizedAjax()) { - let request = this._requestFor({ - store, type, query, - requestType: 'query' - }); + let url = this.buildURL(type.modelName, null, null, 'query', query); - return this._makeRequest(request); - } else { - let url = this.buildURL(type.modelName, null, null, 'query', query); - - if (this.sortQueryParams) { - query = this.sortQueryParams(query); - } - - return this.ajax(url, 'GET', { data: query }); + if (this.sortQueryParams) { + query = this.sortQueryParams(query); } + + return this.ajax(url, 'GET', { data: query }); }, /** @@ -584,22 +554,13 @@ const RESTAdapter = Adapter.extend(BuildURLMixin, { @return {Promise} promise */ queryRecord(store, type, query) { - if (isEnabled('ds-improved-ajax') && !this._hasCustomizedAjax()) { - let request = this._requestFor({ - store, type, query, - requestType: 'queryRecord' - }); - - return this._makeRequest(request); - } else { - let url = this.buildURL(type.modelName, null, null, 'queryRecord', query); - - if (this.sortQueryParams) { - query = this.sortQueryParams(query); - } + let url = this.buildURL(type.modelName, null, null, 'queryRecord', query); - return this.ajax(url, 'GET', { data: query }); + if (this.sortQueryParams) { + query = this.sortQueryParams(query); } + + return this.ajax(url, 'GET', { data: query }); }, /** @@ -636,17 +597,8 @@ const RESTAdapter = Adapter.extend(BuildURLMixin, { @return {Promise} promise */ findMany(store, type, ids, snapshots) { - if (isEnabled('ds-improved-ajax') && !this._hasCustomizedAjax()) { - let request = this._requestFor({ - store, type, ids, snapshots, - requestType: 'findMany' - }); - - return this._makeRequest(request); - } else { - let url = this.buildURL(type.modelName, ids, snapshots, 'findMany'); - return this.ajax(url, 'GET', { data: { ids: ids } }); - } + let url = this.buildURL(type.modelName, ids, snapshots, 'findMany'); + return this.ajax(url, 'GET', { data: { ids: ids } }); }, /** @@ -686,21 +638,12 @@ const RESTAdapter = Adapter.extend(BuildURLMixin, { @return {Promise} promise */ findHasMany(store, snapshot, url, relationship) { - if (isEnabled('ds-improved-ajax') && !this._hasCustomizedAjax()) { - let request = this._requestFor({ - store, snapshot, url, relationship, - requestType: 'findHasMany' - }); + let id = snapshot.id; + let type = snapshot.modelName; - return this._makeRequest(request); - } else { - let id = snapshot.id; - let type = snapshot.modelName; - - url = this.urlPrefix(url, this.buildURL(type, id, snapshot, 'findHasMany')); + url = this.urlPrefix(url, this.buildURL(type, id, snapshot, 'findHasMany')); - return this.ajax(url, 'GET'); - } + return this.ajax(url, 'GET'); }, /** @@ -740,20 +683,11 @@ const RESTAdapter = Adapter.extend(BuildURLMixin, { @return {Promise} promise */ findBelongsTo(store, snapshot, url, relationship) { - if (isEnabled('ds-improved-ajax') && !this._hasCustomizedAjax()) { - let request = this._requestFor({ - store, snapshot, url, relationship, - requestType: 'findBelongsTo' - }); - - return this._makeRequest(request); - } else { - let id = snapshot.id; - let type = snapshot.modelName; + let id = snapshot.id; + let type = snapshot.modelName; - url = this.urlPrefix(url, this.buildURL(type, id, snapshot, 'findBelongsTo')); - return this.ajax(url, 'GET'); - } + url = this.urlPrefix(url, this.buildURL(type, id, snapshot, 'findBelongsTo')); + return this.ajax(url, 'GET'); }, /** @@ -773,22 +707,13 @@ const RESTAdapter = Adapter.extend(BuildURLMixin, { @return {Promise} promise */ createRecord(store, type, snapshot) { - if (isEnabled('ds-improved-ajax') && !this._hasCustomizedAjax()) { - let request = this._requestFor({ - store, type, snapshot, - requestType: 'createRecord' - }); - - return this._makeRequest(request); - } else { - let data = {}; - let serializer = store.serializerFor(type.modelName); - let url = this.buildURL(type.modelName, null, snapshot, 'createRecord'); + let data = {}; + let serializer = store.serializerFor(type.modelName); + let url = this.buildURL(type.modelName, null, snapshot, 'createRecord'); - serializer.serializeIntoHash(data, type, snapshot, { includeId: true }); + serializer.serializeIntoHash(data, type, snapshot, { includeId: true }); - return this.ajax(url, "POST", { data: data }); - } + return this.ajax(url, "POST", { data: data }); }, /** @@ -808,24 +733,15 @@ const RESTAdapter = Adapter.extend(BuildURLMixin, { @return {Promise} promise */ updateRecord(store, type, snapshot) { - if (isEnabled('ds-improved-ajax') && !this._hasCustomizedAjax()) { - let request = this._requestFor({ - store, type, snapshot, - requestType: 'updateRecord' - }); + let data = {}; + let serializer = store.serializerFor(type.modelName); - return this._makeRequest(request); - } else { - let data = {}; - let serializer = store.serializerFor(type.modelName); - - serializer.serializeIntoHash(data, type, snapshot); + serializer.serializeIntoHash(data, type, snapshot); - let id = snapshot.id; - let url = this.buildURL(type.modelName, id, snapshot, 'updateRecord'); + let id = snapshot.id; + let url = this.buildURL(type.modelName, id, snapshot, 'updateRecord'); - return this.ajax(url, "PUT", { data: data }); - } + return this.ajax(url, "PUT", { data: data }); }, /** @@ -840,18 +756,9 @@ const RESTAdapter = Adapter.extend(BuildURLMixin, { @return {Promise} promise */ deleteRecord(store, type, snapshot) { - if (isEnabled('ds-improved-ajax') && !this._hasCustomizedAjax()) { - let request = this._requestFor({ - store, type, snapshot, - requestType: 'deleteRecord' - }); - - return this._makeRequest(request); - } else { - let id = snapshot.id; + let id = snapshot.id; - return this.ajax(this.buildURL(type.modelName, id, snapshot, 'deleteRecord'), "DELETE"); - } + return this.ajax(this.buildURL(type.modelName, id, snapshot, 'deleteRecord'), "DELETE"); }, _stripIDFromURL(store, snapshot) { @@ -1246,251 +1153,6 @@ const RESTAdapter = Adapter.extend(BuildURLMixin, { } }); -if (isEnabled('ds-improved-ajax')) { - - RESTAdapter.reopen({ - - /* - * Get the data (body or query params) for a request. - * - * @public - * @method dataForRequest - * @param {Object} params - * @return {Object} data - */ - dataForRequest(params) { - let { store, type, snapshot, requestType, query } = params; - - // type is not passed to findBelongsTo and findHasMany - type = type || (snapshot && snapshot.type); - - let serializer = store.serializerFor(type.modelName); - let data = {}; - - switch (requestType) { - case 'createRecord': - serializer.serializeIntoHash(data, type, snapshot, { includeId: true }); - break; - - case 'updateRecord': - serializer.serializeIntoHash(data, type, snapshot); - break; - - case 'findRecord': - data = this.buildQuery(snapshot); - break; - - case 'findAll': - if (params.sinceToken) { - query = query || {}; - query.since = params.sinceToken; - } - data = query; - break; - - case 'query': - case 'queryRecord': - if (this.sortQueryParams) { - query = this.sortQueryParams(query); - } - data = query; - break; - - case 'findMany': - data = { ids: params.ids }; - break; - - default: - data = undefined; - break; - } - - return data; - }, - - /* - * Get the HTTP method for a request. - * - * @public - * @method methodForRequest - * @param {Object} params - * @return {String} HTTP method - */ - methodForRequest(params) { - let { requestType } = params; - - switch (requestType) { - case 'createRecord': return 'POST'; - case 'updateRecord': return 'PUT'; - case 'deleteRecord': return 'DELETE'; - } - - return 'GET'; - }, - - /* - * Get the URL for a request. - * - * @public - * @method urlForRequest - * @param {Object} params - * @return {String} URL - */ - urlForRequest(params) { - let { type, id, ids, snapshot, snapshots, requestType, query } = params; - - // type and id are not passed from updateRecord and deleteRecord, hence they - // are defined if not set - type = type || (snapshot && snapshot.type); - id = id || (snapshot && snapshot.id); - - switch (requestType) { - case 'findAll': - return this.buildURL(type.modelName, null, snapshots, requestType); - - case 'query': - case 'queryRecord': - return this.buildURL(type.modelName, null, null, requestType, query); - - case 'findMany': - return this.buildURL(type.modelName, ids, snapshots, requestType); - - case 'findHasMany': - case 'findBelongsTo': { - let url = this.buildURL(type.modelName, id, snapshot, requestType); - return this.urlPrefix(params.url, url); - } - } - - return this.buildURL(type.modelName, id, snapshot, requestType, query); - }, - - /* - * Get the headers for a request. - * - * By default the value of the `headers` property of the adapter is - * returned. - * - * @public - * @method headersForRequest - * @param {Object} params - * @return {Object} headers - */ - headersForRequest(params) { - return this.get('headers'); - }, - - /* - * Get an object which contains all properties for a request which should - * be made. - * - * @private - * @method _requestFor - * @param {Object} params - * @return {Object} request object - */ - _requestFor(params) { - let method = this.methodForRequest(params); - let url = this.urlForRequest(params); - let headers = this.headersForRequest(params); - let data = this.dataForRequest(params); - - return { method, url, headers, data }; - }, - - /* - * Convert a request object into a hash which can be passed to `jQuery.ajax`. - * - * @private - * @method _requestToJQueryAjaxHash - * @param {Object} request - * @return {Object} jQuery ajax hash - */ - _requestToJQueryAjaxHash(request) { - let hash = {}; - - hash.type = request.method; - hash.url = request.url; - hash.dataType = 'json'; - hash.context = this; - - if (request.data) { - if (request.method !== 'GET') { - hash.contentType = 'application/json; charset=utf-8'; - hash.data = JSON.stringify(request.data); - } else { - hash.data = request.data; - } - } - - let headers = request.headers; - if (headers !== undefined) { - hash.beforeSend = function(xhr) { - Object.keys(headers).forEach((key) => xhr.setRequestHeader(key, headers[key])); - }; - } - - return hash; - }, - - /* - * Make a request using `jQuery.ajax`. - * - * @private - * @method _makeRequest - * @param {Object} request - * @return {Promise} promise - */ - _makeRequest(request) { - let token = heimdall.start('adapter._makeRequest'); - let adapter = this; - let hash = this._requestToJQueryAjaxHash(request); - - let { method, url } = request; - let requestData = { method, url }; - - return new Promise((resolve, reject) => { - - hash.success = function(payload, textStatus, jqXHR) { - heimdall.stop(token); - let response = ajaxSuccess(adapter, jqXHR, payload, requestData); - run.join(null, resolve, response); - }; - - hash.error = function(jqXHR, textStatus, errorThrown) { - heimdall.stop(token); - let responseData = { - textStatus, - errorThrown - }; - let error = ajaxError(adapter, jqXHR, requestData, responseData); - run.join(null, reject, error); - }; - - instrument(function() { - hash.converters = { - 'text json': function(payload) { - let token = heimdall.start('json.parse'); - let json; - try { - json = JSON.parse(payload); - } catch (e) { - json = payload; - } - heimdall.stop(token); - return json; - } - }; - }); - - adapter._ajaxRequest(hash); - - }, `DS: RESTAdapter#makeRequest: ${method} ${url}`); - } - }); - -} - function ajaxSuccess(adapter, jqXHR, payload, requestData) { let response; try { diff --git a/addon/serializers/json-api.js b/addon/serializers/json-api.js index 02ba82f1acd..0c6684eacd6 100644 --- a/addon/serializers/json-api.js +++ b/addon/serializers/json-api.js @@ -6,11 +6,11 @@ import { typeOf, isNone } from '@ember/utils'; import { dasherize } from '@ember/string'; import { pluralize, singularize } from 'ember-inflector'; -import { assert, deprecate, warn } from '@ember/debug'; +import { assert, warn } from '@ember/debug'; import { DEBUG } from '@glimmer/env'; import JSONSerializer from './json'; -import { normalizeModelName, isEnabled } from '../-private'; +import { normalizeModelName } from '../-private'; /** Ember Data 2.0 Serializer: @@ -174,23 +174,7 @@ const JSONAPISerializer = JSONSerializer.extend({ @private */ _normalizeRelationshipDataHelper(relationshipDataHash) { - if (isEnabled("ds-payload-type-hooks")) { - let modelName = this.modelNameFromPayloadType(relationshipDataHash.type); - let deprecatedModelNameLookup = this.modelNameFromPayloadKey(relationshipDataHash.type); - - if (modelName !== deprecatedModelNameLookup && this._hasCustomModelNameFromPayloadKey()) { - deprecate("You are using modelNameFromPayloadKey to normalize the type for a relationship. This has been deprecated in favor of modelNameFromPayloadType", false, { - id: 'ds.json-api-serializer.deprecated-model-name-for-relationship', - until: '4.0.0' - }); - - modelName = deprecatedModelNameLookup; - } - - relationshipDataHash.type = modelName; - } else { - relationshipDataHash.type = this.modelNameFromPayloadKey(relationshipDataHash.type); - } + relationshipDataHash.type = this.modelNameFromPayloadKey(relationshipDataHash.type); return relationshipDataHash; }, @@ -208,25 +192,8 @@ const JSONAPISerializer = JSONSerializer.extend({ let modelName, usedLookup; - if (isEnabled("ds-payload-type-hooks")) { - modelName = this.modelNameFromPayloadType(resourceHash.type); - let deprecatedModelNameLookup = this.modelNameFromPayloadKey(resourceHash.type); - - usedLookup = 'modelNameFromPayloadType'; - - if (modelName !== deprecatedModelNameLookup && this._hasCustomModelNameFromPayloadKey()) { - deprecate("You are using modelNameFromPayloadKey to normalize the type for a resource. This has been deprecated in favor of modelNameFromPayloadType", false, { - id: 'ds.json-api-serializer.deprecated-model-name-for-resource', - until: '4.0.0' - }); - - modelName = deprecatedModelNameLookup; - usedLookup = 'modelNameFromPayloadKey'; - } - } else { - modelName = this.modelNameFromPayloadKey(resourceHash.type); - usedLookup = 'modelNameFromPayloadKey'; - } + modelName = this.modelNameFromPayloadKey(resourceHash.type); + usedLookup = 'modelNameFromPayloadKey'; if (!this.store._hasModelFor(modelName)) { warn(this.warnMessageNoModelForType(modelName, resourceHash.type, usedLookup), false, { @@ -248,11 +215,7 @@ const JSONAPISerializer = JSONSerializer.extend({ */ pushPayload(store, payload) { let normalizedPayload = this._normalizeDocumentHelper(payload); - if (isEnabled('ds-pushpayload-return')) { - return store.push(normalizedPayload); - } else { - store.push(normalizedPayload); - } + store.push(normalizedPayload); }, /** @@ -371,23 +334,7 @@ const JSONAPISerializer = JSONSerializer.extend({ @private */ _extractType(modelClass, resourceHash) { - if (isEnabled("ds-payload-type-hooks")) { - let modelName = this.modelNameFromPayloadType(resourceHash.type); - let deprecatedModelNameLookup = this.modelNameFromPayloadKey(resourceHash.type); - - if (modelName !== deprecatedModelNameLookup && this._hasCustomModelNameFromPayloadKey()) { - deprecate("You are using modelNameFromPayloadKey to normalize the type for a polymorphic relationship. This has been deprecated in favor of modelNameFromPayloadType", false, { - id: 'ds.json-api-serializer.deprecated-model-name-for-polymorphic-type', - until: '3.0.0' - }); - - modelName = deprecatedModelNameLookup; - } - - return modelName; - } else { - return this.modelNameFromPayloadKey(resourceHash.type); - } + return this.modelNameFromPayloadKey(resourceHash.type); }, /** @@ -506,25 +453,8 @@ const JSONAPISerializer = JSONSerializer.extend({ serialize(snapshot, options) { let data = this._super(...arguments); + data.type = this.payloadKeyFromModelName(snapshot.modelName); - let payloadType; - if (isEnabled("ds-payload-type-hooks")) { - payloadType = this.payloadTypeFromModelName(snapshot.modelName); - let deprecatedPayloadTypeLookup = this.payloadKeyFromModelName(snapshot.modelName); - - if (payloadType !== deprecatedPayloadTypeLookup && this._hasCustomPayloadKeyFromModelName()) { - deprecate("You used payloadKeyFromModelName to customize how a type is serialized. Use payloadTypeFromModelName instead.", false, { - id: 'ds.json-api-serializer.deprecated-payload-type-for-model', - until: '4.0.0' - }); - - payloadType = deprecatedPayloadTypeLookup; - } - } else { - payloadType = this.payloadKeyFromModelName(snapshot.modelName); - } - - data.type = payloadType; return { data }; }, @@ -567,23 +497,7 @@ const JSONAPISerializer = JSONSerializer.extend({ let data = null; if (belongsTo) { - let payloadType; - - if (isEnabled("ds-payload-type-hooks")) { - payloadType = this.payloadTypeFromModelName(belongsTo.modelName); - let deprecatedPayloadTypeLookup = this.payloadKeyFromModelName(belongsTo.modelName); - - if (payloadType !== deprecatedPayloadTypeLookup && this._hasCustomPayloadKeyFromModelName()) { - deprecate("You used payloadKeyFromModelName to serialize type for belongs-to relationship. Use payloadTypeFromModelName instead.", false, { - id: 'ds.json-api-serializer.deprecated-payload-type-for-belongs-to', - until: '4.0.0' - }); - - payloadType = deprecatedPayloadTypeLookup; - } - } else { - payloadType = this.payloadKeyFromModelName(belongsTo.modelName); - } + let payloadType = this.payloadKeyFromModelName(belongsTo.modelName); data = { type: payloadType, @@ -614,24 +528,7 @@ const JSONAPISerializer = JSONSerializer.extend({ for (let i = 0; i < hasMany.length; i++) { let item = hasMany[i]; - - let payloadType; - - if (isEnabled("ds-payload-type-hooks")) { - payloadType = this.payloadTypeFromModelName(item.modelName); - let deprecatedPayloadTypeLookup = this.payloadKeyFromModelName(item.modelName); - - if (payloadType !== deprecatedPayloadTypeLookup && this._hasCustomPayloadKeyFromModelName()) { - deprecate("You used payloadKeyFromModelName to serialize type for belongs-to relationship. Use payloadTypeFromModelName instead.", false, { - id: 'ds.json-api-serializer.deprecated-payload-type-for-has-many', - until: '4.0.0' - }); - - payloadType = deprecatedPayloadTypeLookup; - } - } else { - payloadType = this.payloadKeyFromModelName(item.modelName); - } + let payloadType = this.payloadKeyFromModelName(item.modelName); data[i] = { type: payloadType, @@ -645,117 +542,6 @@ const JSONAPISerializer = JSONSerializer.extend({ } }); -if (isEnabled("ds-payload-type-hooks")) { - - JSONAPISerializer.reopen({ - - /** - `modelNameFromPayloadType` can be used to change the mapping for a DS model - name, taken from the value in the payload. - - Say your API namespaces the type of a model and returns the following - payload for the `post` model: - - ```javascript - // GET /api/posts/1 - { - "data": { - "id": 1, - "type: "api::v1::post" - } - } - ``` - - By overwriting `modelNameFromPayloadType` you can specify that the - `post` model should be used: - - ```app/serializers/application.js - import DS from 'ember-data'; - - export default DS.JSONAPISerializer.extend({ - modelNameFromPayloadType(payloadType) { - return payloadType.replace('api::v1::', ''); - } - }); - ``` - - By default the modelName for a model is its singularized name in dasherized - form. Usually, Ember Data can use the correct inflection to do this for - you. Most of the time, you won't need to override - `modelNameFromPayloadType` for this purpose. - - Also take a look at - [payloadTypeFromModelName](#method_payloadTypeFromModelName) to customize - how the type of a record should be serialized. - - @method modelNameFromPayloadType - @public - @param {String} payloadType type from payload - @return {String} modelName - */ - modelNameFromPayloadType(type) { - return singularize(normalizeModelName(type)); - }, - - /** - `payloadTypeFromModelName` can be used to change the mapping for the type in - the payload, taken from the model name. - - Say your API namespaces the type of a model and expects the following - payload when you update the `post` model: - - ```javascript - // POST /api/posts/1 - { - "data": { - "id": 1, - "type": "api::v1::post" - } - } - ``` - - By overwriting `payloadTypeFromModelName` you can specify that the - namespaces model name for the `post` should be used: - - ```app/serializers/application.js - import DS from 'ember-data'; - - export default JSONAPISerializer.extend({ - payloadTypeFromModelName(modelName) { - return 'api::v1::' + modelName; - } - }); - ``` - - By default the payload type is the pluralized model name. Usually, Ember - Data can use the correct inflection to do this for you. Most of the time, - you won't need to override `payloadTypeFromModelName` for this purpose. - - Also take a look at - [modelNameFromPayloadType](#method_modelNameFromPayloadType) to customize - how the model name from should be mapped from the payload. - - @method payloadTypeFromModelName - @public - @param {String} modelname modelName from the record - @return {String} payloadType - */ - payloadTypeFromModelName(modelName) { - return pluralize(modelName); - }, - - _hasCustomModelNameFromPayloadKey() { - return this.modelNameFromPayloadKey !== JSONAPISerializer.prototype.modelNameFromPayloadKey; - }, - - _hasCustomPayloadKeyFromModelName() { - return this.payloadKeyFromModelName !== JSONAPISerializer.prototype.payloadKeyFromModelName; - } - - }); - -} - if (DEBUG) { JSONAPISerializer.reopen({ willMergeMixin(props) { diff --git a/addon/serializers/json.js b/addon/serializers/json.js index 1970d21dcb5..88d9c1a33d3 100644 --- a/addon/serializers/json.js +++ b/addon/serializers/json.js @@ -1,15 +1,14 @@ import { assign, merge } from '@ember/polyfills'; import { isNone, typeOf } from '@ember/utils'; import { get } from '@ember/object'; -import { assert, deprecate, warn } from '@ember/debug'; +import { assert, warn } from '@ember/debug'; import Serializer from "../serializer"; import { getOwner, coerceId, modelHasAttributeOrRelationshipNamedType, normalizeModelName, - errorsArrayToHash, - isEnabled + errorsArrayToHash } from '../-private'; const emberAssign = assign || merge; @@ -611,26 +610,9 @@ const JSONSerializer = Serializer.extend({ let modelClass = this.store.modelFor(relationshipModelName); if (relationshipHash.type && !modelHasAttributeOrRelationshipNamedType(modelClass)) { - - if (isEnabled("ds-payload-type-hooks")) { - let modelName = this.modelNameFromPayloadType(relationshipHash.type); - let deprecatedModelNameLookup = this.modelNameFromPayloadKey(relationshipHash.type); - - if (modelName !== deprecatedModelNameLookup && this._hasCustomModelNameFromPayloadKey()) { - deprecate("You used modelNameFromPayloadKey to customize how a type is normalized. Use modelNameFromPayloadType instead", false, { - id: 'ds.json-serializer.deprecated-type-for-polymorphic-relationship', - until: '3.0.0' - }); - - modelName = deprecatedModelNameLookup; - } - - relationshipHash.type = modelName; - - } else { - relationshipHash.type = this.modelNameFromPayloadKey(relationshipHash.type); - } + relationshipHash.type = this.modelNameFromPayloadKey(relationshipHash.type); } + return relationshipHash; } return { id: coerceId(relationshipHash), type: relationshipModelName }; @@ -1012,13 +994,9 @@ const JSONSerializer = Serializer.extend({ let json = {}; if (options && options.includeId) { - if (isEnabled('ds-serialize-id')) { - this.serializeId(snapshot, json, get(this, 'primaryKey')); - } else { - const id = snapshot.id; - if (id) { - json[get(this, 'primaryKey')] = id; - } + const id = snapshot.id; + if (id) { + json[get(this, 'primaryKey')] = id; } } @@ -1479,63 +1457,4 @@ const JSONSerializer = Serializer.extend({ } }); -if (isEnabled("ds-payload-type-hooks")) { - - JSONSerializer.reopen({ - - /** - @method modelNameFromPayloadType - @public - @param {String} type - @return {String} the model's modelName - */ - modelNameFromPayloadType(type) { - return normalizeModelName(type); - }, - - _hasCustomModelNameFromPayloadKey() { - return this.modelNameFromPayloadKey !== JSONSerializer.prototype.modelNameFromPayloadKey; - } - - }); - -} - -if (isEnabled("ds-serialize-id")) { - - JSONSerializer.reopen({ - - /** - serializeId can be used to customize how id is serialized - For example, your server may expect integer datatype of id - - By default the snapshot's id (String) is set on the json hash via json[primaryKey] = snapshot.id. - - ```app/serializers/application.js - import DS from 'ember-data'; - - export default DS.JSONSerializer.extend({ - serializeId(snapshot, json, primaryKey) { - var id = snapshot.id; - json[primaryKey] = parseInt(id, 10); - } - }); - ``` - - @method serializeId - @public - @param {DS.Snapshot} snapshot - @param {Object} json - @param {String} primaryKey - */ - serializeId(snapshot, json, primaryKey) { - let id = snapshot.id; - - if (id) { - json[primaryKey] = id; - } - } - }); -} - export default JSONSerializer; diff --git a/addon/serializers/rest.js b/addon/serializers/rest.js index 3480b3f9bab..97e1085808e 100644 --- a/addon/serializers/rest.js +++ b/addon/serializers/rest.js @@ -14,8 +14,7 @@ import JSONSerializer from "../serializers/json"; import { coerceId, modelHasAttributeOrRelationshipNamedType, - normalizeModelName, - isEnabled + normalizeModelName } from '../-private'; /** @@ -201,22 +200,7 @@ const RESTSerializer = JSONSerializer.extend({ if (!primaryHasTypeAttribute && hash.type) { // Support polymorphic records in async relationships - let modelName; - if (isEnabled("ds-payload-type-hooks")) { - modelName = this.modelNameFromPayloadType(hash.type); - let deprecatedModelNameLookup = this.modelNameFromPayloadKey(hash.type); - - if (modelName !== deprecatedModelNameLookup && !this._hasCustomModelNameFromPayloadType() && this._hasCustomModelNameFromPayloadKey()) { - deprecate("You are using modelNameFromPayloadKey to normalize the type for a polymorphic relationship. This is has been deprecated in favor of modelNameFromPayloadType", false, { - id: 'ds.rest-serializer.deprecated-model-name-for-polymorphic-type', - until: '3.0.0' - }); - - modelName = deprecatedModelNameLookup; - } - } else { - modelName = this.modelNameFromPayloadKey(hash.type); - } + let modelName = this.modelNameFromPayloadKey(hash.type); if (store._hasModelFor(modelName)) { serializer = store.serializerFor(modelName); @@ -429,11 +413,7 @@ const RESTSerializer = JSONSerializer.extend({ }); } - if (isEnabled('ds-pushpayload-return')) { - return store.push(documentHash); - } else { - store.push(documentHash); - } + store.push(documentHash); }, /** @@ -755,11 +735,7 @@ const RESTSerializer = JSONSerializer.extend({ if (isNone(belongsTo)) { json[typeKey] = null; } else { - if (isEnabled("ds-payload-type-hooks")) { - json[typeKey] = this.payloadTypeFromModelName(belongsTo.modelName); - } else { - json[typeKey] = camelize(belongsTo.modelName); - } + json[typeKey] = camelize(belongsTo.modelName); } }, @@ -797,165 +773,17 @@ const RESTSerializer = JSONSerializer.extend({ let typeProperty = this.keyForPolymorphicType(key, relationshipType, 'deserialize'); if (isPolymorphic && resourceHash[typeProperty] !== undefined && typeof relationshipHash !== 'object') { - - if (isEnabled("ds-payload-type-hooks")) { - - let payloadType = resourceHash[typeProperty]; - let type = this.modelNameFromPayloadType(payloadType); - let deprecatedTypeLookup = this.modelNameFromPayloadKey(payloadType); - - if (payloadType !== deprecatedTypeLookup && !this._hasCustomModelNameFromPayloadType() && this._hasCustomModelNameFromPayloadKey()) { - deprecate("You are using modelNameFromPayloadKey to normalize the type for a polymorphic relationship. This has been deprecated in favor of modelNameFromPayloadType", false, { - id: 'ds.rest-serializer.deprecated-model-name-for-polymorphic-type', - until: '3.0.0' - }); - - type = deprecatedTypeLookup; - } - - return { - id: relationshipHash, - type: type - }; - - } else { - - let type = this.modelNameFromPayloadKey(resourceHash[typeProperty]); - return { - id: relationshipHash, - type: type - }; - - } + let type = this.modelNameFromPayloadKey(resourceHash[typeProperty]); + return { + id: relationshipHash, + type: type + }; } return this._super(...arguments); } }); - -if (isEnabled("ds-payload-type-hooks")) { - - RESTSerializer.reopen({ - - /** - `modelNameFromPayloadType` can be used to change the mapping for a DS model - name, taken from the value in the payload. - - Say your API namespaces the type of a model and returns the following - payload for the `post` model, which has a polymorphic `user` relationship: - - ```javascript - // GET /api/posts/1 - { - "post": { - "id": 1, - "user": 1, - "userType: "api::v1::administrator" - } - } - ``` - - By overwriting `modelNameFromPayloadType` you can specify that the - `administrator` model should be used: - - ```app/serializers/application.js - import DS from 'ember-data'; - - export default DS.RESTSerializer.extend({ - modelNameFromPayloadType(payloadType) { - return payloadType.replace('api::v1::', ''); - } - }); - ``` - - By default the modelName for a model is its name in dasherized form. - Usually, Ember Data can use the correct inflection to do this for you. Most - of the time, you won't need to override `modelNameFromPayloadType` for this - purpose. - - Also take a look at - [payloadTypeFromModelName](#method_payloadTypeFromModelName) to customize - how the type of a record should be serialized. - - @method modelNameFromPayloadType - @public - @param {String} payloadType type from payload - @return {String} modelName - */ - modelNameFromPayloadType(payloadType) { - return singularize(normalizeModelName(payloadType)); - }, - - /** - `payloadTypeFromModelName` can be used to change the mapping for the type in - the payload, taken from the model name. - - Say your API namespaces the type of a model and expects the following - payload when you update the `post` model, which has a polymorphic `user` - relationship: - - ```javascript - // POST /api/posts/1 - { - "post": { - "id": 1, - "user": 1, - "userType": "api::v1::administrator" - } - } - ``` - - By overwriting `payloadTypeFromModelName` you can specify that the - namespaces model name for the `administrator` should be used: - - ```app/serializers/application.js - import DS from 'ember-data'; - - export default DS.RESTSerializer.extend({ - payloadTypeFromModelName(modelName) { - return 'api::v1::' + modelName; - } - }); - ``` - - By default the payload type is the camelized model name. Usually, Ember - Data can use the correct inflection to do this for you. Most of the time, - you won't need to override `payloadTypeFromModelName` for this purpose. - - Also take a look at - [modelNameFromPayloadType](#method_modelNameFromPayloadType) to customize - how the model name from should be mapped from the payload. - - @method payloadTypeFromModelName - @public - @param {String} modelName modelName from the record - @return {String} payloadType - */ - payloadTypeFromModelName(modelName) { - return camelize(modelName); - }, - - _hasCustomModelNameFromPayloadKey() { - return this.modelNameFromPayloadKey !== RESTSerializer.prototype.modelNameFromPayloadKey; - }, - - _hasCustomModelNameFromPayloadType() { - return this.modelNameFromPayloadType !== RESTSerializer.prototype.modelNameFromPayloadType; - }, - - _hasCustomPayloadTypeFromModelName() { - return this.payloadTypeFromModelName !== RESTSerializer.prototype.payloadTypeFromModelName; - }, - - _hasCustomPayloadKeyFromModelName() { - return this.payloadKeyFromModelName !== RESTSerializer.prototype.payloadKeyFromModelName; - } - - }); - -} - if (DEBUG) { RESTSerializer.reopen({ warnMessageNoModelForKey(prop, typeKey) { diff --git a/config/features.json b/config/features.json index e7bcedaf466..2c63c085104 100644 --- a/config/features.json +++ b/config/features.json @@ -1,9 +1,2 @@ { - "ds-improved-ajax": null, - "ds-pushpayload-return": null, - "ds-overhaul-references": null, - "ds-payload-type-hooks": null, - "ds-rollback-attribute": null, - "ds-serialize-id": null, - "ds-deprecate-store-serialize": true }