postprocessor.ts
1 import { LITERAL_MARKER } from "../helpers/constants" 2 import { Log } from "../types" 3 4 export enum PostProcessorNames { 5 CONVERT_LITERALS = "convert-literals", 6 } 7 8 export type PostprocessorFn = (statement: string) => { 9 result: any 10 logs?: Log[] 11 } 12 13 export class Postprocessor { 14 name: PostProcessorNames 15 private readonly fn: PostprocessorFn 16 17 constructor(name: PostProcessorNames, fn: PostprocessorFn) { 18 this.name = name 19 this.fn = fn 20 } 21 22 process(statement: string) { 23 return this.fn(statement) 24 } 25 } 26 27 export const processors = [ 28 new Postprocessor( 29 PostProcessorNames.CONVERT_LITERALS, 30 (statement: string): { result: any; logs?: Log[] } => { 31 if ( 32 typeof statement !== "string" || 33 !statement.includes(LITERAL_MARKER) 34 ) { 35 return { result: statement } 36 } 37 const splitMarkerIndex = statement.indexOf("-") 38 const type = statement.substring(12, splitMarkerIndex) 39 const value = statement.substring( 40 splitMarkerIndex + 1, 41 statement.length - 2 42 ) 43 switch (type) { 44 case "string": 45 return { result: value } 46 case "number": 47 return { result: parseFloat(value) } 48 case "boolean": 49 return { result: value === "true" } 50 case "object": 51 return { result: JSON.parse(value) } 52 case "js_result": { 53 // We use the literal helper to process the result of JS expressions 54 // as we want to be able to return any types. 55 // We wrap the value in an abject to be able to use undefined properly. 56 const parsed = JSON.parse(value) 57 return { result: parsed.data, logs: parsed.logs } 58 } 59 } 60 return { result: value } 61 } 62 ), 63 ]