diff --git a/CODEOWNERS b/CODEOWNERS index bd290fd15..17dcef21c 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,3 +1,4 @@ **/* @github/codeql-vscode-reviewers **/variant-analysis/ @github/code-scanning-secexp-reviewers **/databases/ @github/code-scanning-secexp-reviewers +**/data-extensions-editor/ @github/code-scanning-secexp-reviewers diff --git a/extensions/ql-vscode/package.json b/extensions/ql-vscode/package.json index ff8813127..058733d31 100644 --- a/extensions/ql-vscode/package.json +++ b/extensions/ql-vscode/package.json @@ -703,6 +703,10 @@ "title": "CodeQL: Go to QL Code", "enablement": "codeql.hasQLSource" }, + { + "command": "codeQL.openDataExtensionsEditor", + "title": "CodeQL: Open Data Extensions Editor" + }, { "command": "codeQL.mockGitHubApiServer.startRecording", "title": "CodeQL: Mock GitHub API Server: Start Scenario Recording" @@ -1086,6 +1090,10 @@ "command": "codeQL.viewCfgContextEditor", "when": "false" }, + { + "command": "codeQL.openDataExtensionsEditor", + "when": "config.codeQL.canary && config.codeQL.dataExtensions.editor" + }, { "command": "codeQLVariantAnalysisRepositories.openConfigFile", "when": "false" diff --git a/extensions/ql-vscode/src/common/commands.ts b/extensions/ql-vscode/src/common/commands.ts index 55e47f22b..22e3a585b 100644 --- a/extensions/ql-vscode/src/common/commands.ts +++ b/extensions/ql-vscode/src/common/commands.ts @@ -241,6 +241,10 @@ export type PackagingCommands = { "codeQL.downloadPacks": () => Promise; }; +export type DataExtensionsEditorCommands = { + "codeQL.openDataExtensionsEditor": () => Promise; +}; + export type EvalLogViewerCommands = { "codeQLEvalLogViewer.clear": () => Promise; }; @@ -273,6 +277,7 @@ export type AllExtensionCommands = BaseCommands & AstCfgCommands & AstViewerCommands & PackagingCommands & + DataExtensionsEditorCommands & EvalLogViewerCommands & SummaryLanguageSupportCommands & Partial & diff --git a/extensions/ql-vscode/src/data-extensions-editor/data-extensions-editor-module.ts b/extensions/ql-vscode/src/data-extensions-editor/data-extensions-editor-module.ts new file mode 100644 index 000000000..61a29ea4d --- /dev/null +++ b/extensions/ql-vscode/src/data-extensions-editor/data-extensions-editor-module.ts @@ -0,0 +1,16 @@ +import { ExtensionContext } from "vscode"; +import { DataExtensionsEditorView } from "./data-extensions-editor-view"; +import { DataExtensionsEditorCommands } from "../common/commands"; + +export class DataExtensionsEditorModule { + public constructor(private readonly ctx: ExtensionContext) {} + + public getCommands(): DataExtensionsEditorCommands { + return { + "codeQL.openDataExtensionsEditor": async () => { + const view = new DataExtensionsEditorView(this.ctx); + await view.openView(); + }, + }; + } +} diff --git a/extensions/ql-vscode/src/data-extensions-editor/data-extensions-editor-view.ts b/extensions/ql-vscode/src/data-extensions-editor/data-extensions-editor-view.ts new file mode 100644 index 000000000..d8456ccb0 --- /dev/null +++ b/extensions/ql-vscode/src/data-extensions-editor/data-extensions-editor-view.ts @@ -0,0 +1,53 @@ +import { ExtensionContext, ViewColumn } from "vscode"; +import { AbstractWebview, WebviewPanelConfig } from "../abstract-webview"; +import { + FromDataExtensionsEditorMessage, + ToDataExtensionsEditorMessage, +} from "../pure/interface-types"; + +export class DataExtensionsEditorView extends AbstractWebview< + ToDataExtensionsEditorMessage, + FromDataExtensionsEditorMessage +> { + public constructor(ctx: ExtensionContext) { + super(ctx); + } + + public async openView() { + const panel = await this.getPanel(); + panel.reveal(undefined, true); + + await this.waitForPanelLoaded(); + } + + protected async getPanelConfig(): Promise { + return { + viewId: "data-extensions-editor", + title: "Data Extensions Editor", + viewColumn: ViewColumn.Active, + preserveFocus: true, + view: "data-extensions-editor", + }; + } + + protected onPanelDispose(): void { + // Nothing to do here + } + + protected async onMessage( + msg: FromDataExtensionsEditorMessage, + ): Promise { + switch (msg.t) { + case "viewLoaded": + await this.onWebViewLoaded(); + + break; + default: + throw new Error("Unexpected message type"); + } + } + + protected async onWebViewLoaded() { + super.onWebViewLoaded(); + } +} diff --git a/extensions/ql-vscode/src/extension.ts b/extensions/ql-vscode/src/extension.ts index a91663be6..391acd501 100644 --- a/extensions/ql-vscode/src/extension.ts +++ b/extensions/ql-vscode/src/extension.ts @@ -120,6 +120,7 @@ import { getAstCfgCommands } from "./ast-cfg-commands"; import { getQueryEditorCommands } from "./query-editor"; import { App } from "./common/app"; import { registerCommandWithErrorHandling } from "./common/vscode/commands"; +import { DataExtensionsEditorModule } from "./data-extensions-editor/data-extensions-editor-module"; /** * extension.ts @@ -860,6 +861,8 @@ async function activateWithInstalledDistribution( ); ctx.subscriptions.push(localQueries); + const dataExtensionsEditorModule = new DataExtensionsEditorModule(ctx); + void extLogger.log("Initializing QLTest interface."); const testExplorerExtension = extensions.getExtension( testExplorerExtensionId, @@ -922,6 +925,7 @@ async function activateWithInstalledDistribution( ...getPackagingCommands({ cliServer, }), + ...dataExtensionsEditorModule.getCommands(), ...evalLogViewer.getCommands(), ...summaryLanguageSupport.getCommands(), ...testUiCommands, diff --git a/extensions/ql-vscode/src/interface-utils.ts b/extensions/ql-vscode/src/interface-utils.ts index 68232dacd..65ed3d2aa 100644 --- a/extensions/ql-vscode/src/interface-utils.ts +++ b/extensions/ql-vscode/src/interface-utils.ts @@ -113,7 +113,8 @@ export type WebviewView = | "results" | "compare" | "variant-analysis" - | "data-flow-paths"; + | "data-flow-paths" + | "data-extensions-editor"; export interface WebviewMessage { t: string; diff --git a/extensions/ql-vscode/src/pure/interface-types.ts b/extensions/ql-vscode/src/pure/interface-types.ts index 2d68b39d2..95d9475e5 100644 --- a/extensions/ql-vscode/src/pure/interface-types.ts +++ b/extensions/ql-vscode/src/pure/interface-types.ts @@ -478,3 +478,7 @@ export interface SetDataFlowPathsMessage { export type ToDataFlowPathsMessage = SetDataFlowPathsMessage; export type FromDataFlowPathsMessage = CommonFromViewMessages; + +export type ToDataExtensionsEditorMessage = never; + +export type FromDataExtensionsEditorMessage = ViewLoadedMsg; diff --git a/extensions/ql-vscode/src/view/data-extensions-editor/DataExtensionsEditor.tsx b/extensions/ql-vscode/src/view/data-extensions-editor/DataExtensionsEditor.tsx new file mode 100644 index 000000000..0edc98a66 --- /dev/null +++ b/extensions/ql-vscode/src/view/data-extensions-editor/DataExtensionsEditor.tsx @@ -0,0 +1,5 @@ +import * as React from "react"; + +export function DataExtensionsEditor(): JSX.Element { + return
Data extensions editor
; +} diff --git a/extensions/ql-vscode/src/view/data-extensions-editor/index.tsx b/extensions/ql-vscode/src/view/data-extensions-editor/index.tsx new file mode 100644 index 000000000..247a35066 --- /dev/null +++ b/extensions/ql-vscode/src/view/data-extensions-editor/index.tsx @@ -0,0 +1,9 @@ +import * as React from "react"; +import { WebviewDefinition } from "../webview-definition"; +import { DataExtensionsEditor } from "./DataExtensionsEditor"; + +const definition: WebviewDefinition = { + component: , +}; + +export default definition; diff --git a/extensions/ql-vscode/src/view/vscode-api.ts b/extensions/ql-vscode/src/view/vscode-api.ts index fa2eaa948..a018216a1 100644 --- a/extensions/ql-vscode/src/view/vscode-api.ts +++ b/extensions/ql-vscode/src/view/vscode-api.ts @@ -1,5 +1,6 @@ import { FromCompareViewMessage, + FromDataExtensionsEditorMessage, FromResultsViewMsg, FromVariantAnalysisMessage, VariantAnalysisState, @@ -13,7 +14,8 @@ export interface VsCodeApi { msg: | FromResultsViewMsg | FromCompareViewMessage - | FromVariantAnalysisMessage, + | FromVariantAnalysisMessage + | FromDataExtensionsEditorMessage, ): void; /**