glutenfree
Version:
A profiler/loganalyzer for nginx/Cetrea Aw.
114 lines (92 loc) • 3.99 kB
text/coffeescript
_ = require("underscore")
winston = require("winston")
util = require("util")
class Mapper
constructor: ->
unmap: (schema) ->
unmapped =
for schematic in schema
do (schematic) ->
if Array.isArray(schematic)
# replace value of keyed properties in schematic.original
newArg = schematic.original
for arg in schematic
do (arg) ->
newArg[arg.key] = arg.newvalue
# return newArg
JSON.stringify(newArg)
else if typeof(schematic) is "object"
schematic.newvalue.join(",")
# return "/" joined string
unmapped.join("/")
# map supports three schemes:
# map(["conf#genericlistid"], args)
# map(["mapi#Organization.Id"], args) shorthanded to map(["Organization.Id"], args)
# map([{ key1: obj1 }, ..., { keyN: objN}]) where
# key is the property of json argument which should be mapped, and
# obj is an object controlling the mapping.
# Example:
# url is /ModuleX/ActionY/{ Organization: 123, Task: "Task.Oid1" }/999 which could be mapped as follows
# map[{ Organization: { Type: "Organization", Property: "Id" }, Task: { Type: "Task", Property: "Oid" } }, "Personnel.Id"]
# --
# The following properties are available the obj controlling the mapi:
# * Type: The MAPI type of the object to map.
# * Property: The property to use on the object.
# * Depth: The depth used in the query (if you want to filter on nested properties)
# * Filter: A function taking two arguments, 1) the obj in question, 2) the schema used (here you can see e.g. other mapped properties). Return false to disallow object to be selected for mapping.
map: (def, args) ->
args = _.map((if typeof(args) is "string" then args.split("/") else args), (a) -> a.split(","))
for arg, idx in args
do (arg, idx) ->
if def[idx]?
if typeof(def[idx]) is "string" # for my beatiful and simple argument construction technique
origin = "mapi"
typeProperty = def[idx]
# may contain information about origin
if typeProperty.indexOf("#") > 0 then [origin, typeProperty] = def[idx].split("#")
[type, property] = typeProperty.split(".")
{
origin: origin
type: type
property: property
currentvalue: arg
depth: 1
}
else if typeof(def[idx]) is "object" # for generic lists etc
original = JSON.parse(arg)
schematic =
for pKey, pTypeSelector of def[idx]
do (pKey, pTypeSelector) ->
# get current value
currentvalue = original[pKey]
if typeof(pTypeSelector) is "string"
[pType, pSelector] = pTypeSelector.split(".") # nb. we only support immediate properties
{
origin: "mapi"
type: pType
property: pSelector
currentvalue: currentvalue
key: pKey
depth: 1
}
else # assume pTypeSelector is object
{
origin: "mapi"
type: pTypeSelector.type
property: pTypeSelector.property
currentvalue: currentvalue
key: pKey
depth: pTypeSelector.depth
hql: pTypeSelector.hql
filter: pTypeSelector.filter
}
schematic.original = original
# return schematic
schematic
else # no def given
{
origin: "fixed"
currentvalue: arg
}
applySchema: (method, action, fun, schema) -> @unmap(schema)
exports.mapper = Mapper