Implements tryEval.

This commit is contained in:
Henning Dieterichs
2020-02-12 19:04:59 +01:00
parent 17e362aaa9
commit fbcc852fc2
5 changed files with 62 additions and 4 deletions

View File

@@ -17,10 +17,12 @@ export interface DataExtractorApi {
registerExtractors(extractors: DataExtractor<ExtractedData>[]): void;
/**
* Extracts data from `value`.
* Extracts data from the result of `valueFn`.
* @valueFn a function returning the value to extract the data from.
* Is a function so that it's evaluation can depend on `evalFn`.
*/
getData(
value: unknown,
valueFn: () => unknown,
evalFn: <T>(expression: string) => T,
preferredDataExtractorId: string | undefined
): JSONString<DataResult>;

View File

@@ -10,6 +10,8 @@ import { ExtractedData, DataExtractorInfo } from "../../DataExtractionResult";
import { registerDefaultDataExtractors } from "./default-extractors";
export class DataExtractorApiImpl implements DataExtractorApi {
public static lastEvalFn: (<T>(expression: string) => T) | undefined;
private readonly extractors = new Map<
string,
DataExtractor<ExtractedData>
@@ -34,7 +36,7 @@ export class DataExtractorApiImpl implements DataExtractorApi {
}
public getData(
value: unknown,
valueFn: () => unknown,
evalFn: <T>(expression: string) => T,
preferredDataExtractorId: string | undefined
): JSONString<DataResult> {
@@ -45,6 +47,10 @@ export class DataExtractorApiImpl implements DataExtractorApi {
},
};
DataExtractorApiImpl.lastEvalFn = evalFn;
const value = valueFn();
DataExtractorApiImpl.lastEvalFn = undefined;
for (const e of this.extractors.values()) {
e.getExtractions(value, extractionCollector, { evalFn });
}
@@ -85,6 +91,7 @@ export class DataExtractorApiImpl implements DataExtractorApi {
}
public registerDefaultExtractors(preferExisting: boolean = false): void {
// TODO consider preferExisting
registerDefaultDataExtractors(this);
}
}

View File

@@ -1,2 +1,3 @@
export * from "./createGraph";
export * from "./createGraphFromPointers";
export * from "./tryEval";

View File

@@ -0,0 +1,48 @@
import { DataExtractorApiImpl } from "../api/DataExtractorApiImpl";
/**
* Takes an object and eval's its values.
* Each successfully evaluated value is added to the result object,
* its original key is used as key in the result object.
*
* # Example
* ```
* const x = 1;
* tryEval({ val1: "x", val2: "x y" })
* // -> { val1: 1 }
* ```
*/
export function tryEval(obj: Record<string, string>): Record<string, unknown>;
/**
* Takes an array of strings and eval's its items.
* Each successfully evaluated value is added to the result object,
* its original value is used as key.
*
* # Example
* ```
* const x = 1;
* tryEval(["x", "y", "a a", "x + 2"])
* // -> { x: 1, "x + 2": 3 }
* ```
*/
export function tryEval(arr: string[]): Record<string, unknown>;
export function tryEval(
obj: Record<string, string> | string[] | string
): Record<string, unknown> | unknown {
const result: Record<string, unknown> = {};
const evalFn = DataExtractorApiImpl.lastEvalFn!;
if (Array.isArray(obj)) {
for (const val of obj) {
try {
result[val] = evalFn(val);
} catch (e) {}
}
} else {
for (const [key, val] of Object.entries(obj)) {
try {
result[key] = evalFn(val);
} catch (e) {}
}
}
return result;
}

View File

@@ -103,7 +103,7 @@ export class JsDebuggerSourceImplementation implements JsDataSource {
: "undefined";
const body = `${getExpressionForDataExtractorApi()}.getData(
${w.expression},
e => (${w.expression}),
expr => eval(expr),
${preferredExtractor}
)`;