commit
f493ee1cec
|
@ -238,15 +238,42 @@ export default class Walker {
|
|||
})
|
||||
}
|
||||
|
||||
private constructObject(value) {
|
||||
const propArray = _.get(value, 'properties', [])
|
||||
const valueObj = propArray.reduce((acc, p) => {
|
||||
return {...acc, [p.key.name]: p.value.name}
|
||||
}, {})
|
||||
return valueObj
|
||||
}
|
||||
|
||||
private constructArray(value) {
|
||||
const elementsArray = _.get(value, 'elements', [])
|
||||
const valueArray = elementsArray.reduce((acc, e) => {
|
||||
return [...acc, e.value]
|
||||
}, [])
|
||||
return valueArray
|
||||
}
|
||||
|
||||
private getProperties = props => {
|
||||
return props.map(prop => ({
|
||||
key: prop.key.name,
|
||||
value: _.get(
|
||||
prop,
|
||||
'value.value',
|
||||
_.get(prop, 'value.location.source', '')
|
||||
),
|
||||
}))
|
||||
return props.map(prop => {
|
||||
const key = prop.key.name
|
||||
let value
|
||||
if (_.get(prop, 'value.type', '') === 'ObjectExpression') {
|
||||
value = this.constructObject(prop.value)
|
||||
} else if (_.get(prop, 'value.type', '') === 'ArrayExpression') {
|
||||
value = this.constructArray(prop.value)
|
||||
} else {
|
||||
value = _.get(
|
||||
prop,
|
||||
'value.value',
|
||||
_.get(prop, 'value.location.source', '')
|
||||
)
|
||||
}
|
||||
return {
|
||||
key,
|
||||
value,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private get baseExpression() {
|
||||
|
|
|
@ -35,6 +35,7 @@ class BodyBuilder extends PureComponent<Props> {
|
|||
declarationID={d.id}
|
||||
funcNames={this.funcNames}
|
||||
funcs={d.funcs}
|
||||
declarationsFromBody={this.declarationsFromBody}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
@ -54,6 +55,7 @@ class BodyBuilder extends PureComponent<Props> {
|
|||
bodyID={b.id}
|
||||
funcs={b.funcs}
|
||||
funcNames={this.funcNames}
|
||||
declarationsFromBody={this.declarationsFromBody}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
@ -84,6 +86,20 @@ class BodyBuilder extends PureComponent<Props> {
|
|||
return declarationFunctions
|
||||
}
|
||||
|
||||
private get declarationsFromBody(): string[] {
|
||||
const {body} = this.props
|
||||
const declarations = _.flatten(
|
||||
body.map(b => {
|
||||
if ('declarations' in b) {
|
||||
const declarationsArray = b.declarations
|
||||
return declarationsArray.map(da => da.name)
|
||||
}
|
||||
return []
|
||||
})
|
||||
)
|
||||
return declarations
|
||||
}
|
||||
|
||||
private createNewBody = name => {
|
||||
if (name === funcNames.FROM) {
|
||||
this.props.onAppendFrom()
|
||||
|
|
|
@ -11,12 +11,19 @@ interface Props {
|
|||
bodyID: string
|
||||
funcs: Func[]
|
||||
declarationID?: string
|
||||
declarationsFromBody: string[]
|
||||
}
|
||||
|
||||
// an Expression is a group of one or more functions
|
||||
class ExpressionNode extends PureComponent<Props> {
|
||||
public render() {
|
||||
const {declarationID, bodyID, funcNames, funcs} = this.props
|
||||
const {
|
||||
declarationID,
|
||||
bodyID,
|
||||
funcNames,
|
||||
funcs,
|
||||
declarationsFromBody,
|
||||
} = this.props
|
||||
return (
|
||||
<IFQLContext.Consumer>
|
||||
{({
|
||||
|
@ -38,6 +45,7 @@ class ExpressionNode extends PureComponent<Props> {
|
|||
onDelete={onDeleteFuncNode}
|
||||
declarationID={declarationID}
|
||||
onGenerateScript={onGenerateScript}
|
||||
declarationsFromBody={declarationsFromBody}
|
||||
/>
|
||||
))}
|
||||
<FuncSelector
|
||||
|
|
|
@ -15,7 +15,7 @@ interface Props {
|
|||
funcName: string
|
||||
funcID: string
|
||||
argKey: string
|
||||
value: string | boolean
|
||||
value: string | boolean | {[x: string]: string}
|
||||
type: string
|
||||
bodyID: string
|
||||
declarationID: string
|
||||
|
|
|
@ -19,10 +19,10 @@ interface State {
|
|||
}
|
||||
|
||||
@ErrorHandling
|
||||
class FuncArgInput extends PureComponent<Props, State> {
|
||||
class FuncArgTextArea extends PureComponent<Props, State> {
|
||||
private ref: React.RefObject<HTMLTextAreaElement>
|
||||
|
||||
constructor(props) {
|
||||
constructor(props: Props) {
|
||||
super(props)
|
||||
this.ref = React.createRef()
|
||||
this.state = {
|
||||
|
@ -99,4 +99,4 @@ class FuncArgInput extends PureComponent<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
export default FuncArgInput
|
||||
export default FuncArgTextArea
|
||||
|
|
|
@ -4,6 +4,7 @@ import {OnChangeArg} from 'src/types/ifql'
|
|||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
import {Func} from 'src/types/ifql'
|
||||
import {funcNames} from 'src/ifql/constants'
|
||||
import Join from 'src/ifql/components/Join'
|
||||
import {Service} from 'src/types'
|
||||
|
||||
interface Props {
|
||||
|
@ -14,6 +15,7 @@ interface Props {
|
|||
declarationID: string
|
||||
onGenerateScript: () => void
|
||||
onDeleteFunc: () => void
|
||||
declarationsFromBody: string[]
|
||||
}
|
||||
|
||||
@ErrorHandling
|
||||
|
@ -27,27 +29,37 @@ export default class FuncArgs extends PureComponent<Props> {
|
|||
onDeleteFunc,
|
||||
declarationID,
|
||||
onGenerateScript,
|
||||
declarationsFromBody,
|
||||
} = this.props
|
||||
|
||||
const {name: funcName, id: funcID} = func
|
||||
return (
|
||||
<div className="func-node--tooltip">
|
||||
{func.args.map(({key, value, type}) => {
|
||||
return (
|
||||
{funcName === funcNames.JOIN ? (
|
||||
<Join
|
||||
func={func}
|
||||
bodyID={bodyID}
|
||||
declarationID={declarationID}
|
||||
onChangeArg={onChangeArg}
|
||||
declarationsFromBody={declarationsFromBody}
|
||||
onGenerateScript={onGenerateScript}
|
||||
/>
|
||||
) : (
|
||||
func.args.map(({key, value, type}) => (
|
||||
<FuncArg
|
||||
key={key}
|
||||
type={type}
|
||||
argKey={key}
|
||||
value={value}
|
||||
bodyID={bodyID}
|
||||
funcID={func.id}
|
||||
funcID={funcID}
|
||||
funcName={funcName}
|
||||
service={service}
|
||||
funcName={func.name}
|
||||
onChangeArg={onChangeArg}
|
||||
declarationID={declarationID}
|
||||
onGenerateScript={onGenerateScript}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
))
|
||||
)}
|
||||
<div className="func-node--buttons">
|
||||
<div
|
||||
className="btn btn-sm btn-danger func-node--delete"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React, {PureComponent} from 'react'
|
||||
import uuid from 'uuid'
|
||||
import _ from 'lodash'
|
||||
|
||||
import {Func} from 'src/types/ifql'
|
||||
|
@ -6,7 +7,7 @@ import {funcNames} from 'src/ifql/constants'
|
|||
import Filter from 'src/ifql/components/Filter'
|
||||
import FilterPreview from 'src/ifql/components/FilterPreview'
|
||||
|
||||
import uuid from 'uuid'
|
||||
import {getDeep} from 'src/utils/wrappers'
|
||||
|
||||
interface Props {
|
||||
func: Func
|
||||
|
@ -26,7 +27,7 @@ export default class FuncArgsPreview extends PureComponent<Props> {
|
|||
}
|
||||
|
||||
if (func.name === funcNames.FILTER) {
|
||||
const value = _.get(args, '0.value', '')
|
||||
const value = getDeep<string>(args, '0.value', '')
|
||||
if (!value) {
|
||||
return this.colorizedArguments
|
||||
}
|
||||
|
@ -51,11 +52,18 @@ export default class FuncArgsPreview extends PureComponent<Props> {
|
|||
}
|
||||
|
||||
const separator = i === 0 ? null : ', '
|
||||
let argValue
|
||||
if (arg.type === 'object') {
|
||||
const valueMap = _.map(arg.value, (value, key) => `${key}:${value}`)
|
||||
argValue = `{${valueMap.join(', ')}}`
|
||||
} else {
|
||||
argValue = `${arg.value}`
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment key={uuid.v4()}>
|
||||
{separator}
|
||||
{arg.key}: {this.colorArgType(`${arg.value}`, arg.type)}
|
||||
{arg.key}: {this.colorArgType(argValue, arg.type)}
|
||||
</React.Fragment>
|
||||
)
|
||||
})
|
||||
|
@ -76,6 +84,9 @@ export default class FuncArgsPreview extends PureComponent<Props> {
|
|||
case 'string': {
|
||||
return <span className="variable-value--string">"{argument}"</span>
|
||||
}
|
||||
case 'object': {
|
||||
return <span className="variable-value--object">{argument}</span>
|
||||
}
|
||||
case 'invalid': {
|
||||
return <span className="variable-value--invalid">{argument}</span>
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ interface Props {
|
|||
onDelete: OnDeleteFuncNode
|
||||
onChangeArg: OnChangeArg
|
||||
onGenerateScript: () => void
|
||||
declarationsFromBody: string[]
|
||||
}
|
||||
|
||||
interface State {
|
||||
|
@ -41,6 +42,7 @@ export default class FuncNode extends PureComponent<Props, State> {
|
|||
onChangeArg,
|
||||
declarationID,
|
||||
onGenerateScript,
|
||||
declarationsFromBody,
|
||||
} = this.props
|
||||
const {isExpanded} = this.state
|
||||
|
||||
|
@ -61,6 +63,7 @@ export default class FuncNode extends PureComponent<Props, State> {
|
|||
declarationID={declarationID}
|
||||
onGenerateScript={onGenerateScript}
|
||||
onDeleteFunc={this.handleDelete}
|
||||
declarationsFromBody={declarationsFromBody}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
import React, {PureComponent} from 'react'
|
||||
import _ from 'lodash'
|
||||
|
||||
import Dropdown from 'src/shared/components/Dropdown'
|
||||
import FuncArgInput from 'src/ifql/components/FuncArgInput'
|
||||
import FuncArgTextArea from 'src/ifql/components/FuncArgTextArea'
|
||||
import {getDeep} from 'src/utils/wrappers'
|
||||
|
||||
import {OnChangeArg, Func, Arg} from 'src/types/ifql'
|
||||
import {argTypes} from 'src/ifql/constants'
|
||||
|
||||
interface Props {
|
||||
func: Func
|
||||
bodyID: string
|
||||
declarationID: string
|
||||
onChangeArg: OnChangeArg
|
||||
declarationsFromBody: string[]
|
||||
onGenerateScript: () => void
|
||||
}
|
||||
|
||||
interface DropdownItem {
|
||||
text: string
|
||||
}
|
||||
|
||||
class Join extends PureComponent<Props> {
|
||||
constructor(props: Props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {
|
||||
func,
|
||||
bodyID,
|
||||
onChangeArg,
|
||||
declarationID,
|
||||
onGenerateScript,
|
||||
} = this.props
|
||||
return (
|
||||
<>
|
||||
<div className="func-arg">
|
||||
<label className="func-arg--label">tables</label>
|
||||
<Dropdown
|
||||
selected={this.table1Value}
|
||||
className="from--dropdown dropdown-100 func-arg--value"
|
||||
menuClass="dropdown-astronaut"
|
||||
buttonColor="btn-default"
|
||||
items={this.items}
|
||||
onChoose={this.handleChooseTable1}
|
||||
/>
|
||||
<Dropdown
|
||||
selected={this.table2Value}
|
||||
className="from--dropdown dropdown-100 func-arg--value"
|
||||
menuClass="dropdown-astronaut"
|
||||
buttonColor="btn-default"
|
||||
items={this.items}
|
||||
onChoose={this.handleChooseTable2}
|
||||
/>
|
||||
</div>
|
||||
<div className="func-arg">
|
||||
<FuncArgInput
|
||||
value={this.onValue}
|
||||
argKey={'on'}
|
||||
bodyID={bodyID}
|
||||
funcID={func.id}
|
||||
type={argTypes.STRING}
|
||||
onChangeArg={onChangeArg}
|
||||
declarationID={declarationID}
|
||||
onGenerateScript={onGenerateScript}
|
||||
/>
|
||||
</div>
|
||||
<div className="func-arg">
|
||||
<FuncArgTextArea
|
||||
type={argTypes.FUNCTION}
|
||||
value={this.fnValue}
|
||||
argKey={'fn'}
|
||||
funcID={func.id}
|
||||
bodyID={bodyID}
|
||||
onChangeArg={onChangeArg}
|
||||
declarationID={declarationID}
|
||||
onGenerateScript={onGenerateScript}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
private handleChooseTable1 = (item: DropdownItem): void => {
|
||||
this.handleChooseTables(item.text, this.table2Value)
|
||||
}
|
||||
|
||||
private handleChooseTable2 = (item: DropdownItem): void => {
|
||||
this.handleChooseTables(this.table1Value, item.text)
|
||||
}
|
||||
|
||||
private handleChooseTables = (table1: string, table2: string): void => {
|
||||
const {
|
||||
onChangeArg,
|
||||
bodyID,
|
||||
declarationID,
|
||||
func,
|
||||
onGenerateScript,
|
||||
} = this.props
|
||||
|
||||
onChangeArg({
|
||||
funcID: func.id,
|
||||
bodyID,
|
||||
declarationID,
|
||||
key: 'tables',
|
||||
value: {[table1]: table1, [table2]: table2},
|
||||
generate: true,
|
||||
})
|
||||
onGenerateScript()
|
||||
}
|
||||
|
||||
private get items(): DropdownItem[] {
|
||||
return this.props.declarationsFromBody.map(d => ({text: d}))
|
||||
}
|
||||
|
||||
private get argsArray(): Arg[] {
|
||||
const {func} = this.props
|
||||
return getDeep<Arg[]>(func, 'args', [])
|
||||
}
|
||||
|
||||
private get onValue(): string {
|
||||
const onObject = this.argsArray.find(a => a.key === 'on')
|
||||
return onObject.value.toString()
|
||||
}
|
||||
|
||||
private get fnValue(): string {
|
||||
const fnObject = this.argsArray.find(a => a.key === 'fn')
|
||||
return fnObject.value.toString()
|
||||
}
|
||||
|
||||
private get table1Value(): string {
|
||||
const tables = this.argsArray.find(a => a.key === 'tables')
|
||||
if (tables) {
|
||||
const keys = _.keys(tables.value)
|
||||
return getDeep<string>(keys, '0', '')
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
private get table2Value(): string {
|
||||
const tables = this.argsArray.find(a => a.key === 'tables')
|
||||
|
||||
if (tables) {
|
||||
const keys = _.keys(tables.value)
|
||||
return getDeep<string>(keys, '1', getDeep<string>(keys, '0', ''))
|
||||
}
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
export default Join
|
|
@ -1,2 +1,2 @@
|
|||
export const NEW_FROM = `from(db: "pick a db")\n\t|> filter(fn: (r) => r.tag == "value")\n\t|> range(start: -1m)`
|
||||
export const NEW_JOIN = `join(tables: {fil:fil, tele:tele}, on:["host"], fn: (tables) => tables.fil["_value"] + tables.tele["_value"])`
|
||||
export const NEW_JOIN = `join(tables:{fil:fil, tele:tele}, on:["host"], fn:(tables) => tables.fil["_value"] + tables.tele["_value"])`
|
||||
|
|
|
@ -14,7 +14,7 @@ import {UpdateScript} from 'src/ifql/actions'
|
|||
|
||||
import {bodyNodes} from 'src/ifql/helpers'
|
||||
import {getSuggestions, getAST, getTimeSeries} from 'src/ifql/apis'
|
||||
import {funcNames, builder, argTypes} from 'src/ifql/constants'
|
||||
import {builder, argTypes} from 'src/ifql/constants'
|
||||
|
||||
import {Source, Service, Notification, ScriptResult} from 'src/types'
|
||||
import {
|
||||
|
@ -225,7 +225,7 @@ export class IFQLPage extends PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
if (!declaration.funcs) {
|
||||
return `${acc}${b.source}\n\n`
|
||||
return `${acc}${b.source}`
|
||||
}
|
||||
|
||||
return `${acc}${declaration.name} = ${this.funcsToScript(
|
||||
|
@ -253,7 +253,12 @@ export class IFQLPage extends PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
if (type === argTypes.ARRAY) {
|
||||
return `${key}: [${value}]`
|
||||
return `${key}: ["${value}"]`
|
||||
}
|
||||
|
||||
if (type === argTypes.OBJECT) {
|
||||
const valueString = _.map(value, (v, k) => k + ':' + v).join(',')
|
||||
return `${key}: {${valueString}}`
|
||||
}
|
||||
|
||||
return `${key}: ${value}`
|
||||
|
@ -402,20 +407,7 @@ export class IFQLPage extends PureComponent<Props, State> {
|
|||
|
||||
try {
|
||||
const ast = await getAST({url: links.ast, body: script})
|
||||
const suggestions = this.state.suggestions.map(s => {
|
||||
if (s.name === funcNames.JOIN) {
|
||||
return {
|
||||
...s,
|
||||
params: {
|
||||
tables: 'object',
|
||||
on: 'array',
|
||||
fn: 'function',
|
||||
},
|
||||
}
|
||||
}
|
||||
return s
|
||||
})
|
||||
const body = bodyNodes(ast, suggestions)
|
||||
const body = bodyNodes(ast, this.state.suggestions)
|
||||
const status = {type: 'success', text: ''}
|
||||
this.setState({ast, body, status})
|
||||
this.props.updateScript(script)
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import uuid from 'uuid'
|
||||
import _ from 'lodash'
|
||||
|
||||
import Walker from 'src/ifql/ast/walker'
|
||||
import {FlatBody, Func} from 'src/types/ifql'
|
||||
|
||||
import {FlatBody, Func, Suggestion} from 'src/types/ifql'
|
||||
|
||||
interface Body extends FlatBody {
|
||||
id: string
|
||||
}
|
||||
|
||||
export const bodyNodes = (ast, suggestions): Body[] => {
|
||||
export const bodyNodes = (ast, suggestions: Suggestion[]): Body[] => {
|
||||
if (!ast) {
|
||||
return []
|
||||
}
|
||||
|
@ -47,11 +49,12 @@ export const bodyNodes = (ast, suggestions): Body[] => {
|
|||
return body
|
||||
}
|
||||
|
||||
const functions = (funcs, suggestions): Func[] => {
|
||||
const functions = (funcs: Func[], suggestions: Suggestion[]): Func[] => {
|
||||
const funcList = funcs.map(func => {
|
||||
const suggestion = suggestions.find(f => f.name === func.name)
|
||||
if (!suggestion) {
|
||||
return {
|
||||
type: func.type,
|
||||
id: uuid.v4(),
|
||||
source: func.source,
|
||||
name: func.name,
|
||||
|
@ -61,7 +64,8 @@ const functions = (funcs, suggestions): Func[] => {
|
|||
|
||||
const {params, name} = suggestion
|
||||
const args = Object.entries(params).map(([key, type]) => {
|
||||
const value = _.get(func.args.find(arg => arg.key === key), 'value', '')
|
||||
const argWithKey = func.args.find(arg => arg.key === key)
|
||||
const value = _.get(argWithKey, 'value', '')
|
||||
|
||||
return {
|
||||
key,
|
||||
|
@ -71,6 +75,7 @@ const functions = (funcs, suggestions): Func[] => {
|
|||
})
|
||||
|
||||
return {
|
||||
type: func.type,
|
||||
id: uuid.v4(),
|
||||
source: func.source,
|
||||
name,
|
||||
|
|
|
@ -59,6 +59,10 @@ export const modeIFQL = {
|
|||
regex: /0x[a-f\d]+|[-+]?(?:\.\d+|\d+\.?\d*)(?:e[-+]?\d+)?/i,
|
||||
token: 'number',
|
||||
},
|
||||
{
|
||||
regex: /({.+:.+})/,
|
||||
token: 'object',
|
||||
},
|
||||
{
|
||||
regex: /\/\/.*/,
|
||||
token: 'comment',
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
.cm-boolean {
|
||||
color: $c-viridian;
|
||||
}
|
||||
.cm-object {
|
||||
color: $c-honeydew;
|
||||
}
|
||||
.cm-null {
|
||||
color: $c-dreamsicle;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ $ifql-node-gap: 5px;
|
|||
$ifql-node-padding: 10px;
|
||||
$ifql-arg-min-width: 120px;
|
||||
$ifql-number-color: $c-neutrino;
|
||||
$ifql-object-color: $c-viridian;
|
||||
$ifql-string-color: $c-honeydew;
|
||||
$ifql-boolean-color: $c-viridian;
|
||||
$ifql-invalid-color: $c-viridian;
|
||||
|
@ -76,6 +77,10 @@ $ifql-invalid-color: $c-viridian;
|
|||
color: $ifql-number-color;
|
||||
}
|
||||
|
||||
.variable-value--object {
|
||||
color: $ifql-object-color;
|
||||
}
|
||||
|
||||
.variable-value--invalid {
|
||||
color: $ifql-invalid-color;
|
||||
}
|
||||
|
@ -257,16 +262,16 @@ $ifql-filter-parens: $g5-pepper;
|
|||
padding: 0 ($ifql-filter-gap / 2);
|
||||
}
|
||||
|
||||
.ifql-filter--value+.ifql-filter--operator,
|
||||
.ifql-filter--paren-close+.ifql-filter--operator {
|
||||
.ifql-filter--value + .ifql-filter--operator,
|
||||
.ifql-filter--paren-close + .ifql-filter--operator {
|
||||
padding: 0 $ifql-filter-gap;
|
||||
}
|
||||
|
||||
.ifql-filter--key+.ifql-filter--operator {
|
||||
.ifql-filter--key + .ifql-filter--operator {
|
||||
background-color: $ifql-filter-expression;
|
||||
}
|
||||
|
||||
.ifql-filter--key+.ifql-filter--operator+.ifql-filter--value {
|
||||
.ifql-filter--key + .ifql-filter--operator + .ifql-filter--value {
|
||||
background-color: $ifql-filter-expression;
|
||||
border-radius: 0 3px 3px 0;
|
||||
}
|
||||
|
@ -291,7 +296,8 @@ $ifql-filter-parens: $g5-pepper;
|
|||
height: $ifql-filter-unit-wrapped;
|
||||
width: ($ifql-filter-unit-wrapped - $ifql-filter-unit) / 2;
|
||||
background-color: $ifql-filter-parens;
|
||||
border: (($ifql-filter-unit-wrapped - $ifql-filter-unit) / 2) solid $ifql-filter-expression;
|
||||
border: (($ifql-filter-unit-wrapped - $ifql-filter-unit) / 2) solid
|
||||
$ifql-filter-expression;
|
||||
}
|
||||
|
||||
.ifql-filter--paren-open {
|
||||
|
|
|
@ -37,7 +37,7 @@ export interface InputArg {
|
|||
bodyID: string
|
||||
declarationID?: string
|
||||
key: string
|
||||
value: string | boolean
|
||||
value: string | boolean | {[x: string]: string}
|
||||
generate?: boolean
|
||||
}
|
||||
|
||||
|
@ -80,11 +80,11 @@ export interface Func {
|
|||
id: string
|
||||
}
|
||||
|
||||
type Value = string | boolean
|
||||
export type Arg = ArgString
|
||||
|
||||
export interface Arg {
|
||||
export interface ArgString {
|
||||
key: string
|
||||
value: Value
|
||||
value: string
|
||||
type: string
|
||||
}
|
||||
|
||||
|
|
|
@ -345,3 +345,516 @@ export const Fork = {
|
|||
},
|
||||
],
|
||||
}
|
||||
|
||||
export const JoinWithObjectArg = {
|
||||
type: 'Program',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 1,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 106,
|
||||
},
|
||||
source:
|
||||
'join(tables:{cpu:cpu, mem:mem}, on:["host"], fn: (tables) => tables.cpu["_value"] + tables.mem["_value"])',
|
||||
},
|
||||
body: [
|
||||
{
|
||||
type: 'ExpressionStatement',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 1,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 106,
|
||||
},
|
||||
source:
|
||||
'join(tables:{cpu:cpu, mem:mem}, on:["host"], fn: (tables) => tables.cpu["_value"] + tables.mem["_value"])',
|
||||
},
|
||||
expression: {
|
||||
type: 'CallExpression',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 1,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 106,
|
||||
},
|
||||
source:
|
||||
'join(tables:{cpu:cpu, mem:mem}, on:["host"], fn: (tables) => tables.cpu["_value"] + tables.mem["_value"])',
|
||||
},
|
||||
callee: {
|
||||
type: 'Identifier',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 1,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 5,
|
||||
},
|
||||
source: 'join',
|
||||
},
|
||||
name: 'join',
|
||||
},
|
||||
arguments: [
|
||||
{
|
||||
type: 'ObjectExpression',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 6,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 105,
|
||||
},
|
||||
source:
|
||||
'tables:{cpu:cpu, mem:mem}, on:["host"], fn: (tables) => tables.cpu["_value"] + tables.mem["_value"]',
|
||||
},
|
||||
properties: [
|
||||
{
|
||||
type: 'Property',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 6,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 31,
|
||||
},
|
||||
source: 'tables:{cpu:cpu, mem:mem}',
|
||||
},
|
||||
key: {
|
||||
type: 'Identifier',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 6,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 12,
|
||||
},
|
||||
source: 'tables',
|
||||
},
|
||||
name: 'tables',
|
||||
},
|
||||
value: {
|
||||
type: 'ObjectExpression',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 14,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 30,
|
||||
},
|
||||
source: 'cpu:cpu, mem:mem',
|
||||
},
|
||||
properties: [
|
||||
{
|
||||
type: 'Property',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 14,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 21,
|
||||
},
|
||||
source: 'cpu:cpu',
|
||||
},
|
||||
key: {
|
||||
type: 'Identifier',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 14,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 17,
|
||||
},
|
||||
source: 'cpu',
|
||||
},
|
||||
name: 'cpu',
|
||||
},
|
||||
value: {
|
||||
type: 'Identifier',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 18,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 21,
|
||||
},
|
||||
source: 'cpu',
|
||||
},
|
||||
name: 'cpu',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'Property',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 23,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 30,
|
||||
},
|
||||
source: 'mem:mem',
|
||||
},
|
||||
key: {
|
||||
type: 'Identifier',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 23,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 26,
|
||||
},
|
||||
source: 'mem',
|
||||
},
|
||||
name: 'mem',
|
||||
},
|
||||
value: {
|
||||
type: 'Identifier',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 27,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 30,
|
||||
},
|
||||
source: 'mem',
|
||||
},
|
||||
name: 'mem',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'Property',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 33,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 44,
|
||||
},
|
||||
source: 'on:["host"]',
|
||||
},
|
||||
key: {
|
||||
type: 'Identifier',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 33,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 35,
|
||||
},
|
||||
source: 'on',
|
||||
},
|
||||
name: 'on',
|
||||
},
|
||||
value: {
|
||||
type: 'ArrayExpression',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 37,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 43,
|
||||
},
|
||||
source: '"host"',
|
||||
},
|
||||
elements: [
|
||||
{
|
||||
type: 'StringLiteral',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 37,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 43,
|
||||
},
|
||||
source: '"host"',
|
||||
},
|
||||
value: 'host',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'Property',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 46,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 105,
|
||||
},
|
||||
source:
|
||||
'fn: (tables) => tables.cpu["_value"] + tables.mem["_value"]',
|
||||
},
|
||||
key: {
|
||||
type: 'Identifier',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 46,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 48,
|
||||
},
|
||||
source: 'fn',
|
||||
},
|
||||
name: 'fn',
|
||||
},
|
||||
value: {
|
||||
type: 'ArrowFunctionExpression',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 50,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 105,
|
||||
},
|
||||
source:
|
||||
'(tables) => tables.cpu["_value"] + tables.mem["_value"]',
|
||||
},
|
||||
params: [
|
||||
{
|
||||
type: 'Property',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 51,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 57,
|
||||
},
|
||||
source: 'tables',
|
||||
},
|
||||
key: {
|
||||
type: 'Identifier',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 51,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 57,
|
||||
},
|
||||
source: 'tables',
|
||||
},
|
||||
name: 'tables',
|
||||
},
|
||||
value: null,
|
||||
},
|
||||
],
|
||||
body: {
|
||||
type: 'BinaryExpression',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 62,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 105,
|
||||
},
|
||||
source: 'tables.cpu["_value"] + tables.mem["_value"]',
|
||||
},
|
||||
operator: '+',
|
||||
left: {
|
||||
type: 'MemberExpression',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 62,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 83,
|
||||
},
|
||||
source: 'tables.cpu["_value"] ',
|
||||
},
|
||||
object: {
|
||||
type: 'MemberExpression',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 62,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 83,
|
||||
},
|
||||
source: 'tables.cpu["_value"] ',
|
||||
},
|
||||
object: {
|
||||
type: 'Identifier',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 62,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 68,
|
||||
},
|
||||
source: 'tables',
|
||||
},
|
||||
name: 'tables',
|
||||
},
|
||||
property: {
|
||||
type: 'Identifier',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 69,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 72,
|
||||
},
|
||||
source: 'cpu',
|
||||
},
|
||||
name: 'cpu',
|
||||
},
|
||||
},
|
||||
property: {
|
||||
type: 'StringLiteral',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 73,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 81,
|
||||
},
|
||||
source: '"_value"',
|
||||
},
|
||||
value: '_value',
|
||||
},
|
||||
},
|
||||
right: {
|
||||
type: 'MemberExpression',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 85,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 105,
|
||||
},
|
||||
source: 'tables.mem["_value"]',
|
||||
},
|
||||
object: {
|
||||
type: 'MemberExpression',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 85,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 105,
|
||||
},
|
||||
source: 'tables.mem["_value"]',
|
||||
},
|
||||
object: {
|
||||
type: 'Identifier',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 85,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 91,
|
||||
},
|
||||
source: 'tables',
|
||||
},
|
||||
name: 'tables',
|
||||
},
|
||||
property: {
|
||||
type: 'Identifier',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 92,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 95,
|
||||
},
|
||||
source: 'mem',
|
||||
},
|
||||
name: 'mem',
|
||||
},
|
||||
},
|
||||
property: {
|
||||
type: 'StringLiteral',
|
||||
location: {
|
||||
start: {
|
||||
line: 1,
|
||||
column: 96,
|
||||
},
|
||||
end: {
|
||||
line: 1,
|
||||
column: 104,
|
||||
},
|
||||
source: '"_value"',
|
||||
},
|
||||
value: '_value',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
Expression,
|
||||
ArrowFunction,
|
||||
Fork,
|
||||
JoinWithObjectArg,
|
||||
} from 'test/ifql/ast/variable'
|
||||
|
||||
describe('IFQL.AST.Walker', () => {
|
||||
|
@ -14,7 +15,7 @@ describe('IFQL.AST.Walker', () => {
|
|||
describe('a single expression', () => {
|
||||
it('returns a flattened ordered list of from and its args', () => {
|
||||
const walker = new Walker(From)
|
||||
expect(walker.body).toEqual([
|
||||
const expectedWalkerBody = [
|
||||
{
|
||||
type: 'CallExpression',
|
||||
source: 'from(db: "telegraf")',
|
||||
|
@ -31,14 +32,15 @@ describe('IFQL.AST.Walker', () => {
|
|||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
]
|
||||
expect(walker.body).toEqual(expectedWalkerBody)
|
||||
})
|
||||
|
||||
describe('variables', () => {
|
||||
describe('a single string literal variable', () => {
|
||||
it('returns the expected list', () => {
|
||||
const walker = new Walker(StringLiteral)
|
||||
expect(walker.body).toEqual([
|
||||
const expectedWalkerBody = [
|
||||
{
|
||||
type: 'VariableDeclaration',
|
||||
source: 'bux = "im a var"',
|
||||
|
@ -50,14 +52,15 @@ describe('IFQL.AST.Walker', () => {
|
|||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
]
|
||||
expect(walker.body).toEqual(expectedWalkerBody)
|
||||
})
|
||||
})
|
||||
|
||||
describe('a single expression variable', () => {
|
||||
it('returns the expected list', () => {
|
||||
const walker = new Walker(Expression)
|
||||
expect(walker.body).toEqual([
|
||||
const expectedWalkerBody = [
|
||||
{
|
||||
type: 'VariableDeclaration',
|
||||
source: 'tele = from(db: "telegraf")',
|
||||
|
@ -81,14 +84,15 @@ describe('IFQL.AST.Walker', () => {
|
|||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
]
|
||||
expect(walker.body).toEqual(expectedWalkerBody)
|
||||
})
|
||||
})
|
||||
|
||||
describe('a single ArrowFunction variable', () => {
|
||||
it('returns the expected list', () => {
|
||||
const walker = new Walker(ArrowFunction)
|
||||
expect(walker.body).toEqual([
|
||||
const expectedWalkerBody = [
|
||||
{
|
||||
type: 'VariableDeclaration',
|
||||
source: 'addOne = (n) => n + 1',
|
||||
|
@ -106,14 +110,15 @@ describe('IFQL.AST.Walker', () => {
|
|||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
]
|
||||
expect(walker.body).toEqual(expectedWalkerBody)
|
||||
})
|
||||
})
|
||||
|
||||
describe('forking', () => {
|
||||
it('return the expected list of objects', () => {
|
||||
const walker = new Walker(Fork)
|
||||
expect(walker.body).toEqual([
|
||||
const expectedWalkerBody = [
|
||||
{
|
||||
type: 'VariableDeclaration',
|
||||
source: 'tele = from(db: "telegraf")',
|
||||
|
@ -145,17 +150,48 @@ describe('IFQL.AST.Walker', () => {
|
|||
{args: [], name: 'sum', source: '|> sum()'},
|
||||
],
|
||||
},
|
||||
])
|
||||
]
|
||||
expect(walker.body).toEqual(expectedWalkerBody)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Args that are objects', () => {
|
||||
it('returns an object when arg type is object', () => {
|
||||
const walker = new Walker(JoinWithObjectArg)
|
||||
const expectedWalkerBody = [
|
||||
{
|
||||
type: 'CallExpression',
|
||||
source:
|
||||
'join(tables:{cpu:cpu, mem:mem}, on:["host"], fn: (tables) => tables.cpu["_value"] + tables.mem["_value"])',
|
||||
funcs: [
|
||||
{
|
||||
name: 'join',
|
||||
source:
|
||||
'join(tables:{cpu:cpu, mem:mem}, on:["host"], fn: (tables) => tables.cpu["_value"] + tables.mem["_value"])',
|
||||
args: [
|
||||
{key: 'tables', value: {cpu: 'cpu', mem: 'mem'}},
|
||||
{key: 'on', value: ['host']},
|
||||
{
|
||||
key: 'fn',
|
||||
value:
|
||||
'(tables) => tables.cpu["_value"] + tables.mem["_value"]',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
expect(walker.body).toEqual(expectedWalkerBody)
|
||||
})
|
||||
})
|
||||
|
||||
describe('complex example', () => {
|
||||
it('returns a flattened ordered list of all funcs and their args', () => {
|
||||
const walker = new Walker(Complex)
|
||||
expect(walker.body).toEqual([
|
||||
const expectedWalkerBody = [
|
||||
{
|
||||
type: 'PipeExpression',
|
||||
source:
|
||||
|
@ -183,7 +219,8 @@ describe('IFQL.AST.Walker', () => {
|
|||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
]
|
||||
expect(walker.body).toEqual(expectedWalkerBody)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue