mike-north/ember-api-actions

View on GitHub
addon/utils/serialize-and-push.ts

Summary

Maintainability
A
1 hr
Test Coverage
import { isArray } from '@ember/array';
import { typeOf } from '@ember/utils';
import Model from 'ember-data/model';
import JSONSerializer from 'ember-data/serializers/json';
import SerializerRegistry from 'ember-data/types/registries/serializer';
import { CollectionResourceDoc, Document as JSONApiDoc, DocWithData, SingleResourceDoc } from 'jsonapi-typescript';
import { _getModelClass, _getModelName, _getStoreFromRecord } from './build-url';

function isJsonApi(raw: any): raw is JSONApiDoc {
  return raw.jsonapi && raw.jsonapi.version;
}
function isDocWithData(doc: any): doc is DocWithData {
  return isJsonApi(doc) && ['object', 'array'].indexOf(typeOf((doc as DocWithData).data)) >= 0;
}

export default function serializeAndPush(this: Model, response: any) {
  if (!isDocWithData(response)) {
    // tslint:disable-next-line:no-console
    console.warn(
      'serializeAndPush may only be used with a JSON API document. Ignoring response. ' +
        'Document must have a mandatory JSON API object. See https://jsonapi.org/format/#document-jsonapi-object.'
    );
    return response;
  }

  const recordClass = _getModelClass(this);
  const modelName = _getModelName(recordClass);
  const store = _getStoreFromRecord(this);
  const serializer: JSONSerializer = store.serializerFor(modelName as keyof SerializerRegistry);
  let normalized: {};
  if (isArray(response.data)) {
    const doc = response as CollectionResourceDoc;
    normalized = serializer.normalizeArrayResponse(store, recordClass as any, doc, null as any, 'findAll');
  } else {
    const doc = response as SingleResourceDoc;
    normalized = serializer.normalizeSingleResponse(
      store,
      recordClass as any,
      doc,
      `${doc.data.id || '(unknown)'}`,
      'findRecord'
    );
  }
  return store.push(normalized);
}