Skip to content

feat: vscode extension #4104

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft

feat: vscode extension #4104

wants to merge 1 commit into from

Conversation

benfdking
Copy link
Contributor

@benfdking benfdking commented Apr 9, 2025

Initial scope:

  • Format code -> through lsp
  • List diagnostics -> through diagnostics
  • Lineage view
    • Jump to model on file change
    • Click on node opens file

<small
className="block text-neutral-600 italic overflow-hidden whitespace-nowrap overflow-ellipsis"
dangerouslySetInnerHTML={{
__html: highlightMatch(index, search),

Check warning

Code scanning / CodeQL

DOM text reinterpreted as HTML Medium

DOM text
is reinterpreted as HTML without escaping meta-characters.
title={item[displayBy]}
className="font-bold"
dangerouslySetInnerHTML={{
__html: highlightMatch(item[displayBy], search),

Check warning

Code scanning / CodeQL

DOM text reinterpreted as HTML Medium

DOM text
is reinterpreted as HTML without escaping meta-characters.

Copilot Autofix

AI 2 days ago

To fix the issue, we need to ensure that any HTML injected into the DOM via dangerouslySetInnerHTML is sanitized to prevent XSS. The best approach is to use a library like dompurify to sanitize the output of highlightMatch. This ensures that any potentially malicious input is neutralized before being rendered as HTML.

Steps to fix:

  1. Install the dompurify library if it is not already installed.
  2. Import dompurify into the file.
  3. Use DOMPurify.sanitize to sanitize the output of highlightMatch before passing it to dangerouslySetInnerHTML.

Suggested changeset 2
vscode/react/src/components/search/SearchList.tsx

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/vscode/react/src/components/search/SearchList.tsx b/vscode/react/src/components/search/SearchList.tsx
--- a/vscode/react/src/components/search/SearchList.tsx
+++ b/vscode/react/src/components/search/SearchList.tsx
@@ -1,2 +1,3 @@
 import React, { Fragment, useMemo, useRef, useState } from 'react'
+import DOMPurify from 'dompurify'
 import Input from '@/components/input/Input'
@@ -333,3 +334,3 @@
           dangerouslySetInnerHTML={{
-            __html: highlightMatch(item[displayBy], search),
+            __html: DOMPurify.sanitize(highlightMatch(item[displayBy], search)),
           }}
EOF
@@ -1,2 +1,3 @@
import React, { Fragment, useMemo, useRef, useState } from 'react'
import DOMPurify from 'dompurify'
import Input from '@/components/input/Input'
@@ -333,3 +334,3 @@
dangerouslySetInnerHTML={{
__html: highlightMatch(item[displayBy], search),
__html: DOMPurify.sanitize(highlightMatch(item[displayBy], search)),
}}
vscode/react/package.json
Outside changed files

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/vscode/react/package.json b/vscode/react/package.json
--- a/vscode/react/package.json
+++ b/vscode/react/package.json
@@ -23,3 +23,4 @@
     "react-dom": "^19.0.0",
-    "tailwindcss": "^4.1.3"
+    "tailwindcss": "^4.1.3",
+    "dompurify": "^3.2.5"
   },
EOF
@@ -23,3 +23,4 @@
"react-dom": "^19.0.0",
"tailwindcss": "^4.1.3"
"tailwindcss": "^4.1.3",
"dompurify": "^3.2.5"
},
This fix introduces these dependencies
Package Version Security advisories
dompurify (npm) 3.2.5 None
Copilot is powered by AI and may make mistakes. Always verify output.
@benfdking benfdking force-pushed the vscode_extension branch 5 times, most recently from 8a0b89e to 2673372 Compare April 11, 2025 22:30

import * as path from 'path'

const folderName = path.basename(__dirname)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FOLDER_NAME ?

export function loadServerDefaults(): IServerInfo {
const packageJson = path.join(EXTENSION_ROOT_DIR, 'package.json')
const content = fs.readFileSync(packageJson).toString()
const config = JSON.parse(content)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

config is unused

let rootWorkspace = workspaces[0]
let root = undefined
for (const w of workspaces) {
if (await fs.pathExists(w.uri.fsPath)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we juts use pathExistsSync ?

*
* @returns The sqlmesh executable for the current workspace.
*/
export const sqlmesh_exec = async (): Promise<Result<sqlmesh_exec, string>> => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we use camelCase ?

target="_blank"
rel="noopener noreferrer"
>
Learn React
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

example file

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

react logo

Comment on lines +9 to +17
// Use a different variable name to avoid conflict with the parameter
const eventPayload = {
key: callbackName,
payload: payload,
}
window.parent.postMessage({
key: "vscode_callback",
payload: eventPayload,
}, '*');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe just use object directly payload: { ... }?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

example file ?

// You can import and use all API from the 'vscode' module
// as well as import your extension to test it
import * as vscode from 'vscode'
// import * as myExtension from '../../extension';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

example ?

Comment on lines +61 to +62
if (message && message.key) {
if (message.key === "vscode_callback") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think you can just if (message?.key === "vscode_callback") { ... } else {}

webviewView.webview.onDidReceiveMessage(
async (message) => {
console.log("message received", message);
if (message && message.key) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we have a dedicated ConsoleLog() function to use when we need to log something and treat native console.log as part of dev debugging that needs to be removed ?

Comment on lines +46 to +139
// synchronize: {
// fileEvents: workspace.createFileSystemWatcher('**/*.{sql,py}'),
// }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove ?

Comment on lines 22 to 25
if (_api) {
return _api
}
_api = await PythonExtension.api()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe _api = _api || await PythonExtension.api()

Comment on lines 30 to 46
try {
const api = await getPythonExtensionAPI()

if (api) {
disposables.push(
api.environments.onDidChangeActiveEnvironmentPath(async (e) => {
const environment = await api.environments.resolveEnvironment(e.path)
const isVirtualEnv = environment?.environment !== undefined
const binPath = isVirtualEnv ? environment?.environment?.folderUri.fsPath : undefined

onDidChangePythonInterpreterEvent.fire({
path: [e.path],
resource: e.resource?.uri,
isVirtualEnvironment: isVirtualEnv,
binPath
})
}),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is trying to catch Error initializing python and i think if await getPythonExtensionAPI() returns null that kinda like an error we want to catch here but having if (api) { prevents that

Comment on lines 34 to 36
const level = logLevelToTrace(channelLogLevel <= globalLogLevel ? channelLogLevel : globalLogLevel)
return level
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe just return logLevelToTrace(channelLogLevel <= globalLogLevel ? channelLogLevel : globalLogLevel)

@benfdking benfdking marked this pull request as draft April 17, 2025 15:45
@benfdking benfdking force-pushed the vscode_extension branch 8 times, most recently from 5cc30c2 to daa2f80 Compare April 24, 2025 11:47
@benfdking benfdking force-pushed the vscode_extension branch 4 times, most recently from cdb81d1 to a019d1c Compare April 24, 2025 11:53
registered logging

[ci skip]

format works

making progress

making progress sharing node modules

creating the docs

progress

getting react server to show

making progress with the server

temp

get calling api now need to add lineage tab

making progress on vscode lineage

temp

progress: showing the lineage graph

[ci skip]

cleaning up lineage

[ci skip]

added ability to open files

temp [ci skip]

trying to implement lsp

[ci skip]

temp

[ci skip]

test [ci skip]

temp [ci skip]

temp [ci skip]

temp [ci skip]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants