Repository URL to install this package:
|
Version:
1.2.0 ▾
|
"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]
});