Skip to content

Instantly share code, notes, and snippets.

@ismasan
Last active March 9, 2018 15:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ismasan/a1dafc96decd4724c952c5fb39cda7c9 to your computer and use it in GitHub Desktop.
Save ismasan/a1dafc96decd4724c952c5fb39cda7c9 to your computer and use it in GitHub Desktop.
var sys = require('util');
function value (obj, path) {
var segments = path.split('/')
if(segments[0] == '') segments = segments.slice(1)
return segments.reduce(function (memo, segment) {
return (typeof memo == 'object') ? memo[segment] : {}
}, obj)
}
var ROOT_PATH = new RegExp('^\/')
function Mapper() {
}
Mapper.prototype.scope = function (path, func) {
this.scopePath = path
func.call(this)
return this
}
Mapper.prototype.map = function (headerName, path, modifierFunc) {
this.schema = this.schema || []
var modifierFunc = modifierFunc || function (value) {return value}
this.schema.push([headerName, path, modifierFunc])
return this
}
Mapper.prototype.headers = function () {
return this.schema.map(function (segs) {
return segs[0]
})
}
Mapper.prototype.eachRow = function (topEntity, func, thisArg) {
var self = this
var base = this.scopePath ? value(topEntity, this.scopePath) : topEntity
if(!('forEach' in base)) base = [base]
base.forEach(function (entity, idx) {
var row = []
this.schema.forEach(function (scheme) {
var path = scheme[1],
modifierFunc = scheme[2];
if(ROOT_PATH.test(path)) { // look from top entity
row.push(modifierFunc(value(topEntity, path)))
} else { // look in this sub entity
row.push(modifierFunc(value(entity, path)))
}
})
thisArg = thisArg || row
func.call(thisArg, row, idx + 1)
}, this)
return this
}
exports.define = function (definitions) {
var constructor = function () {
definitions.call(this)
}
sys.inherits(constructor, Mapper)
return constructor
}
var mapper = require('../lib/object_mapper');
function year (dateString) {
return new Date(dateString).getFullYear()
}
function month (dateString) {
return new Date(dateString).getMonth() + 1
}
function day (dateString) {
return new Date(dateString).getUTCDate()
}
function address (props) {
if(props == null) return ''
return [props.street, props.street_2, props.postal_code].join(', ')
}
function tbd (value) {
return 'TBD'
}
var OrderMapper = mapper.define(function () {
this.scope('_embedded/line_items', function () {
this
.map('id', '/id')
.map('order', '/code')
.map('status', '/status')
.map('discount', '/discount_total')
.map('shipping price', '/shipping_total')
.map('net total', '/net_total')
.map('total', '/total')
.map('shipping zone', '/shipping_description')
.map('year', '/updated_on', year)
.map('month', '/updated_on', month)
.map('day', '/updated_on', day)
.map('payment method', '/payment_info/name')
.map('payment auth code', '/payment_info/auth_code')
.map('payment transaction ID', '/payment_info/transaction_id')
.map('name', '/_embedded/contact/name')
.map('email', '/_embedded/contact/email')
.map('address', '/_embedded/address', address)
.map('locality_name', '/_embedded/address/locality_name')
.map('region_name', '/_embedded/address/region_name')
.map('country_name', '/_embedded/address/country_name')
.map('product', 'product_title')
.map('product_type_name','product_type_name')
.map('variant', 'variant_title')
.map('sku', 'variant_sku')
.map('unit price', 'unit_price')
.map('quantity', 'units')
.map('requested quantity','requested_units')
.map('order_weight_gr', '/total_weight_in_grams')
.map('unit_weight_gr', 'product_weight_in_grams')
.map('weight_gr', 'weight_in_grams')
})
})
exports.OrderMapper = OrderMapper
var assert = require("assert"),
OrderMapper = require('../mappers/orders_mapper.js').OrderMapper;
describe('Orders mapper', function () {
var mapper = new OrderMapper()
describe('#headers()', function () {
it('includes the following headers', function () {
assert.deepEqual(
mapper.headers(),
[ 'id',
'order',
'status',
'discount',
'shipping price',
'net total',
'total',
'shipping zone',
'year',
'month',
'day',
'payment method',
'payment auth code',
'payment transaction ID',
'name',
'email',
'address',
'locality_name',
'region_name',
'country_name',
'product',
'product_type_name',
'variant',
'sku',
'unit price',
'quantity',
'requested quantity',
'order_weight_gr',
'unit_weight_gr',
'weight_gr'
]
)
})
})
describe('#eachRow', function () {
var order = {
id: '123',
code: 'abc',
status: 'shipped',
discount_total: 10,
shipping_total: 11,
shipping_description: 'London',
net_total: 100,
total_weight_in_grams: 120,
total: 121,
created_on: '2014-01-02',
updated_on: '2014-01-03',
payment_info: {
type: 'webpay',
name: 'Webpay',
auth_code: '1234',
transaction_id: 'abc'
},
_embedded: {
contact: {
name: 'Juan Perez',
email: 'juan@perez.com'
},
address: {
street: 'Main Street',
street_2: 'flat B',
postal_code: 'zip123',
locality_name: 'London',
region_name: 'Greater London',
country_name: 'UK'
},
line_items: [
{
product_title: 'iPhone 17',
product_type_name: 'A type',
variant_title: 'white',
variant_sku: 'sku123',
unit_price: 10,
units: 1,
requested_units: 1,
weight_in_grams: 100,
product_weight_in_grams: 100
},
{
product_title: 'iPhone 15',
product_type_name: 'A type',
variant_title: 'red',
variant_sku: 'sku124',
unit_price: 11,
units: 2,
requested_units: 3,
weight_in_grams: 20,
product_weight_in_grams: 10
}
]
}
}
it('maps API order to rows per order item', function () {
var rows = []
mapper.eachRow(order, function (r) {
rows.push(r)
})
assert.equal(rows.length, 2)
assert.deepEqual(rows[0], [
'123',
'abc',
'shipped',
10,
11,
100,
121,
'London',
2014,
1,
3,
'Webpay',
'1234',
'abc',
'Juan Perez',
'juan@perez.com',
'Main Street, flat B, zip123',
'London',
'Greater London',
'UK',
'iPhone 17',
'A type',
'white',
'sku123',
10,
1,
1,
120,
100,
100
])
assert.deepEqual(rows[1], [
'123',
'abc',
'shipped',
10,
11,
100,
121,
'London',
2014,
1,
3,
'Webpay',
'1234',
'abc',
'Juan Perez',
'juan@perez.com',
'Main Street, flat B, zip123',
'London',
'Greater London',
'UK',
'iPhone 15',
'A type',
'red',
'sku124',
11,
2,
3,
120,
10,
20
])
})
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment