diff --git a/data-extraction/src/js/api/DataExtractorApi.ts b/data-extraction/src/js/api/DataExtractorApi.ts index 970fa38..af4a176 100644 --- a/data-extraction/src/js/api/DataExtractorApi.ts +++ b/data-extraction/src/js/api/DataExtractorApi.ts @@ -17,10 +17,12 @@ export interface DataExtractorApi { registerExtractors(extractors: DataExtractor[]): 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: (expression: string) => T, preferredDataExtractorId: string | undefined ): JSONString; diff --git a/data-extraction/src/js/api/DataExtractorApiImpl.ts b/data-extraction/src/js/api/DataExtractorApiImpl.ts index 1b0e8bb..441dc86 100644 --- a/data-extraction/src/js/api/DataExtractorApiImpl.ts +++ b/data-extraction/src/js/api/DataExtractorApiImpl.ts @@ -10,6 +10,8 @@ import { ExtractedData, DataExtractorInfo } from "../../DataExtractionResult"; import { registerDefaultDataExtractors } from "./default-extractors"; export class DataExtractorApiImpl implements DataExtractorApi { + public static lastEvalFn: ((expression: string) => T) | undefined; + private readonly extractors = new Map< string, DataExtractor @@ -34,7 +36,7 @@ export class DataExtractorApiImpl implements DataExtractorApi { } public getData( - value: unknown, + valueFn: () => unknown, evalFn: (expression: string) => T, preferredDataExtractorId: string | undefined ): JSONString { @@ -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); } } diff --git a/data-extraction/src/js/helpers/index.ts b/data-extraction/src/js/helpers/index.ts index b106c10..4f6547f 100644 --- a/data-extraction/src/js/helpers/index.ts +++ b/data-extraction/src/js/helpers/index.ts @@ -1,2 +1,3 @@ export * from "./createGraph"; export * from "./createGraphFromPointers"; +export * from "./tryEval"; diff --git a/data-extraction/src/js/helpers/tryEval.ts b/data-extraction/src/js/helpers/tryEval.ts new file mode 100644 index 0000000..bab659c --- /dev/null +++ b/data-extraction/src/js/helpers/tryEval.ts @@ -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): Record; +/** + * 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; +export function tryEval( + obj: Record | string[] | string +): Record | unknown { + const result: Record = {}; + 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; +} diff --git a/extension/src/DataSource/JsDebuggerSource.ts b/extension/src/DataSource/JsDebuggerSource.ts index 2dd5805..c7b6e8f 100644 --- a/extension/src/DataSource/JsDebuggerSource.ts +++ b/extension/src/DataSource/JsDebuggerSource.ts @@ -103,7 +103,7 @@ export class JsDebuggerSourceImplementation implements JsDataSource { : "undefined"; const body = `${getExpressionForDataExtractorApi()}.getData( - ${w.expression}, + e => (${w.expression}), expr => eval(expr), ${preferredExtractor} )`;