Air tasker from schema compiler
Helps your create a security (sandbox) custom form.

Installation
npm install --save @airtasker/form-schema-compiler
This assumes that you’re using npm package manager with a module bundler like Webpack or Browserify to consume CommonJS modules.
If you don’t yet use npm or a modern module bundler, and would rather prefer a single-file UMD build that makes FormSchemaCompiler
available as a global object.
Documentation
compileComponents(schema, [options]):AST
Compile an airtasker form schema to an AST (abstract structure tree).
Arguments
schema
: Airtaker form schemaoptions
: { typeCompilers
}
typeCompilers
: { [TYPE
]: createCompiler()
:{[before(schema)
], [after(AST)
]}}: you can add custom components compiler. it have high priority than default components compiler.
apply(ast, options):any
Apply an AST.
Arguments
const
a const file
export const TYPES = {
Numeric: "Numeric",
String: "String",
Boolean: "Boolean",
Object: "Object",
Array: "Array",
Null: "Null",
RegExp: "RegExp",
Identifier: "Identifier",
Keyword: 'Keyword',
AssignExpression: "AssignExpression",
ObjectExpression: "ObjectExpression",
ObjectProperty: "ObjectProperty",
ArrayExpression: "ArrayExpression",
BinaryExpression: "BinaryExpression",
UnaryExpression: "UnaryExpression",
CallExpression: "CallExpression",
TemplateLiteral: "TemplateLiteral",
MemberExpression: "MemberExpression",
IfStatement: "IfStatement",
Components: "Components",
Operator: "Operator",
Punctuation: "Punctuation",
Raw: "Raw",
Program: 'Program',
BlockStatement: 'BlockStatement',
PropertyBinding: 'PropertyBinding',
EventBinding: 'EventBinding',
};
export const PRIMITIVES = [
TYPES.Numeric,
TYPES.String,
TYPES.Boolean,
TYPES.Null
];
export const OBJECTS = [TYPES.RegExp, TYPES.Identifier, TYPES.Component];
export const EXPRESSIONS = [
TYPES.ObjectExpression,
TYPES.ArrayExpression,
TYPES.BinaryExpression,
TYPES.AssignExpression,
TYPES.CallExpression,
TYPES.UnaryExpression,
TYPES.TemplateLiteral,
];
export const OPERATORS = {
Assign: "=",
Add: "+",
Subtract: "-",
Multiply: "*",
Remainder: "%",
Divide: "/",
GreaterThan: ">",
GreaterThanOrEqualTo: ">=",
LessThan: "<",
LessThanOrEqualTo: "<=",
EqualTo: "is",
NotEqualTo: "isnt",
And: "and",
Or: "or",
Match: "match",
Not: "not"
};
export const PRECEDENCE = {
[OPERATORS.Assign]: 1,
[OPERATORS.Or]: 2,
[OPERATORS.And]: 3,
[OPERATORS.GreaterThan]: 7,
[OPERATORS.GreaterThanOrEqualTo]: 7,
[OPERATORS.LessThan]: 7,
[OPERATORS.LessThanOrEqualTo]: 7,
[OPERATORS.EqualTo]: 7,
[OPERATORS.NotEqualTo]: 7,
[OPERATORS.Match]: 7,
[OPERATORS.Add]: 10,
[OPERATORS.Subtract]: 10,
[OPERATORS.Multiply]: 20,
[OPERATORS.Divide]: 20,
[OPERATORS.Remainder]: 20
};
export const BOOLEANS = ["false", "true"];
export const IF_KEYWORDS = {
If: 'if',
Else: 'else',
Then: 'then'
}
export const KEYWORDS = [...BOOLEANS, ...Object.values(IF_KEYWORDS)];
export const PUNCTUATIONS = {
Braces: ["{", "}"],
SquareBrackets: ["[", "]"],
Parentheses: ["(", ")"],
Separator: ",",
Colon: ":",
BackQuote: "`",
SemiColon: ";",
};
export const ANNOTATION_TYPES = {
[TYPES.PropertyBinding]: TYPES.PropertyBinding,
[TYPES.EventBinding]: TYPES.EventBinding,
Template: "Template",
Components: "Components",
TwoWayBinding: "TwoWayBinding"
};
export const ANNOTATIONS = {
[ANNOTATION_TYPES.PropertyBinding]: ["{", "}"],
[ANNOTATION_TYPES.Template]: ["#", "#"],
[ANNOTATION_TYPES.Components]: ["<", ">"],
[ANNOTATION_TYPES.EventBinding]: ["(", ")"],
[ANNOTATION_TYPES.TwoWayBinding]: ["[", "]"]
};
Schema
Airtasker form schema using JSON schema.
Annotation
-
key
: no annotation, compile as json
compile
{
key: "1",
key2: 1,
key3: null,
key4: true,
key5: [],
key6: {}
}
to
{
key: {type: "String", value: "1"},
key2: {type: "Number", value: 1},
key3: {type: "Null", value: null},
key4: {type: "Boolean", value: true},
key5: {type: "Array", value: []},
key6: {type: "Object", value: {}}
}
-
<key>
: component annotation
compile
{"<key>": {/*component schema*/}}
to
{"key": {/*component ast*/}}
-
[key]
: two way data binding
compile
{"[key]": "foo"}
to
{"key": { type: "identifier", name: "foo" }
-
#key#
: string template
compile
{"#key#": "foo{"bar"}"}
to
{
"key": {
type: "BinaryExpression",
left: { type: "String", value: "foo" },
operator: "+",
right: {
type: "callExpression",
callee: { type: "identifier", name: "toString" },
arguments: [{ type: "identifier", name: "bar" }]
}
}
}
-
{key}
: expression
compile
{
"{key}": "1 + 2",
"{key2}": "{k: 1, date: dueDate}"
}
to
{
"key": {
type: "BinaryExpression",
left: { type: "Numeric", value: "1" },
operator: "+",
right: { type: "Numeric", value: "2" },
}
}
-
(key)
: event binding, eventValue is a special identifier that's reference the action callback value
compile
{"(click)": "doAction(eventValue)"}
to
{
"onClick": {
type: "callExpression",
callee: { type: "identifier", name: "doAction" },
arguments: [{ type: "identifier", name: "eventValue" }]
}
}
License
MIT