pickpick-targeting-compiler

compiles targeting expressions for pickpick engine

Usage no npm install needed!

<script type="module">
  import pickpickTargetingCompiler from 'https://cdn.skypack.dev/pickpick-targeting-compiler';
</script>

README

pickpick-targeting-compiler

compiles targeting expressions to javascript code for pickpick engine

  • uses jsep to parse expressions and turn them into a javascript function that evaluates a conditiongiven a certain input.
  • uses the vm module to have isolated context
  • in addition to normal javascript operators, there are some special operators (see below for example):
    • in is exactly Array.includes
    • match regexp test
    • startsWith and endsWith is exactly String.startsWith and String.endsWith respectively
  • exposes a bunch of useful is* functions from util module
  • open for extension via user defined envinronment accessible using $

example

npm i pickpick-targeting-compiler

const assert = require('assert')
const compile = require('pickpick-targeting-compiler')

// intentionally using var here 

// all normal js operators apply
var { isMatch, features } = compile('_.geo === "US"')
assert(isMatch({ geo: 'US' }))

var { isMatch, features } = compile('_.number >= 0')
assert(isMatch({ number: 1 }))
assert(isMatch({ number: 2 }))
assert(isMatch({ number: 3 }))

// can create compound logical statements
var { isMatch, features } = compile('_.geo === "US" && _.number > 5')
assert(isMatch({ geo: 'US', number: 8 }))

// in operator - same as Array.includes(value)
var { isMatch, features } = compile('_.geo in ["US", "MX"]')
assert(isMatch({ geo: 'US' }))

// operators apply to context data as well
var { isMatch, features } = compile('_.geo in _.page')
assert(isMatch({ geo: 'US', page: ["US", "MX"] }))

// startsWith operator - same as String.startsWith(string)
var { isMatch, features } = compile('_.geo startsWith "x"')
assert(isMatch({ geo: 'xyz' }))

// endsWith operator - same as String.endsWith(string)
var { isMatch, features } = compile('_.geo endsWith "z"')
assert(isMatch({ geo: 'xyz' }))

// match operator for literal regular expressions, same as /regex/g.test('value')
var { isMatch, features } = compile('_.geo match "[0-9]"')
assert(isMatch({ geo: 0 }))

// deeplyEquals operator performs a deep equal comparison (uses [lodash.isEqual](https://lodash.com/docs/4.17.10#isEqual))
var { isMatch, features } = compile('_.geo deeplyEquals [1, 2, 3]')
assert(isMatch({ geo: [1, 2, 3] }))

// exposes a bunch of isSomething from util:
// isNullOrUndefined,
// isNull,
// isUndefined,
// isString,
// isNumber,
// isArray,
// isObject,
// isBoolean,
// isDate,
// isNull,
// isPrimitive
var { isMatch, features } = compile('isNumber(_.geo)')
assert(isMatch({ geo: 0 }))

// provide user defined functions and data
const userEnvironment = { x: [1, 2, 3], isOk: (arg) => arg.startsWith('x') }
var { isMatch, features } = compile('_.geo in $.x && $.isOk(_.page)', { userEnvironment })
assert(isMatch({ geo: 1, page: 'x.html' }))

api

Table of Contents

compile

index.js:56-156

Compile an expression into a resuable javascript function

Parameters

  • expression String any expression that can be parsed by jsep
  • options Object (optional, default {})
    • options.matcherProperty String return the match function using a different property name in the compound return value, e.g: (optional, default 'isMatch')
    • options.userEnvironment Object allows the user to inject additional functionality that will be exposed to the expression. e.g: (optional, default {})
    • options.userEnvNamespace String change the name used to access user environment in an expression (optional, default $)
    • options.inputNamespace String change the name used to access input in the expression (optional, default _)

Examples

// options.matcherProperty
 
   // normally this would be isMatch instead of 'foo'
   let { foo } = compile('_.geo === "1"', { matcherProperty: 'foo' })
// options.userEnvironment
   
   let userEnvironment = {
        geos: ['MX', 'US', 'IL'],
        format: value => value.toUpperCase()
   }
   
   let { isMatch } = compile('$.format(_.geo) in $.geos', { userEnvironment })

Returns Function a function that accepts input and returns a boolean value

license

MIT © ironSource LTD