Version 2.2.0.
* Adds support for custom injected scripts with automatic reload * Refactors extension
This commit is contained in:
7
data-extraction/src/js/api/LoadDataExtractorsFn.ts
Normal file
7
data-extraction/src/js/api/LoadDataExtractorsFn.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { DataExtractor } from "./DataExtractorApi";
|
||||
import type * as helpersTypes from "../helpers"
|
||||
|
||||
export type LoadDataExtractorsFn = (
|
||||
register: (extractor: DataExtractor) => void,
|
||||
helpers: typeof helpersTypes
|
||||
) => void;
|
||||
@@ -0,0 +1,34 @@
|
||||
import {
|
||||
DataExtractor,
|
||||
ExtractionCollector,
|
||||
DataExtractorContext,
|
||||
LoadDataExtractorsFn,
|
||||
} from "..";
|
||||
import * as helpers from "../../helpers";
|
||||
|
||||
export class InjectedExtractor implements DataExtractor {
|
||||
readonly id = "injected-extractor";
|
||||
|
||||
getExtractions(
|
||||
data: unknown,
|
||||
extractionCollector: ExtractionCollector,
|
||||
context: DataExtractorContext
|
||||
): void {
|
||||
const key = "@hediet/debug-visualizer/injectedScripts";
|
||||
const injectedExtractorsFns = Object.values(
|
||||
(global as any)[key]
|
||||
) as LoadDataExtractorsFn[];
|
||||
|
||||
const extractors = new Array<DataExtractor>();
|
||||
|
||||
for (const fn of injectedExtractorsFns) {
|
||||
fn(extractor => {
|
||||
extractors.push(extractor);
|
||||
}, helpers);
|
||||
}
|
||||
|
||||
for (const extractor of extractors) {
|
||||
extractor.getExtractions(data, extractionCollector, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import { getDataExtractorApi } from "../injection";
|
||||
import { GridExtractor } from "./GridExtractor";
|
||||
import { TableDataExtractor } from "./TableExtractor";
|
||||
import { StringDiffExtractor } from "./StringDiffExtractor";
|
||||
import { find } from "../../helpers";
|
||||
import { InjectedExtractor } from "./InjectedExtractor";
|
||||
|
||||
/**
|
||||
* The default data extractors should be registered by VS Code automatically.
|
||||
@@ -28,101 +28,8 @@ export function registerDefaultExtractors(
|
||||
new GridExtractor(),
|
||||
new TableDataExtractor(),
|
||||
new StringDiffExtractor(),
|
||||
new InjectedExtractor(),
|
||||
]) {
|
||||
api.registerExtractor(item);
|
||||
}
|
||||
|
||||
function isRange(
|
||||
value: unknown
|
||||
): value is {
|
||||
startColumn: number;
|
||||
startLineNumber: number;
|
||||
endColumn: number;
|
||||
endLineNumber: number;
|
||||
} {
|
||||
return (
|
||||
typeof value === "object" &&
|
||||
!!value &&
|
||||
"startColumn" in value &&
|
||||
"startLineNumber" in value
|
||||
);
|
||||
}
|
||||
|
||||
function isPosition(
|
||||
value: unknown
|
||||
): value is { column: number; lineNumber: number } {
|
||||
return (
|
||||
typeof value === "object" &&
|
||||
!!value &&
|
||||
"column" in value &&
|
||||
"lineNumber" in value
|
||||
);
|
||||
}
|
||||
|
||||
// hedietDbgVis.find(x => x.constructor.name === 'TextModel').getValue()
|
||||
api.registerExtractor({
|
||||
id: "positionInTextModel",
|
||||
getExtractions(data, collector, context) {
|
||||
let range: {
|
||||
start: {
|
||||
line: number;
|
||||
column: number;
|
||||
};
|
||||
end: {
|
||||
line: number;
|
||||
column: number;
|
||||
};
|
||||
};
|
||||
if (isRange(data)) {
|
||||
range = {
|
||||
start: {
|
||||
line: data.startLineNumber - 1,
|
||||
column: data.startColumn - 1,
|
||||
},
|
||||
end: {
|
||||
line: data.endLineNumber - 1,
|
||||
column: data.endColumn - 1,
|
||||
},
|
||||
};
|
||||
} else if (isPosition(data)) {
|
||||
range = {
|
||||
start: {
|
||||
line: data.lineNumber - 1,
|
||||
column: data.column - 1,
|
||||
},
|
||||
end: {
|
||||
line: data.lineNumber - 1,
|
||||
column: data.column - 1,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isRange(data) && !isPosition(data)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const textModel: any = find(
|
||||
x =>
|
||||
typeof x === "object" &&
|
||||
!!x &&
|
||||
"constructor" in x &&
|
||||
(x as any).constructor.name === "TextModel"
|
||||
);
|
||||
|
||||
collector.addExtraction({
|
||||
id: "positionInTextModel",
|
||||
name: "Position In TextModel",
|
||||
extractData() {
|
||||
return {
|
||||
kind: { text: true },
|
||||
text: textModel.getValue(),
|
||||
decorations: [{ range }],
|
||||
};
|
||||
},
|
||||
priority: 1000,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from "./DataExtractorApi";
|
||||
export * from "./injection";
|
||||
export { DataExtractorApiImpl } from "./DataExtractorApiImpl";
|
||||
export * from "./LoadDataExtractorsFn";
|
||||
|
||||
@@ -20,16 +20,18 @@ export function getExpressionToInitializeDataExtractorApi(): string {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns standalone JS code representing an expression returns the data extraction API.
|
||||
* Returns standalone JS code representing an expression that returns the data extraction API.
|
||||
* This expression returns an object of type `DataExtractorApi`.
|
||||
* If the API must be initialized with `getExpressionToInitializeDataExtractorApi()`,
|
||||
* it throws an exception containing the text of `ApiHasNotBeenInitializedCode`.
|
||||
* This function is called in the VS Code extension, the expression is evaluated in the debugee.
|
||||
*/
|
||||
export function getExpressionForDataExtractorApi(): string {
|
||||
return `((${selfContainedGetInitializedDataExtractorApi.toString()})())`;
|
||||
}
|
||||
|
||||
export function getExpressionToDetectDataExtractorApiPresence(): string {
|
||||
return `((${selfContainedIsDataExtractorApiInitialized.toString()})())`;
|
||||
}
|
||||
|
||||
const apiKey = "@hediet/data-extractor-api/v2";
|
||||
|
||||
export function getDataExtractorApi(): DataExtractorApi {
|
||||
@@ -43,10 +45,15 @@ export function getDataExtractorApi(): DataExtractorApi {
|
||||
}
|
||||
|
||||
/**
|
||||
* This code is used to detect if the API has not been initialized yet.
|
||||
* @internal
|
||||
*/
|
||||
export const ApiHasNotBeenInitializedCode = "EgH0cybXij1jYUozyakO" as const;
|
||||
function selfContainedIsDataExtractorApiInitialized(): boolean {
|
||||
const globalObj =
|
||||
typeof window === "object" ? (window as any) : (global as any);
|
||||
const key: typeof apiKey = "@hediet/data-extractor-api/v2";
|
||||
let api: DataExtractorApi | undefined = globalObj[key];
|
||||
return api !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@@ -57,11 +64,7 @@ function selfContainedGetInitializedDataExtractorApi(): DataExtractorApi {
|
||||
const key: typeof apiKey = "@hediet/data-extractor-api/v2";
|
||||
let api: DataExtractorApi | undefined = globalObj[key];
|
||||
if (!api) {
|
||||
const code: typeof ApiHasNotBeenInitializedCode =
|
||||
"EgH0cybXij1jYUozyakO";
|
||||
throw new Error(
|
||||
`Data Extractor API has not been initialized. Code: ${code}`
|
||||
);
|
||||
throw new Error(`Data Extractor API has not been initialized.`);
|
||||
}
|
||||
return api;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user