Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
"use strict";

const fixture = require("./fixture");

const CompositionLayer = require("./schema"); // @TODO either
// 1. reverse() to undo all coercsions SOMEHOW
// 2. find a more ingenius solution
// 3. have the view send the data the proper format,
//    and we add a mapping for UPDATES not just FETCHING
// @TODO coerce property names toLowerCase
// .scope('namespace')
// or Type.string.url.image('default url')
// .name('product')
// @TODO 1 could even do .namespace('product'), to auto register types, not needed though
// @TODO 2 could use namespaces to create conditions that allow different defaults
//      for those names for easy centralization of entity defaults
//      for now can just call it with an argument if it needs a default
// Type.register('Nav').enum('identifier', 'moose', 'eh').default('identifier')
//
// @TODO am unsure about this one
// Composition.props(['image'])
// 'children.products': [PRODUCT],
// pricing: Composition.pipe(indexBy('label'), PRICE),
// const CompositionLayer = { Type, Schema, Composition, Transform }


const Type = CompositionLayer.Type,
      Schema = CompositionLayer.Schema,
      Composition = CompositionLayer.Composition,
      Transform = CompositionLayer.Transform;
const indexBy = Transform.indexBy; // ---- reusable root registrations ----

/**
 * define an image with a default for this scope
 */

const TypeImage = Type.image('default url');
/**
 * coerce all images
 */

Type.registerProperty('*.image', TypeImage);
/**
 * coerce all identifiers
 */

Type.registerProperty('*.identifier', Type.id());
/**
 * make a type
 */

Type.register('Nav').enum('identifier', 'moose', 'eh').default('identifier'); // ---- domain Compositions ----

/**
 * our product schema
 */

const PRODUCT = Composition.schema({
  name: String
});
/**
 * @NOTE this could use `transform('pricing.prices', indexBy('label'))`
 *       but better to do less transforming,
 *       and more entity composition with related pieces,
 *       future-friendly for only selecting properties required
 *       @example graphql, where we'd get currencycode as-needed
 *
 *
 * @example input
 *   {
 *     pricing: {
 *       currencycode: '$',
 *       prices: [
 *         { label: 'sale', type: 'Sale', value: '40.0' },
 *         { label: 'reg', type: 'Reg', value: '$274.40' },
 *       ],
 *     },
 *   }
 *
 * @see above for Money entity
 * @example output
 * {pricing: Money}
 *
 */

const PRICING = Type.Moneys();
/**
 * our catalog schema
 */

const CATALOG = Composition
/**
 * @name transform/reshape/evolve
 *
 * 1. skus becomes an object with `.identifier` as the index
 * 2. pricing uses `label` as the index
 *
 * @example input
 *  {
 *    skus: [
 *      {
 *        identifier: 'id',
 *        name: 'eh'
 *      }
 *    ],
 *    {
 *      pricing: {
 *        prices: [
 *          { label: 'sale', type: 'Sale', value: '40.0' },
 *        ]
 *      }
 *    }
 *  }
 *
 * @example output
 *  {
 *    skus: { 'id': {name: 'eh'} },
 *    pricing: Money
 *  }
 *
 *
 *
 */
.reshape({
  skus: indexBy('identifier'),
  pricing: PRICING
}) // --- catalog continued

/**
 * our api response
 * has a lot of objects
 * that just have 1 property in an object
 *
 * this lets us easily
 * lift every `.children` property up
 *
 * @NOTE defaults 1 level lifting, can pass in a number to move it higher
 */
.lift('children').schema({
  /**
   * @NOTE this would be optional,
   *       because we registered all .image, before
   *       and we can log our schema with .toJSON
   */
  image: TypeImage,
  navtype: Type.Nav(),

  /**
   * we already lifted .children, so instead of children.products
   */
  products: [PRODUCT]
});