From ba4f9ad800321cfc7ad0a2e9453451d3ef7d4570 Mon Sep 17 00:00:00 2001 From: i582 <51853996+i582@users.noreply.github.com> Date: Fri, 30 May 2025 20:30:30 +0400 Subject: [PATCH 1/5] initial web build --- client/src/extension.ts | 87 +----- eslint.config.mjs | 3 +- package.json | 69 +---- server/src/e2e/runTest.ts | 2 +- server/src/e2e/suite/BaseTestSuite.ts | 2 +- server/src/e2e/suite/index.ts | 2 +- server/src/indexing-root.ts | 2 +- .../languages/tact/completion/data/types.ts | 2 +- .../providers/ImportPathCompletionProvider.ts | 2 +- .../tact/inspections/CompilerInspection.ts | 2 +- .../tact/inspections/MistInspection.ts | 2 +- .../tact/intentions/ExtractToFile.ts | 2 +- .../src/languages/tact/psi/ImportResolver.ts | 2 +- server/src/languages/tact/psi/TactFile.ts | 2 +- .../src/languages/tact/toolchain/toolchain.ts | 2 +- server/src/psi/File.ts | 2 +- server/src/server.ts | 2 +- server/src/utils/logger.ts | 2 +- server/src/vfs/fs-provider.ts | 2 +- webpack.config.js | 182 ++++++++----- yarn.lock | 247 +++++++++++++++++- 21 files changed, 393 insertions(+), 227 deletions(-) diff --git a/client/src/extension.ts b/client/src/extension.ts index d1cb7a69..2ad54211 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright © 2025 TON Studio import * as vscode from "vscode" -import * as path from "node:path" +import * as path from "path" import {Utils as vscode_uri} from "vscode-uri" import { LanguageClient, @@ -30,12 +30,7 @@ import type {Location} from "vscode-languageclient" import * as lsp from "vscode-languageserver-protocol" import type {ClientOptions} from "@shared/config-scheme" import {registerBuildTasks} from "./build-system" -import {registerOpenBocCommand} from "./commands/openBocCommand" -import {BocEditorProvider} from "./providers/BocEditorProvider" -import {BocFileSystemProvider} from "./providers/BocFileSystemProvider" -import {BocDecompilerProvider} from "./providers/BocDecompilerProvider" -import {registerSaveBocDecompiledCommand} from "./commands/saveBocDecompiledCommand" -import {Range, Position, FileSystemWatcher} from "vscode" +import {Range, Position} from "vscode" import {detectPackageManager, PackageManager} from "./utils/package-manager" import {ToolchainConfig} from "@server/settings/settings" @@ -46,35 +41,9 @@ let cachedToolchainInfo: SetToolchainVersionParams | null = null export async function activate(context: vscode.ExtensionContext): Promise { startServer(context).catch(consoleError) await registerBuildTasks(context) - registerOpenBocCommand(context) - registerSaveBocDecompiledCommand(context) + registerMistiCommand(context) registerGasConsumptionStatusBar(context) - - const config = vscode.workspace.getConfiguration("tact") - const openDecompiled = config.get("boc.openDecompiledOnOpen") - if (openDecompiled) { - BocEditorProvider.register() - - const bocFsProvider = new BocFileSystemProvider() - context.subscriptions.push( - vscode.workspace.registerFileSystemProvider("boc", bocFsProvider, { - isCaseSensitive: true, - isReadonly: false, - }), - ) - } - - const bocDecompilerProvider = new BocDecompilerProvider() - context.subscriptions.push( - vscode.workspace.registerTextDocumentContentProvider( - BocDecompilerProvider.scheme, - bocDecompilerProvider, - ), - ) - - const bocWatcher = registerBocWatcher(bocDecompilerProvider) - context.subscriptions.push(bocWatcher) } export function deactivate(): Thenable | undefined { @@ -890,56 +859,6 @@ function registerMistiCommand(context: vscode.ExtensionContext): void { ) } -function registerBocWatcher(bocDecompilerProvider: BocDecompilerProvider): FileSystemWatcher { - const bocWatcher = vscode.workspace.createFileSystemWatcher("**/*.boc") - - bocWatcher.onDidChange((uri: vscode.Uri) => { - const decompileUri = uri.with({ - scheme: BocDecompilerProvider.scheme, - path: uri.path + ".decompiled.fif", - }) - - const openDocument = vscode.workspace.textDocuments.find( - doc => doc.uri.toString() === decompileUri.toString(), - ) - - if (openDocument) { - bocDecompilerProvider.update(decompileUri) - } - }) - - bocWatcher.onDidDelete((uri: vscode.Uri) => { - const decompileUri = uri.with({ - scheme: BocDecompilerProvider.scheme, - path: uri.path + ".decompiled.fif", - }) - - const openDocument = vscode.workspace.textDocuments.find( - doc => doc.uri.toString() === decompileUri.toString(), - ) - - if (openDocument) { - bocDecompilerProvider.update(decompileUri) - } - }) - - bocWatcher.onDidCreate((uri: vscode.Uri) => { - const decompileUri = uri.with({ - scheme: BocDecompilerProvider.scheme, - path: uri.path + ".decompiled.fif", - }) - - const openDocument = vscode.workspace.textDocuments.find( - doc => doc.uri.toString() === decompileUri.toString(), - ) - - if (openDocument) { - bocDecompilerProvider.update(decompileUri) - } - }) - return bocWatcher -} - function registerGasConsumptionStatusBar(context: vscode.ExtensionContext): void { gasStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 1000) context.subscriptions.push( diff --git a/eslint.config.mjs b/eslint.config.mjs index cc675207..d88b76f9 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,4 +1,4 @@ -import path from "node:path" +import path from "path" import tseslint from "typescript-eslint" import url from "node:url" import unusedImports from "eslint-plugin-unused-imports" @@ -125,6 +125,7 @@ export default tseslint.config( "unicorn/no-array-reduce": "off", "unicorn/prefer-string-raw": "off", "unicorn/no-useless-undefined": "off", + "unicorn/prefer-node-protocol": "off", }, }, ) diff --git a/package.json b/package.json index eee45596..9c74ee23 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,9 @@ "scripts": { "test": "yarn jest", "build": "webpack && node ./scripts/set-executable.js ./dist/server.js", + "build:web": "webpack --env target=web", "package": "npx vsce package --no-yarn --readme-path README-extension.md", + "package:web": "npx vsce package --no-yarn --readme-path README-extension.md --target web", "lint": "eslint --cache .", "fmt": "prettier --write -l --cache .", "fmt:check": "prettier --check --cache .", @@ -58,6 +60,7 @@ "postinstall": "husky" }, "main": "./dist/client", + "browser": "./dist/web/client-web", "contributes": { "languages": [ { @@ -106,19 +109,6 @@ }, "configuration": "./client/src/languages/fift-language-configuration.json" }, - { - "id": "boc", - "extensions": [ - ".boc" - ], - "aliases": [ - "TON BoC" - ], - "icon": { - "light": "./dist/icons/icon-boc-dark.svg", - "dark": "./dist/icons/icon-boc-dark.svg" - } - }, { "id": "tlb", "aliases": [ @@ -197,16 +187,6 @@ "command": "tact/executeGetScopeProvider", "title": "Get Scope Information" }, - { - "command": "tact.openBocFile", - "title": "Open Decompiled BoC file", - "category": "Tact" - }, - { - "command": "tact.saveBocDecompiled", - "title": "Decompile BoC to Fift Assembly File", - "category": "Tact" - }, { "command": "tact.runMisti", "title": "Run Misti Analysis", @@ -266,18 +246,7 @@ } ], "menus": { - "explorer/context": [ - { - "when": "resourceExtname == .boc", - "command": "tact.openBocFile", - "group": "navigation" - }, - { - "when": "resourceExtname == '.boc'", - "command": "tact.saveBocDecompiled", - "group": "navigation" - } - ] + "explorer/context": [] }, "configuration": [ { @@ -631,16 +600,6 @@ } } }, - { - "title": "BoC", - "properties": { - "tact.boc.openDecompiledOnOpen": { - "type": "boolean", - "default": true, - "description": "Automatically open decompiled Fift assembly when opening BoC files" - } - } - }, { "title": "Linters", "properties": { @@ -675,18 +634,7 @@ "url": "https://raw.githubusercontent.com/tact-lang/tact/refs/heads/main/src/config/configSchema.json" } ], - "customEditors": [ - { - "viewType": "boc.editor", - "displayName": "BOC Editor", - "selector": [ - { - "filenamePattern": "*.boc" - } - ], - "priority": "default" - } - ], + "customEditors": [], "taskDefinitions": [ { "type": "blueprint-build", @@ -727,7 +675,6 @@ ] }, "dependencies": { - "@tact-lang/opcode": "^0.3.0", "@textlint/markdown-to-ast": "14.4.2", "change-case": "^5.4.4", "glob": "^11.0.1", @@ -742,10 +689,12 @@ "@types/jest": "^29.5.14", "@types/mocha": "^10.0.6", "@types/node": "^22.2.0", + "@types/path-browserify": "^1", "@types/vscode": "^1.63.0", "@vscode/test-cli": "^0.0.10", "@vscode/test-electron": "^2.4.1", "@vscode/vsce": "^3.0.0", + "buffer": "^6.0.3", "c8": "^10.1.3", "copy-webpack-plugin": "^12.0.2", "eslint": "^9.19.0", @@ -755,7 +704,10 @@ "husky": "^9.1.7", "jest": "^29.7.0", "mocha": "^10.3.0", + "path-browserify": "^1.0.1", "prettier": "3.4.2", + "process": "^0.11.10", + "stream-browserify": "^3.0.0", "tree-sitter-cli": "^0.25.0", "ts-jest": "^29.2.6", "ts-loader": "^9.5.1", @@ -763,6 +715,7 @@ "tsconfig-paths-webpack-plugin": "^4.2.0", "typescript": "^5.7.0", "typescript-eslint": "^8.22.0", + "util": "^0.12.5", "webpack": "^5.92.1", "webpack-cli": "^5.1.4" }, diff --git a/server/src/e2e/runTest.ts b/server/src/e2e/runTest.ts index 28d1f55e..2cbbb26e 100644 --- a/server/src/e2e/runTest.ts +++ b/server/src/e2e/runTest.ts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // Copyright © 2025 TON Studio -import * as path from "node:path" +import * as path from "path" import {runTests} from "@vscode/test-electron" // eslint-disable-next-line functional/type-declaration-immutability diff --git a/server/src/e2e/suite/BaseTestSuite.ts b/server/src/e2e/suite/BaseTestSuite.ts index 8716b033..3a6b0c4d 100644 --- a/server/src/e2e/suite/BaseTestSuite.ts +++ b/server/src/e2e/suite/BaseTestSuite.ts @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright © 2025 TON Studio import * as vscode from "vscode" -import * as path from "node:path" +import * as path from "path" import * as fs from "node:fs" import * as glob from "glob" import {TestCase, TestParser} from "./TestParser" diff --git a/server/src/e2e/suite/index.ts b/server/src/e2e/suite/index.ts index 07267c45..8bbc3639 100644 --- a/server/src/e2e/suite/index.ts +++ b/server/src/e2e/suite/index.ts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // Copyright © 2025 TON Studio -import * as path from "node:path" +import * as path from "path" import * as Mocha from "mocha" import {glob} from "glob" import {Suite, Test} from "mocha" diff --git a/server/src/indexing-root.ts b/server/src/indexing-root.ts index bf428622..43eb426d 100644 --- a/server/src/indexing-root.ts +++ b/server/src/indexing-root.ts @@ -3,7 +3,7 @@ import {glob} from "glob" import {index} from "@server/languages/tact/indexes" import {fileURLToPath} from "node:url" -import * as path from "node:path" +import * as path from "path" import {filePathToUri, findTactFile} from "@server/files" export enum IndexingRootKind { diff --git a/server/src/languages/tact/completion/data/types.ts b/server/src/languages/tact/completion/data/types.ts index 1e2dc6ac..de5229e0 100644 --- a/server/src/languages/tact/completion/data/types.ts +++ b/server/src/languages/tact/completion/data/types.ts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // Copyright © 2025 TON Studio -import * as path from "node:path" +import * as path from "path" import {Node as SyntaxNode} from "web-tree-sitter" import {globalVFS, readFileVFS} from "@server/vfs/files-adapter" import {pathToFileURL} from "node:url" diff --git a/server/src/languages/tact/completion/providers/ImportPathCompletionProvider.ts b/server/src/languages/tact/completion/providers/ImportPathCompletionProvider.ts index 445e1a55..9077d6cc 100644 --- a/server/src/languages/tact/completion/providers/ImportPathCompletionProvider.ts +++ b/server/src/languages/tact/completion/providers/ImportPathCompletionProvider.ts @@ -7,7 +7,7 @@ import { CompletionResult, CompletionWeight, } from "@server/languages/tact/completion/WeightedCompletionItem" -import * as path from "node:path" +import * as path from "path" import {globalVFS} from "@server/vfs/global" import {listDirs, listFiles} from "@server/vfs/vfs" import {filePathToUri} from "@server/files" diff --git a/server/src/languages/tact/inspections/CompilerInspection.ts b/server/src/languages/tact/inspections/CompilerInspection.ts index 2205efa8..797f58a8 100644 --- a/server/src/languages/tact/inspections/CompilerInspection.ts +++ b/server/src/languages/tact/inspections/CompilerInspection.ts @@ -6,7 +6,7 @@ import {TactCompiler} from "@server/languages/tact/compiler/TactCompiler" import {Inspection, InspectionIds} from "./Inspection" import {URI} from "vscode-uri" import {workspaceRoot} from "@server/toolchain" -import * as path from "node:path" +import * as path from "path" import {existsVFS, globalVFS} from "@server/vfs/files-adapter" import {filePathToUri} from "@server/files" diff --git a/server/src/languages/tact/inspections/MistInspection.ts b/server/src/languages/tact/inspections/MistInspection.ts index 666e9a5d..47918495 100644 --- a/server/src/languages/tact/inspections/MistInspection.ts +++ b/server/src/languages/tact/inspections/MistInspection.ts @@ -6,7 +6,7 @@ import {URI} from "vscode-uri" import {MistiAnalyzer} from "@server/languages/tact/compiler/MistiAnalyzer" import {Severity} from "@server/languages/tact/compiler/TactCompiler" import {Inspection, InspectionIds} from "@server/languages/tact/inspections/Inspection" -import * as path from "node:path" +import * as path from "path" import {workspaceRoot} from "@server/toolchain" import {getDocumentSettings} from "@server/settings/settings" import {existsVFS, globalVFS} from "@server/vfs/files-adapter" diff --git a/server/src/languages/tact/intentions/ExtractToFile.ts b/server/src/languages/tact/intentions/ExtractToFile.ts index 92548ac3..51df10b0 100644 --- a/server/src/languages/tact/intentions/ExtractToFile.ts +++ b/server/src/languages/tact/intentions/ExtractToFile.ts @@ -17,7 +17,7 @@ import { Constant, Primitive, } from "@server/languages/tact/psi/Decls" -import * as path from "node:path" +import * as path from "path" import {fileURLToPath} from "node:url" import * as lsp from "vscode-languageserver" import {filePathToUri} from "@server/files" diff --git a/server/src/languages/tact/psi/ImportResolver.ts b/server/src/languages/tact/psi/ImportResolver.ts index a694e300..2d81930c 100644 --- a/server/src/languages/tact/psi/ImportResolver.ts +++ b/server/src/languages/tact/psi/ImportResolver.ts @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright © 2025 TON Studio import type {Node as SyntaxNode} from "web-tree-sitter" -import * as path from "node:path" +import * as path from "path" import type {TactFile} from "./TactFile" import {trimPrefix, trimSuffix} from "@server/utils/strings" import {projectStdlibPath} from "@server/languages/tact/toolchain/toolchain" diff --git a/server/src/languages/tact/psi/TactFile.ts b/server/src/languages/tact/psi/TactFile.ts index eb09174e..90b7b71b 100644 --- a/server/src/languages/tact/psi/TactFile.ts +++ b/server/src/languages/tact/psi/TactFile.ts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // Copyright © 2025 TON Studio -import * as path from "node:path" +import * as path from "path" import {NamedNode} from "./TactNode" import {Constant, Contract, Fun, Message, Primitive, Struct, Trait} from "./Decls" import type {Node as SyntaxNode} from "web-tree-sitter" diff --git a/server/src/languages/tact/toolchain/toolchain.ts b/server/src/languages/tact/toolchain/toolchain.ts index d684333d..537d20a1 100644 --- a/server/src/languages/tact/toolchain/toolchain.ts +++ b/server/src/languages/tact/toolchain/toolchain.ts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // Copyright © 2025 TON Studio -import * as path from "node:path" +import * as path from "path" import * as cp from "node:child_process" import {SpawnSyncReturns} from "node:child_process" import * as console from "node:console" diff --git a/server/src/psi/File.ts b/server/src/psi/File.ts index 8c6fd810..16f2e4d0 100644 --- a/server/src/psi/File.ts +++ b/server/src/psi/File.ts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // Copyright © 2025 TON Studio -import * as path from "node:path" +import * as path from "path" import type {Node as SyntaxNode, Tree} from "web-tree-sitter" import {fileURLToPath} from "node:url" diff --git a/server/src/server.ts b/server/src/server.ts index 06829840..296602de 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -9,7 +9,7 @@ import {index, IndexRoot} from "@server/languages/tact/indexes" import * as lsp from "vscode-languageserver" import {DidChangeWatchedFilesParams, FileChangeType} from "vscode-languageserver" import {TypeBasedSearch} from "@server/languages/tact/search/TypeBasedSearch" -import * as path from "node:path" +import * as path from "path" import {globalVFS} from "@server/vfs/global" import {existsVFS} from "@server/vfs/files-adapter" import type {ClientOptions} from "@shared/config-scheme" diff --git a/server/src/utils/logger.ts b/server/src/utils/logger.ts index 79ad3af2..c8a4de5f 100644 --- a/server/src/utils/logger.ts +++ b/server/src/utils/logger.ts @@ -4,7 +4,7 @@ /* eslint-disable @typescript-eslint/no-base-to-string */ import type {Connection} from "vscode-languageserver" import * as fs from "node:fs" -import * as path from "node:path" +import * as path from "path" export class Logger { private logFile: fs.WriteStream | null = null diff --git a/server/src/vfs/fs-provider.ts b/server/src/vfs/fs-provider.ts index 0888a93e..78c4019f 100644 --- a/server/src/vfs/fs-provider.ts +++ b/server/src/vfs/fs-provider.ts @@ -3,7 +3,7 @@ /* eslint-disable @typescript-eslint/require-await */ import {readFileSync, existsSync, readdirSync, statSync} from "node:fs" -import {join} from "node:path" +import {join} from "path" import {fileURLToPath} from "node:url" import {FileSystemProvider, VirtualFile} from "./types" diff --git a/webpack.config.js b/webpack.config.js index 5d517f47..227f0336 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -9,28 +9,52 @@ const webpack = require("webpack") const distDir = path.resolve(__dirname, "dist") -/**@type {import('webpack').Configuration}*/ -const config = { - mode: "development", - - target: "node", // vscode extensions run in webworker context for VS Code web 📖 -> https://webpack.js.org/configuration/target/#target - - entry: { - server: "./server/src/server.ts", - client: "./client/src/extension.ts", - }, // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/ - output: { - // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/ - path: distDir, - filename: "[name].js", - libraryTarget: "commonjs2", - devtoolModuleFilenameTemplate: "../[resource-path]", +const COPY_FILE_PATTERNS = [ + {from: "./node_modules/web-tree-sitter/tree-sitter.wasm", to: distDir}, + { + from: "./server/src/languages/tact/stubs/stubs.tact", + to: path.join(distDir, "stubs"), }, - devtool: "source-map", - externals: { - vscode: "commonjs vscode", // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/ + { + from: "./server/src/languages/tact/tree-sitter-tact/tree-sitter-tact.wasm", + to: distDir, + }, + { + from: "./server/src/languages/fift/tree-sitter-fift/tree-sitter-fift.wasm", + to: distDir, + }, + { + from: "./server/src/languages/tlb/tree-sitter-tlb/tree-sitter-tlb.wasm", + to: distDir, }, + {from: "./client/src/assets/icons/ton-icon.svg", to: path.join(distDir, "icons")}, + { + from: "./client/src/assets/icons/icon-tact-dark.svg", + to: path.join(distDir, "icons"), + }, + { + from: "./client/src/assets/icons/icon-tasm-dark.svg", + to: path.join(distDir, "icons"), + }, + { + from: "./client/src/assets/icons/icon-tlb-dark.svg", + to: path.join(distDir, "icons"), + }, + { + from: "./client/src/assets/icons/icon-boc-dark.svg", + to: path.join(distDir, "icons"), + }, + { + from: "server/src/languages/tact/completion/data/asm.json", + to: distDir, + }, + {from: "./package.server.json", to: path.join(distDir, "package.json")}, + {from: "./README.md", to: path.join(distDir, "README.md")}, +] +const commonConfig = { + mode: "development", + devtool: "source-map", resolve: { extensions: [".ts", ".js"], alias: { @@ -52,6 +76,31 @@ const config = { }, ], }, +} + +/**@type {import("webpack").Configuration}*/ +const nodeConfig = { + mode: commonConfig.mode, + devtool: commonConfig.devtool, + resolve: { + ...commonConfig.resolve, + fallback: {}, + }, + module: commonConfig.module, + target: "node", + entry: { + server: "./server/src/server.ts", + client: "./client/src/extension.ts", + }, + output: { + path: distDir, + filename: "[name].js", + libraryTarget: "commonjs2", + devtoolModuleFilenameTemplate: "../[resource-path]", + }, + externals: { + vscode: "commonjs vscode", + }, plugins: [ new webpack.BannerPlugin({ banner: "#!/usr/bin/env node", @@ -59,49 +108,58 @@ const config = { include: "server.js", }), new CopyPlugin({ - patterns: [ - {from: "./node_modules/web-tree-sitter/tree-sitter.wasm", to: distDir}, - { - from: "./server/src/languages/tact/stubs/stubs.tact", - to: path.join(distDir, "stubs"), - }, - { - from: "./server/src/languages/tact/tree-sitter-tact/tree-sitter-tact.wasm", - to: distDir, - }, - { - from: "./server/src/languages/fift/tree-sitter-fift/tree-sitter-fift.wasm", - to: distDir, - }, - { - from: "./server/src/languages/tlb/tree-sitter-tlb/tree-sitter-tlb.wasm", - to: distDir, - }, - {from: "./client/src/assets/icons/ton-icon.svg", to: path.join(distDir, "icons")}, - { - from: "./client/src/assets/icons/icon-tact-dark.svg", - to: path.join(distDir, "icons"), - }, - { - from: "./client/src/assets/icons/icon-tasm-dark.svg", - to: path.join(distDir, "icons"), - }, - { - from: "./client/src/assets/icons/icon-tlb-dark.svg", - to: path.join(distDir, "icons"), - }, - { - from: "./client/src/assets/icons/icon-boc-dark.svg", - to: path.join(distDir, "icons"), - }, - { - from: "server/src/languages/tact/completion/data/asm.json", - to: distDir, - }, - {from: "./package.server.json", to: path.join(distDir, "package.json")}, - {from: "./README.md", to: path.join(distDir, "README.md")}, - ], + patterns: COPY_FILE_PATTERNS, + }), + ], +} + +// Конфигурация для VS Code Web (Browser/WebWorker) +/**@type {import("webpack").Configuration}*/ +const webConfig = { + mode: commonConfig.mode, + devtool: commonConfig.devtool, + resolve: { + ...commonConfig.resolve, + fallback: { + path: require.resolve("path-browserify"), + "node:buffer": require.resolve("buffer"), + fs: false, + os: false, + crypto: false, + util: require.resolve("util"), + buffer: require.resolve("buffer"), + stream: require.resolve("stream-browserify"), + child_process: false, + }, + }, + module: commonConfig.module, + target: "webworker", + entry: { + "client-web": "./client/src/extension.ts", + }, + output: { + path: path.join(distDir, "web"), + filename: "[name].js", + libraryTarget: "commonjs2", + devtoolModuleFilenameTemplate: "../[resource-path]", + }, + externals: { + vscode: "commonjs vscode", + }, + plugins: [ + new webpack.ProvidePlugin({ + Buffer: ["buffer", "Buffer"], + process: "process/browser", + }), + new CopyPlugin({ + patterns: COPY_FILE_PATTERNS, }), ], } -module.exports = config + +module.exports = (env, _argv) => { + if (env && env.target === "web") { + return webConfig + } + return nodeConfig +} diff --git a/yarn.lock b/yarn.lock index 3357de3e..d01aa112 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1554,6 +1554,13 @@ __metadata: languageName: node linkType: hard +"@types/path-browserify@npm:^1": + version: 1.0.3 + resolution: "@types/path-browserify@npm:1.0.3" + checksum: 10c0/6ed6de375c210dbc20d171ab547be6065ce9904463ca8ca63443a3b23efc7234ff5400d62be05b9be36fc2e863b77592c2e607896988ad39a45276b8a7e42d70 + languageName: node + linkType: hard + "@types/sarif@npm:^2.1.4": version: 2.1.7 resolution: "@types/sarif@npm:2.1.7" @@ -2382,6 +2389,15 @@ __metadata: languageName: node linkType: hard +"available-typed-arrays@npm:^1.0.7": + version: 1.0.7 + resolution: "available-typed-arrays@npm:1.0.7" + dependencies: + possible-typed-array-names: "npm:^1.0.0" + checksum: 10c0/d07226ef4f87daa01bd0fe80f8f310982e345f372926da2e5296aecc25c41cab440916bbaa4c5e1034b453af3392f67df5961124e4b586df1e99793a1374bdb2 + languageName: node + linkType: hard + "azure-devops-node-api@npm:^12.5.0": version: 12.5.0 resolution: "azure-devops-node-api@npm:12.5.0" @@ -2733,6 +2749,16 @@ __metadata: languageName: node linkType: hard +"call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.2": + version: 1.0.2 + resolution: "call-bind-apply-helpers@npm:1.0.2" + dependencies: + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + checksum: 10c0/47bd9901d57b857590431243fea704ff18078b16890a6b3e021e12d279bbf211d039155e27d7566b374d49ee1f8189344bac9833dec7a20cdec370506361c938 + languageName: node + linkType: hard + "call-bind-apply-helpers@npm:^1.0.1": version: 1.0.1 resolution: "call-bind-apply-helpers@npm:1.0.1" @@ -2743,6 +2769,18 @@ __metadata: languageName: node linkType: hard +"call-bind@npm:^1.0.8": + version: 1.0.8 + resolution: "call-bind@npm:1.0.8" + dependencies: + call-bind-apply-helpers: "npm:^1.0.0" + es-define-property: "npm:^1.0.0" + get-intrinsic: "npm:^1.2.4" + set-function-length: "npm:^1.2.2" + checksum: 10c0/a13819be0681d915144467741b69875ae5f4eba8961eb0bf322aab63ec87f8250eb6d6b0dcbb2e1349876412a56129ca338592b3829ef4343527f5f18a0752d4 + languageName: node + linkType: hard + "call-bound@npm:^1.0.2": version: 1.0.3 resolution: "call-bound@npm:1.0.3" @@ -2753,6 +2791,16 @@ __metadata: languageName: node linkType: hard +"call-bound@npm:^1.0.3, call-bound@npm:^1.0.4": + version: 1.0.4 + resolution: "call-bound@npm:1.0.4" + dependencies: + call-bind-apply-helpers: "npm:^1.0.2" + get-intrinsic: "npm:^1.3.0" + checksum: 10c0/f4796a6a0941e71c766aea672f63b72bc61234c4f4964dc6d7606e3664c307e7d77845328a8f3359ce39ddb377fed67318f9ee203dea1d47e46165dcf2917644 + languageName: node + linkType: hard + "callsites@npm:^3.0.0": version: 3.1.0 resolution: "callsites@npm:3.1.0" @@ -3286,6 +3334,17 @@ __metadata: languageName: node linkType: hard +"define-data-property@npm:^1.1.4": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" + dependencies: + es-define-property: "npm:^1.0.0" + es-errors: "npm:^1.3.0" + gopd: "npm:^1.0.1" + checksum: 10c0/dea0606d1483eb9db8d930d4eac62ca0fa16738b0b3e07046cddfacf7d8c868bbe13fa0cb263eb91c7d0d527960dc3f2f2471a69ed7816210307f6744fe62e37 + languageName: node + linkType: hard + "define-lazy-prop@npm:^3.0.0": version: 3.0.0 resolution: "define-lazy-prop@npm:3.0.0" @@ -3523,7 +3582,7 @@ __metadata: languageName: node linkType: hard -"es-define-property@npm:^1.0.1": +"es-define-property@npm:^1.0.0, es-define-property@npm:^1.0.1": version: 1.0.1 resolution: "es-define-property@npm:1.0.1" checksum: 10c0/3f54eb49c16c18707949ff25a1456728c883e81259f045003499efba399c08bad00deebf65cccde8c0e07908c1a225c9d472b7107e558f2a48e28d530e34527c @@ -3544,7 +3603,7 @@ __metadata: languageName: node linkType: hard -"es-object-atoms@npm:^1.0.0": +"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1": version: 1.1.1 resolution: "es-object-atoms@npm:1.1.1" dependencies: @@ -4024,6 +4083,15 @@ __metadata: languageName: node linkType: hard +"for-each@npm:^0.3.5": + version: 0.3.5 + resolution: "for-each@npm:0.3.5" + dependencies: + is-callable: "npm:^1.2.7" + checksum: 10c0/0e0b50f6a843a282637d43674d1fb278dda1dd85f4f99b640024cfb10b85058aac0cc781bf689d5fe50b4b7f638e91e548560723a4e76e04fe96ae35ef039cee + languageName: node + linkType: hard + "foreground-child@npm:^3.1.0, foreground-child@npm:^3.1.1": version: 3.3.0 resolution: "foreground-child@npm:3.3.0" @@ -4127,6 +4195,24 @@ __metadata: languageName: node linkType: hard +"get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.3.0": + version: 1.3.0 + resolution: "get-intrinsic@npm:1.3.0" + dependencies: + call-bind-apply-helpers: "npm:^1.0.2" + es-define-property: "npm:^1.0.1" + es-errors: "npm:^1.3.0" + es-object-atoms: "npm:^1.1.1" + function-bind: "npm:^1.1.2" + get-proto: "npm:^1.0.1" + gopd: "npm:^1.2.0" + has-symbols: "npm:^1.1.0" + hasown: "npm:^2.0.2" + math-intrinsics: "npm:^1.1.0" + checksum: 10c0/52c81808af9a8130f581e6a6a83e1ba4a9f703359e7a438d1369a5267a25412322f03dcbd7c549edaef0b6214a0630a28511d7df0130c93cfd380f4fa0b5b66a + languageName: node + linkType: hard + "get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6": version: 1.2.7 resolution: "get-intrinsic@npm:1.2.7" @@ -4152,7 +4238,7 @@ __metadata: languageName: node linkType: hard -"get-proto@npm:^1.0.0": +"get-proto@npm:^1.0.0, get-proto@npm:^1.0.1": version: 1.0.1 resolution: "get-proto@npm:1.0.1" dependencies: @@ -4325,7 +4411,7 @@ __metadata: languageName: node linkType: hard -"gopd@npm:^1.2.0": +"gopd@npm:^1.0.1, gopd@npm:^1.2.0": version: 1.2.0 resolution: "gopd@npm:1.2.0" checksum: 10c0/50fff1e04ba2b7737c097358534eacadad1e68d24cccee3272e04e007bed008e68d2614f3987788428fd192a5ae3889d08fb2331417e4fc4a9ab366b2043cead @@ -4360,6 +4446,15 @@ __metadata: languageName: node linkType: hard +"has-property-descriptors@npm:^1.0.2": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" + dependencies: + es-define-property: "npm:^1.0.0" + checksum: 10c0/253c1f59e80bb476cf0dde8ff5284505d90c3bdb762983c3514d36414290475fe3fd6f574929d84de2a8eec00d35cf07cb6776205ff32efd7c50719125f00236 + languageName: node + linkType: hard + "has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0": version: 1.1.0 resolution: "has-symbols@npm:1.1.0" @@ -4564,7 +4659,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3": +"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3, inherits@npm:~2.0.4": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 @@ -4612,6 +4707,16 @@ __metadata: languageName: node linkType: hard +"is-arguments@npm:^1.0.4": + version: 1.2.0 + resolution: "is-arguments@npm:1.2.0" + dependencies: + call-bound: "npm:^1.0.2" + has-tostringtag: "npm:^1.0.2" + checksum: 10c0/6377344b31e9fcb707c6751ee89b11f132f32338e6a782ec2eac9393b0cbd32235dad93052998cda778ee058754860738341d8114910d50ada5615912bb929fc + languageName: node + linkType: hard + "is-arrayish@npm:^0.2.1": version: 0.2.1 resolution: "is-arrayish@npm:0.2.1" @@ -4644,6 +4749,13 @@ __metadata: languageName: node linkType: hard +"is-callable@npm:^1.2.7": + version: 1.2.7 + resolution: "is-callable@npm:1.2.7" + checksum: 10c0/ceebaeb9d92e8adee604076971dd6000d38d6afc40bb843ea8e45c5579b57671c3f3b50d7f04869618242c6cee08d1b67806a8cb8edaaaf7c0748b3720d6066f + languageName: node + linkType: hard + "is-core-module@npm:^2.16.0": version: 2.16.1 resolution: "is-core-module@npm:2.16.1" @@ -4690,6 +4802,18 @@ __metadata: languageName: node linkType: hard +"is-generator-function@npm:^1.0.7": + version: 1.1.0 + resolution: "is-generator-function@npm:1.1.0" + dependencies: + call-bound: "npm:^1.0.3" + get-proto: "npm:^1.0.0" + has-tostringtag: "npm:^1.0.2" + safe-regex-test: "npm:^1.1.0" + checksum: 10c0/fdfa96c8087bf36fc4cd514b474ba2ff404219a4dd4cfa6cf5426404a1eed259bdcdb98f082a71029a48d01f27733e3436ecc6690129a7ec09cb0434bee03a2a + languageName: node + linkType: hard + "is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1": version: 4.0.3 resolution: "is-glob@npm:4.0.3" @@ -4761,6 +4885,18 @@ __metadata: languageName: node linkType: hard +"is-regex@npm:^1.2.1": + version: 1.2.1 + resolution: "is-regex@npm:1.2.1" + dependencies: + call-bound: "npm:^1.0.2" + gopd: "npm:^1.2.0" + has-tostringtag: "npm:^1.0.2" + hasown: "npm:^2.0.2" + checksum: 10c0/1d3715d2b7889932349241680032e85d0b492cfcb045acb75ffc2c3085e8d561184f1f7e84b6f8321935b4aea39bc9c6ba74ed595b57ce4881a51dfdbc214e04 + languageName: node + linkType: hard + "is-stream@npm:^2.0.0": version: 2.0.1 resolution: "is-stream@npm:2.0.1" @@ -4768,6 +4904,15 @@ __metadata: languageName: node linkType: hard +"is-typed-array@npm:^1.1.3": + version: 1.1.15 + resolution: "is-typed-array@npm:1.1.15" + dependencies: + which-typed-array: "npm:^1.1.16" + checksum: 10c0/415511da3669e36e002820584e264997ffe277ff136643a3126cc949197e6ca3334d0f12d084e83b1994af2e9c8141275c741cf2b7da5a2ff62dd0cac26f76c4 + languageName: node + linkType: hard + "is-unicode-supported@npm:^0.1.0": version: 0.1.0 resolution: "is-unicode-supported@npm:0.1.0" @@ -6746,6 +6891,13 @@ __metadata: languageName: node linkType: hard +"path-browserify@npm:^1.0.1": + version: 1.0.1 + resolution: "path-browserify@npm:1.0.1" + checksum: 10c0/8b8c3fd5c66bd340272180590ae4ff139769e9ab79522e2eb82e3d571a89b8117c04147f65ad066dccfb42fcad902e5b7d794b3d35e0fd840491a8ddbedf8c66 + languageName: node + linkType: hard + "path-exists@npm:^4.0.0": version: 4.0.0 resolution: "path-exists@npm:4.0.0" @@ -6866,6 +7018,13 @@ __metadata: languageName: node linkType: hard +"possible-typed-array-names@npm:^1.0.0": + version: 1.1.0 + resolution: "possible-typed-array-names@npm:1.1.0" + checksum: 10c0/c810983414142071da1d644662ce4caebce890203eb2bc7bf119f37f3fe5796226e117e6cca146b521921fa6531072674174a3325066ac66fce089a53e1e5196 + languageName: node + linkType: hard + "prebuild-install@npm:^7.0.1": version: 7.1.3 resolution: "prebuild-install@npm:7.1.3" @@ -6929,6 +7088,13 @@ __metadata: languageName: node linkType: hard +"process@npm:^0.11.10": + version: 0.11.10 + resolution: "process@npm:0.11.10" + checksum: 10c0/40c3ce4b7e6d4b8c3355479df77aeed46f81b279818ccdc500124e6a5ab882c0cc81ff7ea16384873a95a74c4570b01b120f287abbdd4c877931460eca6084b3 + languageName: node + linkType: hard + "promise-retry@npm:^2.0.1": version: 2.0.1 resolution: "promise-retry@npm:2.0.1" @@ -7082,7 +7248,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0": +"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.5.0": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" dependencies: @@ -7327,6 +7493,17 @@ __metadata: languageName: node linkType: hard +"safe-regex-test@npm:^1.1.0": + version: 1.1.0 + resolution: "safe-regex-test@npm:1.1.0" + dependencies: + call-bound: "npm:^1.0.2" + es-errors: "npm:^1.3.0" + is-regex: "npm:^1.2.1" + checksum: 10c0/f2c25281bbe5d39cddbbce7f86fca5ea9b3ce3354ea6cd7c81c31b006a5a9fff4286acc5450a3b9122c56c33eba69c56b9131ad751457b2b4a585825e6a10665 + languageName: node + linkType: hard + "safer-buffer@npm:>= 2.1.2 < 3.0.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" @@ -7417,6 +7594,20 @@ __metadata: languageName: node linkType: hard +"set-function-length@npm:^1.2.2": + version: 1.2.2 + resolution: "set-function-length@npm:1.2.2" + dependencies: + define-data-property: "npm:^1.1.4" + es-errors: "npm:^1.3.0" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.4" + gopd: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.2" + checksum: 10c0/82850e62f412a258b71e123d4ed3873fa9377c216809551192bb6769329340176f109c2eeae8c22a8d386c76739855f78e8716515c818bcaef384b51110f0f3c + languageName: node + linkType: hard + "setimmediate@npm:^1.0.5": version: 1.0.5 resolution: "setimmediate@npm:1.0.5" @@ -7705,6 +7896,16 @@ __metadata: languageName: node linkType: hard +"stream-browserify@npm:^3.0.0": + version: 3.0.0 + resolution: "stream-browserify@npm:3.0.0" + dependencies: + inherits: "npm:~2.0.4" + readable-stream: "npm:^3.5.0" + checksum: 10c0/ec3b975a4e0aa4b3dc5e70ffae3fc8fd29ac725353a14e72f213dff477b00330140ad014b163a8cbb9922dfe90803f81a5ea2b269e1bbfd8bd71511b88f889ad + languageName: node + linkType: hard + "string-length@npm:^4.0.1": version: 4.0.2 resolution: "string-length@npm:4.0.2" @@ -8487,6 +8688,19 @@ __metadata: languageName: node linkType: hard +"util@npm:^0.12.5": + version: 0.12.5 + resolution: "util@npm:0.12.5" + dependencies: + inherits: "npm:^2.0.3" + is-arguments: "npm:^1.0.4" + is-generator-function: "npm:^1.0.7" + is-typed-array: "npm:^1.1.3" + which-typed-array: "npm:^1.1.2" + checksum: 10c0/c27054de2cea2229a66c09522d0fa1415fb12d861d08523a8846bf2e4cbf0079d4c3f725f09dcb87493549bcbf05f5798dce1688b53c6c17201a45759e7253f3 + languageName: node + linkType: hard + "uuid@npm:^8.3.0": version: 8.3.2 resolution: "uuid@npm:8.3.2" @@ -8609,10 +8823,12 @@ __metadata: "@types/jest": "npm:^29.5.14" "@types/mocha": "npm:^10.0.6" "@types/node": "npm:^22.2.0" + "@types/path-browserify": "npm:^1" "@types/vscode": "npm:^1.63.0" "@vscode/test-cli": "npm:^0.0.10" "@vscode/test-electron": "npm:^2.4.1" "@vscode/vsce": "npm:^3.0.0" + buffer: "npm:^6.0.3" c8: "npm:^10.1.3" change-case: "npm:^5.4.4" copy-webpack-plugin: "npm:^12.0.2" @@ -8624,7 +8840,10 @@ __metadata: husky: "npm:^9.1.7" jest: "npm:^29.7.0" mocha: "npm:^10.3.0" + path-browserify: "npm:^1.0.1" prettier: "npm:3.4.2" + process: "npm:^0.11.10" + stream-browserify: "npm:^3.0.0" tree-sitter-cli: "npm:^0.25.0" ts-jest: "npm:^29.2.6" ts-loader: "npm:^9.5.1" @@ -8632,6 +8851,7 @@ __metadata: tsconfig-paths-webpack-plugin: "npm:^4.2.0" typescript: "npm:^5.7.0" typescript-eslint: "npm:^8.22.0" + util: "npm:^0.12.5" vscode-languageclient: "npm:^8.0.2" vscode-languageserver: "npm:^8.0.2" vscode-languageserver-textdocument: "npm:^1.0.7" @@ -8792,6 +9012,21 @@ __metadata: languageName: node linkType: hard +"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.2": + version: 1.1.19 + resolution: "which-typed-array@npm:1.1.19" + dependencies: + available-typed-arrays: "npm:^1.0.7" + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.4" + for-each: "npm:^0.3.5" + get-proto: "npm:^1.0.1" + gopd: "npm:^1.2.0" + has-tostringtag: "npm:^1.0.2" + checksum: 10c0/702b5dc878addafe6c6300c3d0af5983b175c75fcb4f2a72dfc3dd38d93cf9e89581e4b29c854b16ea37e50a7d7fca5ae42ece5c273d8060dcd603b2404bbb3f + languageName: node + linkType: hard + "which@npm:^2.0.1": version: 2.0.2 resolution: "which@npm:2.0.2" From 4534d4d90ce1d3b8e1c0aa6e466b1a64f5796345 Mon Sep 17 00:00:00 2001 From: i582 <51853996+i582@users.noreply.github.com> Date: Fri, 30 May 2025 21:12:10 +0400 Subject: [PATCH 2/5] fixes --- .prettierignore | 2 + client/src/commands/openBocCommand.ts | 33 -- .../src/commands/saveBocDecompiledCommand.ts | 64 --- client/src/extension.ts | 160 ++++-- client/src/providers/BocDecompilerProvider.ts | 79 --- client/src/providers/BocEditorProvider.ts | 43 -- client/src/providers/BocFileSystemProvider.ts | 60 --- eslint.config.mjs | 2 +- package.json | 6 +- server/src/connection.ts | 27 +- server/src/files.ts | 2 +- server/src/indexing-root.ts | 2 +- server/src/languages/tact/compiler/sha256.ts | 4 +- .../languages/tact/completion/data/types.ts | 2 +- server/src/languages/tact/indexes/index.ts | 2 +- .../tact/intentions/ExtractToFile.ts | 2 +- .../src/languages/tact/toolchain/toolchain.ts | 40 +- server/src/psi/File.ts | 2 +- server/src/server.ts | 9 +- server/src/toolchain-manager.ts | 2 +- server/src/utils/logger.ts | 214 ++++---- server/src/vfs/fs-provider.ts | 4 +- tsconfig.json | 2 +- webpack.config.js | 10 +- yarn.lock | 505 +++++++++++++++--- 25 files changed, 718 insertions(+), 560 deletions(-) delete mode 100644 client/src/commands/openBocCommand.ts delete mode 100644 client/src/commands/saveBocDecompiledCommand.ts delete mode 100644 client/src/providers/BocDecompilerProvider.ts delete mode 100644 client/src/providers/BocEditorProvider.ts delete mode 100644 client/src/providers/BocFileSystemProvider.ts diff --git a/.prettierignore b/.prettierignore index 122fff60..dcc99f4e 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1 +1,3 @@ server/src/languages/tact/compiler/fmt/cst/cst-parser.ts +.vscode-test-web/ +.mypy_cache/ diff --git a/client/src/commands/openBocCommand.ts b/client/src/commands/openBocCommand.ts deleted file mode 100644 index a6ffcc89..00000000 --- a/client/src/commands/openBocCommand.ts +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT -// Copyright © 2025 TON Studio -import * as vscode from "vscode" -import {BocDecompilerProvider} from "../providers/BocDecompilerProvider" -import {openBocFilePicker} from "./saveBocDecompiledCommand" -import {Disposable} from "vscode" - -export function registerOpenBocCommand(_context: vscode.ExtensionContext): Disposable { - return vscode.commands.registerCommand( - "tact.openBocFile", - async (fileUri: vscode.Uri | undefined) => { - try { - const actualFileUri = fileUri ?? (await openBocFilePicker()) - if (actualFileUri === undefined) return - - const decompileUri = actualFileUri.with({ - scheme: BocDecompilerProvider.scheme, - path: actualFileUri.path + ".decompiled.fif", - }) - - const doc = await vscode.workspace.openTextDocument(decompileUri) - await vscode.window.showTextDocument(doc, { - preview: true, - viewColumn: vscode.ViewColumn.Active, - }) - } catch (error: unknown) { - console.error("Error in openBocCommand:", error) - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - vscode.window.showErrorMessage(`Failed to open BoC file: ${error}`) - } - }, - ) -} diff --git a/client/src/commands/saveBocDecompiledCommand.ts b/client/src/commands/saveBocDecompiledCommand.ts deleted file mode 100644 index 53cd9fb8..00000000 --- a/client/src/commands/saveBocDecompiledCommand.ts +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: MIT -// Copyright © 2025 TON Studio -import * as vscode from "vscode" -import {BocDecompilerProvider} from "../providers/BocDecompilerProvider" - -export function registerSaveBocDecompiledCommand( - _context: vscode.ExtensionContext, -): vscode.Disposable { - return vscode.commands.registerCommand( - "tact.saveBocDecompiled", - async (fileUri: vscode.Uri | undefined) => { - try { - await saveBoc(fileUri) - } catch (error: unknown) { - console.error("Error in saveBocDecompiledCommand:", error) - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - vscode.window.showErrorMessage(`Failed to save decompiled BщC: ${error}`) - } - }, - ) -} - -export async function openBocFilePicker(): Promise { - const files = await vscode.window.showOpenDialog({ - canSelectFiles: true, - canSelectFolders: false, - canSelectMany: false, - filters: { - "BOC files": ["boc"], - }, - }) - if (!files || files.length === 0) { - return undefined - } - return files[0] -} - -async function saveBoc(fileUri: vscode.Uri | undefined): Promise { - const actualFileUri = fileUri ?? (await openBocFilePicker()) - if (actualFileUri === undefined) return - - const decompiler = new BocDecompilerProvider() - - const decompileUri = actualFileUri.with({ - scheme: BocDecompilerProvider.scheme, - path: actualFileUri.path + ".decompiled.fif", - }) - const content = await decompiler.provideTextDocumentContent(decompileUri) - - const outputPath = actualFileUri.fsPath + ".decompiled.fif" - - const bytes = new TextEncoder().encode(content) - vscode.workspace.fs.writeFile(vscode.Uri.file(outputPath), bytes) - - const relativePath = vscode.workspace.asRelativePath(outputPath) - vscode.window.showInformationMessage(`Decompiled BOC saved to: ${relativePath}`) - - const savedFileUri = vscode.Uri.file(outputPath) - const doc = await vscode.workspace.openTextDocument(savedFileUri) - await vscode.window.showTextDocument(doc, { - preview: false, - viewColumn: vscode.ViewColumn.Active, - }) -} diff --git a/client/src/extension.ts b/client/src/extension.ts index 2ad54211..90e0a6b4 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -3,13 +3,6 @@ import * as vscode from "vscode" import * as path from "path" import {Utils as vscode_uri} from "vscode-uri" -import { - LanguageClient, - LanguageClientOptions, - RevealOutputChannelOn, - ServerOptions, - TransportKind, -} from "vscode-languageclient/node" import {consoleError, createClientLog} from "./client-log" import {getClientConfiguration} from "./client-config" import { @@ -26,15 +19,15 @@ import { SearchByTypeParams, SearchByTypeResponse, } from "@shared/shared-msgtypes" -import type {Location} from "vscode-languageclient" -import * as lsp from "vscode-languageserver-protocol" +import type {Location} from "vscode-languageclient/browser" +import type * as lspCommon from "vscode-languageclient/lib/common/client" import type {ClientOptions} from "@shared/config-scheme" import {registerBuildTasks} from "./build-system" import {Range, Position} from "vscode" import {detectPackageManager, PackageManager} from "./utils/package-manager" import {ToolchainConfig} from "@server/settings/settings" -let client: LanguageClient | null = null +let client: lspCommon.BaseLanguageClient | null = null let gasStatusBarItem: vscode.StatusBarItem | null = null let cachedToolchainInfo: SetToolchainVersionParams | null = null @@ -56,50 +49,109 @@ export function deactivate(): Thenable | undefined { async function startServer(context: vscode.ExtensionContext): Promise { const disposables: vscode.Disposable[] = [] - const clientOptions: LanguageClientOptions = { - outputChannel: createClientLog(), - revealOutputChannelOn: RevealOutputChannelOn.Never, - documentSelector: [ - {scheme: "file", language: "tact"}, - {scheme: "file", language: "fift"}, - {scheme: "file", language: "tlb"}, - {scheme: "untitled", language: "tact"}, - ], - synchronize: { - configurationSection: "tact", - fileEvents: vscode.workspace.createFileSystemWatcher("**/*.{tact,tlb}"), - }, - initializationOptions: { - clientConfig: getClientConfiguration(), - treeSitterWasmUri: vscode_uri.joinPath(context.extensionUri, "./dist/tree-sitter.wasm") - .fsPath, - tactLangWasmUri: vscode_uri.joinPath( - context.extensionUri, - "./dist/tree-sitter-tact.wasm", - ).fsPath, - fiftLangWasmUri: vscode_uri.joinPath( - context.extensionUri, - "./dist/tree-sitter-fift.wasm", - ).fsPath, - tlbLangWasmUri: vscode_uri.joinPath(context.extensionUri, "./dist/tree-sitter-tlb.wasm") - .fsPath, - } as ClientOptions, - } + if (typeof globalThis === "undefined") { + const lspNode = await import("vscode-languageclient/node") + + const clientOptions: lspCommon.LanguageClientOptions = { + outputChannel: createClientLog(), + revealOutputChannelOn: lspNode.RevealOutputChannelOn.Never, + documentSelector: [ + {scheme: "file", language: "tact"}, + {scheme: "file", language: "fift"}, + {scheme: "file", language: "tlb"}, + {scheme: "untitled", language: "tact"}, + ], + synchronize: { + configurationSection: "tact", + fileEvents: vscode.workspace.createFileSystemWatcher("**/*.{tact,tlb}"), + }, + initializationOptions: { + clientConfig: getClientConfiguration(), + treeSitterWasmUri: vscode_uri.joinPath( + context.extensionUri, + "./dist/tree-sitter.wasm", + ).fsPath, + tactLangWasmUri: vscode_uri.joinPath( + context.extensionUri, + "./dist/tree-sitter-tact.wasm", + ).fsPath, + fiftLangWasmUri: vscode_uri.joinPath( + context.extensionUri, + "./dist/tree-sitter-fift.wasm", + ).fsPath, + tlbLangWasmUri: vscode_uri.joinPath( + context.extensionUri, + "./dist/tree-sitter-tlb.wasm", + ).fsPath, + } as ClientOptions, + } + + const serverModule = context.asAbsolutePath(path.join("dist", "server.js")) + + const serverOptions = { + run: { + module: serverModule, + transport: lspNode.TransportKind.ipc, + }, + debug: { + module: serverModule, + transport: lspNode.TransportKind.ipc, + options: {execArgv: ["--nolazy", "--inspect=6009"]}, // same port as in .vscode/launch.json + }, + } + client = new lspNode.LanguageClient( + "tact-server", + "Tact Language Server", + serverOptions, + clientOptions, + ) + } else { + const lspBrowser = await import("vscode-languageclient/browser") + const clientOptions: lspCommon.LanguageClientOptions = { + outputChannel: createClientLog(), + revealOutputChannelOn: lspBrowser.RevealOutputChannelOn.Never, + documentSelector: [ + {scheme: "file", language: "tact"}, + {scheme: "file", language: "fift"}, + {scheme: "file", language: "tlb"}, + {scheme: "untitled", language: "tact"}, + {scheme: "memfs", language: "tact"}, + ], + synchronize: { + configurationSection: "tact", + fileEvents: vscode.workspace.createFileSystemWatcher("**/*.{tact,tlb}"), + }, + initializationOptions: { + clientConfig: getClientConfiguration(), + treeSitterWasmUri: vscode_uri.joinPath( + context.extensionUri, + "./dist/tree-sitter.wasm", + ).fsPath, + tactLangWasmUri: vscode_uri.joinPath( + context.extensionUri, + "./dist/tree-sitter-tact.wasm", + ).fsPath, + fiftLangWasmUri: vscode_uri.joinPath( + context.extensionUri, + "./dist/tree-sitter-fift.wasm", + ).fsPath, + tlbLangWasmUri: vscode_uri.joinPath( + context.extensionUri, + "./dist/tree-sitter-tlb.wasm", + ).fsPath, + } as ClientOptions, + } - const serverModule = context.asAbsolutePath(path.join("dist", "server.js")) - - const serverOptions: ServerOptions = { - run: { - module: serverModule, - transport: TransportKind.ipc, - }, - debug: { - module: serverModule, - transport: TransportKind.ipc, - options: {execArgv: ["--nolazy", "--inspect=6009"]}, // same port as in .vscode/launch.json - }, + const serverModule = context.asAbsolutePath(path.join("dist", "server.js")) + + const worker = new Worker(serverModule) + client = new lspBrowser.LanguageClient( + "tact-server", + "Tact Language Server", + clientOptions, + worker, + ) } - client = new LanguageClient("tact-server", "Tact Language Server", serverOptions, clientOptions) await client.start() @@ -214,7 +266,7 @@ const onExtractFile = async (params: ExtractToFileIntention): Promise => { } async function showReferencesImpl( - client: LanguageClient | undefined, + client: lspCommon.BaseLanguageClient | undefined, uri: string, position: Position, ): Promise { @@ -463,7 +515,7 @@ Node.js: ${info.environment.nodeVersion ?? "Unknown"}` // Convert results to QuickPickItems // eslint-disable-next-line functional/type-declaration-immutability interface SearchResultItem extends vscode.QuickPickItem { - readonly location: lsp.Location + readonly location: Location readonly resultKind: string } diff --git a/client/src/providers/BocDecompilerProvider.ts b/client/src/providers/BocDecompilerProvider.ts deleted file mode 100644 index f063033b..00000000 --- a/client/src/providers/BocDecompilerProvider.ts +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: MIT -// Copyright © 2025 TON Studio -import * as vscode from "vscode" -import {AssemblyWriter, Cell, debugSymbols, disassembleRoot} from "@tact-lang/opcode" - -export class BocDecompilerProvider implements vscode.TextDocumentContentProvider { - private readonly _onDidChange: vscode.EventEmitter = new vscode.EventEmitter() - public readonly onDidChange: vscode.Event = this._onDidChange.event - - private readonly lastModified: Map = new Map() - - public static scheme: string = "boc-decompiled" - - public async provideTextDocumentContent(uri: vscode.Uri): Promise { - const bocUri = this.getBocPath(uri) - - try { - return await this.decompileBoc(bocUri) - } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error) - return this.formatError(errorMessage) - } - } - - private getBocPath(uri: vscode.Uri): vscode.Uri { - console.log("Original URI:", uri.toString()) - const bocPath = uri.fsPath.replace(".decompiled.fif", "") - console.log("BOC path:", bocPath) - return vscode.Uri.file(bocPath) - } - - private async decompileBoc(bocUri: vscode.Uri): Promise { - try { - const rawContent = await vscode.workspace.fs.readFile(bocUri) - const content = Buffer.from(rawContent).toString("base64") - const cell = Cell.fromBase64(content) - const program = disassembleRoot(cell, { - computeRefs: true, - }) - - const output = AssemblyWriter.write(program, { - useAliases: true, - debugSymbols: debugSymbols, - }) - - return this.formatDecompiledOutput(output, bocUri) - } catch (error: unknown) { - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - throw new Error(`Decompilation failed: ${error}`) - } - } - - private formatDecompiledOutput(output: string, bocUri: vscode.Uri): string { - const header = [ - "// Decompiled BOC file", - "// Note: This is auto-generated code", - `// Time: ${new Date().toISOString()}`, - `// Source: ${bocUri.fsPath}`, - "", - "", - ].join("\n") - - return header + output - } - - private formatError(error: string): string { - return [ - "// Failed to decompile BOC file", - "// Error: " + error, - "// Time: " + new Date().toISOString(), - ].join("\n") - } - - public update(uri: vscode.Uri): void { - const bocUri = this.getBocPath(uri) - this.lastModified.set(bocUri, new Date()) - this._onDidChange.fire(uri) - } -} diff --git a/client/src/providers/BocEditorProvider.ts b/client/src/providers/BocEditorProvider.ts deleted file mode 100644 index 74d7ebb9..00000000 --- a/client/src/providers/BocEditorProvider.ts +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT -// Copyright © 2025 TON Studio -import * as vscode from "vscode" -import {BocDecompilerProvider} from "./BocDecompilerProvider" - -export class BocEditorProvider implements vscode.CustomReadonlyEditorProvider { - public static register(): vscode.Disposable { - return vscode.window.registerCustomEditorProvider("boc.editor", new BocEditorProvider(), { - supportsMultipleEditorsPerDocument: false, - }) - } - - public openCustomDocument( - uri: vscode.Uri, - _openContext: vscode.CustomDocumentOpenContext, - _token: vscode.CancellationToken, - ): {uri: vscode.Uri; dispose(): void} { - return { - uri, - dispose: () => {}, - } - } - - public async resolveCustomEditor( - document: {uri: vscode.Uri}, - webviewPanel: vscode.WebviewPanel, - _token: vscode.CancellationToken, - ): Promise { - const decompileUri = document.uri.with({ - scheme: BocDecompilerProvider.scheme, - path: document.uri.path + ".decompiled.fif", - }) - - const doc = await vscode.workspace.openTextDocument(decompileUri) - await vscode.window.showTextDocument(doc, { - preview: false, - viewColumn: vscode.ViewColumn.Active, - preserveFocus: true, - }) - - webviewPanel.dispose() - } -} diff --git a/client/src/providers/BocFileSystemProvider.ts b/client/src/providers/BocFileSystemProvider.ts deleted file mode 100644 index 3b40c491..00000000 --- a/client/src/providers/BocFileSystemProvider.ts +++ /dev/null @@ -1,60 +0,0 @@ -// SPDX-License-Identifier: MIT -// Copyright © 2025 TON Studio -import * as vscode from "vscode" -import {BocDecompilerProvider} from "./BocDecompilerProvider" - -export class BocFileSystemProvider implements vscode.FileSystemProvider { - private readonly _emitter: vscode.EventEmitter = - new vscode.EventEmitter() - public readonly onDidChangeFile: vscode.Event = this._emitter.event - - public watch(_uri: vscode.Uri): vscode.Disposable { - return new vscode.Disposable(() => {}) - } - - public stat(_uri: vscode.Uri): vscode.FileStat { - return { - type: vscode.FileType.File, - ctime: Date.now(), - mtime: Date.now(), - size: 0, - } - } - - public readDirectory(_uri: vscode.Uri): [string, vscode.FileType][] { - return [] - } - - public createDirectory(_uri: vscode.Uri): void {} - - public async readFile(uri: vscode.Uri): Promise { - console.log("Reading BOC file:", uri.fsPath) - try { - const fileContent = await vscode.workspace.fs.readFile(uri) - console.log("File content length:", fileContent.length) - - const decompileUri = uri.with({ - scheme: BocDecompilerProvider.scheme, - path: uri.path + ".decompiled.fif", - }) - console.log("Decompile URI:", decompileUri.toString()) - - const doc = await vscode.workspace.openTextDocument(decompileUri) - await vscode.window.showTextDocument(doc, { - preview: true, - viewColumn: vscode.ViewColumn.Active, - }) - - return fileContent - } catch (error) { - console.error("Error reading BOC file:", error) - throw vscode.FileSystemError.FileNotFound(uri) - } - } - - public writeFile(_uri: vscode.Uri, _content: Uint8Array): void {} - - public delete(_uri: vscode.Uri): void {} - - public rename(_oldUri: vscode.Uri, _newUri: vscode.Uri): void {} -} diff --git a/eslint.config.mjs b/eslint.config.mjs index d88b76f9..bd072c5a 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,6 +1,6 @@ import path from "path" import tseslint from "typescript-eslint" -import url from "node:url" +import url from "url" import unusedImports from "eslint-plugin-unused-imports" import unicornPlugin from "eslint-plugin-unicorn" import functional from "eslint-plugin-functional" diff --git a/package.json b/package.json index 9c74ee23..a2d3be6a 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "postinstall": "husky" }, "main": "./dist/client", - "browser": "./dist/web/client-web", + "browser": "./dist/web/client", "contributes": { "languages": [ { @@ -676,8 +676,11 @@ }, "dependencies": { "@textlint/markdown-to-ast": "14.4.2", + "buffer": "^6.0.3", "change-case": "^5.4.4", + "crypto-browserify": "^3.12.1", "glob": "^11.0.1", + "url": "^0.11.3", "vscode-languageclient": "^8.0.2", "vscode-languageserver": "^8.0.2", "vscode-languageserver-textdocument": "^1.0.7", @@ -694,7 +697,6 @@ "@vscode/test-cli": "^0.0.10", "@vscode/test-electron": "^2.4.1", "@vscode/vsce": "^3.0.0", - "buffer": "^6.0.3", "c8": "^10.1.3", "copy-webpack-plugin": "^12.0.2", "eslint": "^9.19.0", diff --git a/server/src/connection.ts b/server/src/connection.ts index 3f0b10da..51f5bacc 100644 --- a/server/src/connection.ts +++ b/server/src/connection.ts @@ -1,5 +1,28 @@ // SPDX-License-Identifier: MIT // Copyright © 2025 TON Studio -import {createConnection, ProposedFeatures} from "vscode-languageserver/node" +import * as lspBrowser from "vscode-languageserver/browser" +import * as lspNode from "vscode-languageserver/node" +import {Connection} from "vscode-languageserver" -export const connection = createConnection(ProposedFeatures.all) +declare const self: DedicatedWorkerGlobalScope + +export const isWeb = (): boolean => { + return typeof globalThis !== "undefined" +} + +export const openConnection = (): Connection => { + if (isWeb()) { + const messageReader = new lspBrowser.BrowserMessageReader(self) + const messageWriter = new lspBrowser.BrowserMessageWriter(self) + + messageReader.listen(message => { + console.log("Received message from main thread:", message) + }) + + return lspBrowser.createConnection(messageReader, messageWriter) + } + + return lspNode.createConnection(lspBrowser.ProposedFeatures.all) +} + +export const connection = openConnection() diff --git a/server/src/files.ts b/server/src/files.ts index 753b1b16..2db7a0f1 100644 --- a/server/src/files.ts +++ b/server/src/files.ts @@ -1,7 +1,7 @@ import * as lsp from "vscode-languageserver" import {TextDocument} from "vscode-languageserver-textdocument" import {TactFile} from "@server/languages/tact/psi/TactFile" -import {pathToFileURL} from "node:url" +import {pathToFileURL} from "url" import {createFiftParser, createTactParser, createTlbParser} from "@server/parser" import {readFileVFS, globalVFS} from "@server/vfs/files-adapter" import {FiftFile} from "@server/languages/fift/psi/FiftFile" diff --git a/server/src/indexing-root.ts b/server/src/indexing-root.ts index 43eb426d..f8cc8c50 100644 --- a/server/src/indexing-root.ts +++ b/server/src/indexing-root.ts @@ -2,7 +2,7 @@ // Copyright © 2025 TON Studio import {glob} from "glob" import {index} from "@server/languages/tact/indexes" -import {fileURLToPath} from "node:url" +import {fileURLToPath} from "url" import * as path from "path" import {filePathToUri, findTactFile} from "@server/files" diff --git a/server/src/languages/tact/compiler/sha256.ts b/server/src/languages/tact/compiler/sha256.ts index 491329ca..7ec196f1 100644 --- a/server/src/languages/tact/compiler/sha256.ts +++ b/server/src/languages/tact/compiler/sha256.ts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // Copyright © 2025 TON Studio -import {sha256_sync} from "@ton/crypto" +import * as crypto from "crypto" // Witness tag. Do not use, do not export! const Sha256Tag = Symbol("sha256") @@ -12,7 +12,7 @@ interface Sha256 { export const sha256 = (input: Buffer | string): Sha256 => ({ kind: Sha256Tag, - value: bufferToBigInt(sha256_sync(input)), + value: bufferToBigInt(crypto.createHash("sha256").update(input).digest()), }) /** diff --git a/server/src/languages/tact/completion/data/types.ts b/server/src/languages/tact/completion/data/types.ts index de5229e0..f2706f7f 100644 --- a/server/src/languages/tact/completion/data/types.ts +++ b/server/src/languages/tact/completion/data/types.ts @@ -3,7 +3,7 @@ import * as path from "path" import {Node as SyntaxNode} from "web-tree-sitter" import {globalVFS, readFileVFS} from "@server/vfs/files-adapter" -import {pathToFileURL} from "node:url" +import {pathToFileURL} from "url" export interface AsmInstruction { readonly mnemonic: string diff --git a/server/src/languages/tact/indexes/index.ts b/server/src/languages/tact/indexes/index.ts index 0385a9db..24167baa 100644 --- a/server/src/languages/tact/indexes/index.ts +++ b/server/src/languages/tact/indexes/index.ts @@ -14,7 +14,7 @@ import { import {isNamedFunNode} from "@server/languages/tact/psi/utils" import {ScopeProcessor} from "@server/languages/tact/psi/Reference" import {CACHE} from "@server/languages/tact/cache" -import {fileURLToPath} from "node:url" +import {fileURLToPath} from "url" import {PARSED_FILES_CACHE} from "@server/files" import {ResolveState} from "@server/psi/ResolveState" diff --git a/server/src/languages/tact/intentions/ExtractToFile.ts b/server/src/languages/tact/intentions/ExtractToFile.ts index 51df10b0..7a2f9579 100644 --- a/server/src/languages/tact/intentions/ExtractToFile.ts +++ b/server/src/languages/tact/intentions/ExtractToFile.ts @@ -18,7 +18,7 @@ import { Primitive, } from "@server/languages/tact/psi/Decls" import * as path from "path" -import {fileURLToPath} from "node:url" +import {fileURLToPath} from "url" import * as lsp from "vscode-languageserver" import {filePathToUri} from "@server/files" import {existsVFS, globalVFS} from "@server/vfs/files-adapter" diff --git a/server/src/languages/tact/toolchain/toolchain.ts b/server/src/languages/tact/toolchain/toolchain.ts index 537d20a1..0744d398 100644 --- a/server/src/languages/tact/toolchain/toolchain.ts +++ b/server/src/languages/tact/toolchain/toolchain.ts @@ -1,10 +1,6 @@ // SPDX-License-Identifier: MIT // Copyright © 2025 TON Studio import * as path from "path" -import * as cp from "node:child_process" -import {SpawnSyncReturns} from "node:child_process" -import * as console from "node:console" -import * as os from "node:os" import {EnvironmentInfo, ToolchainInfo} from "@shared/shared-msgtypes" import {existsVFS, globalVFS} from "@server/vfs/files-adapter" import {filePathToUri} from "@server/files" @@ -57,7 +53,7 @@ export class Toolchain { return new Toolchain(foundPath, true, detectionMethod).setVersion() } - public static fromPath(path: string): Toolchain { + public static async fromPath(path: string): Promise { return new Toolchain(path, false, "manual").validate() } @@ -65,13 +61,21 @@ export class Toolchain { return this.version.number.startsWith("1.6") } - public getEnvironmentInfo(): EnvironmentInfo { + public async getEnvironmentInfo(): Promise { + let platform = "web" + let arch = "unknown" + try { + const os = await import("node:os") + platform = os.platform() + arch = os.arch() + + const cp = await import("node:child_process") const result = cp.execSync("node --version", {encoding: "utf8"}) return { nodeVersion: result.trim(), - platform: os.platform(), - arch: os.arch(), + platform: platform, + arch: arch, } } catch { // node version not available @@ -79,8 +83,8 @@ export class Toolchain { return { nodeVersion: undefined, - platform: os.platform(), - arch: os.arch(), + platform: platform, + arch: arch, } } @@ -92,8 +96,9 @@ export class Toolchain { } } - private setVersion(): this { + private async setVersion(): Promise { try { + const cp = await import("node:child_process") const result = cp.execSync(`"${this.compilerPath}" -v`) const rawVersion = result.toString() const lines = rawVersion.split("\n") @@ -108,8 +113,9 @@ export class Toolchain { return this } - private validate(): this { + private async validate(): Promise { try { + const cp = await import("node:child_process") const result = cp.execSync(`"${this.compilerPath}" -v`) const rawVersion = result.toString() const lines = rawVersion.split("\n") @@ -119,6 +125,16 @@ export class Toolchain { commit: lines[1] ?? "", } } catch (error_: unknown) { + interface SpawnSyncReturns { + readonly pid: number + readonly output: (T | null)[] + readonly stdout: T + readonly stderr: T + readonly status: number | null + readonly signal: NodeJS.Signals | null + readonly error?: Error | undefined + } + const error = error_ as SpawnSyncReturns console.log(error.stdout.toString()) diff --git a/server/src/psi/File.ts b/server/src/psi/File.ts index 16f2e4d0..ab3c09ef 100644 --- a/server/src/psi/File.ts +++ b/server/src/psi/File.ts @@ -2,7 +2,7 @@ // Copyright © 2025 TON Studio import * as path from "path" import type {Node as SyntaxNode, Tree} from "web-tree-sitter" -import {fileURLToPath} from "node:url" +import {fileURLToPath} from "url" export class File { public constructor( diff --git a/server/src/server.ts b/server/src/server.ts index 296602de..6c18f2e8 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -25,7 +25,6 @@ import { SetToolchainVersionNotification, SetToolchainVersionParams, } from "@shared/shared-msgtypes" -import {Logger} from "@server/utils/logger" import {CACHE} from "./languages/tact/cache" import {IndexingRoot, IndexingRootKind} from "./indexing-root" import {clearDocumentSettings, getDocumentSettings, TactSettings} from "@server/settings/settings" @@ -41,7 +40,7 @@ import { import {setToolchain, setWorkspaceRoot, toolchain} from "@server/toolchain" import * as toolchainManager from "@server/toolchain-manager" import {formatCode} from "@server/languages/tact/compiler/fmt/fmt" -import {fileURLToPath} from "node:url" +import {fileURLToPath} from "url" import {onFileRenamed, processFileRenaming} from "@server/languages/tact/rename/file-renaming" import {provideSelectionGasConsumption} from "@server/languages/tact/custom/selection-gas-consumption" import {runInspections} from "@server/languages/tact/inspections" @@ -259,7 +258,7 @@ async function initialize(): Promise { await connection.sendNotification(SetToolchainVersionNotification, { version: toolchain.version, toolchain: toolchain.getToolchainInfo(), - environment: toolchain.getEnvironmentInfo(), + environment: await toolchain.getEnvironmentInfo(), } satisfies SetToolchainVersionParams) } else { console.warn(`No active toolchain found for ${settings.toolchain.activeToolchain}`) @@ -500,7 +499,7 @@ connection.onInitialize(async (initParams: lsp.InitializeParams): Promise { - instance.log(...args) - } - console.info = (...args) => { - instance.info(...args) - } - console.warn = (...args) => { - instance.warn(...args) - } - console.error = (...args) => { - instance.error(...args) - } - - Logger.instance = instance - } - return Logger.instance - } - - public static getInstance(): Logger { - if (!Logger.instance) { - throw new Error("Logger not initialized") - } - return Logger.instance - } - - public log(...args: unknown[]): void { - const message = Logger.formatMessage(args) - this.connection.console.log(message) - this.writeToFile(`[LOG] [${Logger.formatDate(new Date())}] ${message}`) - } - - public info(...args: unknown[]): void { - const message = Logger.formatMessage(args) - this.connection.console.info(message) - this.writeToFile(`[INFO] [${Logger.formatDate(new Date())}] ${message}`) - } - - public warn(...args: unknown[]): void { - const message = Logger.formatMessage(args) - this.connection.console.warn(message) - this.writeToFile(`[WARN] [${Logger.formatDate(new Date())}] ${message}`) - } - - public error(...args: unknown[]): void { - const message = Logger.formatMessage(args) - this.connection.console.error(message) - this.writeToFile(`[ERROR] [${Logger.formatDate(new Date())}] ${message}`) - } - - public dispose(): void { - if (this.logFile) { - this.logFile.end() - this.logFile = null - } - } - - private static formatDate(date: Date): string { - const pad = (n: number): string => n.toString().padStart(2, "0") - - const year = date.getFullYear().toString() - const month = pad(date.getMonth() + 1) - const day = pad(date.getDate()) - const hours = pad(date.getHours()) - const minutes = pad(date.getMinutes()) - const seconds = pad(date.getSeconds()) - - return `${day}-${month}-${year} ${hours}:${minutes}:${seconds}` - } - - private static formatMessage(args: unknown[]): string { - return args - .filter(arg => arg !== undefined) - .map(arg => (typeof arg === "object" ? JSON.stringify(arg) : arg.toString())) - .join(" ") - } - - private writeToFile(message: string): void { - if (this.logFile) { - this.logFile.write(message + "\n") - } - } -} +// import type {Connection} from "vscode-languageserver" +// import * as fs from "node:fs" +// import * as path from "path" +// +// export class Logger { +// private logFile: fs.WriteStream | null = null +// private static instance: Logger | null = null +// +// private constructor( +// private readonly connection: Connection, +// logPath?: string, +// ) { +// if (logPath !== undefined) { +// const logDir = path.dirname(logPath) +// if (!fs.existsSync(logDir)) { +// fs.mkdirSync(logDir, {recursive: true}) +// } +// this.logFile = fs.createWriteStream(logPath, {flags: "a"}) +// } +// } +// +// public static initialize(connection: Connection, logPath?: string): Logger { +// if (!Logger.instance) { +// const instance = new Logger(connection, logPath) +// +// console.log = (...args) => { +// instance.log(...args) +// } +// console.info = (...args) => { +// instance.info(...args) +// } +// console.warn = (...args) => { +// instance.warn(...args) +// } +// console.error = (...args) => { +// instance.error(...args) +// } +// +// Logger.instance = instance +// } +// return Logger.instance +// } +// +// public static getInstance(): Logger { +// if (!Logger.instance) { +// throw new Error("Logger not initialized") +// } +// return Logger.instance +// } +// +// public log(...args: unknown[]): void { +// const message = Logger.formatMessage(args) +// this.connection.console.log(message) +// this.writeToFile(`[LOG] [${Logger.formatDate(new Date())}] ${message}`) +// } +// +// public info(...args: unknown[]): void { +// const message = Logger.formatMessage(args) +// this.connection.console.info(message) +// this.writeToFile(`[INFO] [${Logger.formatDate(new Date())}] ${message}`) +// } +// +// public warn(...args: unknown[]): void { +// const message = Logger.formatMessage(args) +// this.connection.console.warn(message) +// this.writeToFile(`[WARN] [${Logger.formatDate(new Date())}] ${message}`) +// } +// +// public error(...args: unknown[]): void { +// const message = Logger.formatMessage(args) +// this.connection.console.error(message) +// this.writeToFile(`[ERROR] [${Logger.formatDate(new Date())}] ${message}`) +// } +// +// public dispose(): void { +// if (this.logFile) { +// this.logFile.end() +// this.logFile = null +// } +// } +// +// private static formatDate(date: Date): string { +// const pad = (n: number): string => n.toString().padStart(2, "0") +// +// const year = date.getFullYear().toString() +// const month = pad(date.getMonth() + 1) +// const day = pad(date.getDate()) +// const hours = pad(date.getHours()) +// const minutes = pad(date.getMinutes()) +// const seconds = pad(date.getSeconds()) +// +// return `${day}-${month}-${year} ${hours}:${minutes}:${seconds}` +// } +// +// private static formatMessage(args: unknown[]): string { +// return args +// .filter(arg => arg !== undefined) +// .map(arg => (typeof arg === "object" ? JSON.stringify(arg) : arg.toString())) +// .join(" ") +// } +// +// private writeToFile(message: string): void { +// if (this.logFile) { +// this.logFile.write(message + "\n") +// } +// } +// } diff --git a/server/src/vfs/fs-provider.ts b/server/src/vfs/fs-provider.ts index 78c4019f..1475926c 100644 --- a/server/src/vfs/fs-provider.ts +++ b/server/src/vfs/fs-provider.ts @@ -2,9 +2,9 @@ // Copyright © 2025 TON Studio /* eslint-disable @typescript-eslint/require-await */ -import {readFileSync, existsSync, readdirSync, statSync} from "node:fs" +import {readFileSync, existsSync, readdirSync, statSync} from "fs" import {join} from "path" -import {fileURLToPath} from "node:url" +import {fileURLToPath} from "url" import {FileSystemProvider, VirtualFile} from "./types" export function createNodeFSProvider(): FileSystemProvider { diff --git a/tsconfig.json b/tsconfig.json index 179cd827..707d44d4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "module": "commonjs", "target": "es2020", - "lib": ["es2020"], + "lib": ["es2020", "WebWorker"], "sourceMap": true, "strict": true, "allowUnreachableCode": true, diff --git a/webpack.config.js b/webpack.config.js index 227f0336..5b3dd60a 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -123,9 +123,12 @@ const webConfig = { fallback: { path: require.resolve("path-browserify"), "node:buffer": require.resolve("buffer"), + crypto: require.resolve("crypto-browserify"), + url: require.resolve("url/"), + "node:url": require.resolve("url/"), fs: false, + "node:fs": false, os: false, - crypto: false, util: require.resolve("util"), buffer: require.resolve("buffer"), stream: require.resolve("stream-browserify"), @@ -135,12 +138,13 @@ const webConfig = { module: commonConfig.module, target: "webworker", entry: { - "client-web": "./client/src/extension.ts", + server: "./server/src/server.ts", + client: "./client/src/extension.ts", }, output: { path: path.join(distDir, "web"), filename: "[name].js", - libraryTarget: "commonjs2", + libraryTarget: "commonjs-static", devtoolModuleFilenameTemplate: "../[resource-path]", }, externals: { diff --git a/yarn.lock b/yarn.lock index d01aa112..044e5caa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1258,20 +1258,10 @@ __metadata: languageName: node linkType: hard -"@tact-lang/opcode@npm:^0.3.0": - version: 0.3.1 - resolution: "@tact-lang/opcode@npm:0.3.1" - dependencies: - "@ton/core": "npm:^0.60.0" - "@ton/crypto": "npm:^3.3.0" - checksum: 10c0/fb55a9ea65db5e6ac694ce488984e902ecc928edceadd2ec268aaafbf479f05b09cc7cd3631be85a82265922409920588de5cd1eb03d56192e4f67910321c88d - languageName: node - linkType: hard - "@textlint/ast-node-types@npm:^14.4.2": - version: 14.4.2 - resolution: "@textlint/ast-node-types@npm:14.4.2" - checksum: 10c0/986d88acfcf3b73cf2dcce67158c2e3027f7f012787cece06909f750f1f73c9ac77031c27c6966ed620617aac206ec6b45f61d32efbd3ce6c5f1bc1e018c4300 + version: 14.7.2 + resolution: "@textlint/ast-node-types@npm:14.7.2" + checksum: 10c0/f50550d918b5212c10f1a05c48de1f1474f0c78fc8a3aeeec36f64308b2356d88c9e2b3d89140c1bcd5abad7ee20cfd0cb8bd0e463356abd59867c7a14f6962c languageName: node linkType: hard @@ -1344,37 +1334,6 @@ __metadata: languageName: node linkType: hard -"@ton/core@npm:^0.60.0": - version: 0.60.1 - resolution: "@ton/core@npm:0.60.1" - dependencies: - symbol.inspect: "npm:1.0.1" - peerDependencies: - "@ton/crypto": ">=3.2.0" - checksum: 10c0/aa2181cb1b7db85ce651f5d31b552858e2e6b98bb69803fc384a7e62b6a9cb4685f6e9f6f00a29bddfa872486ba7c2eb9e51fc84a8599b253c1649b2802876be - languageName: node - linkType: hard - -"@ton/crypto-primitives@npm:2.1.0": - version: 2.1.0 - resolution: "@ton/crypto-primitives@npm:2.1.0" - dependencies: - jssha: "npm:3.2.0" - checksum: 10c0/9869a393297930ae8dfd784b0c2c4f3c9eff6341b82c75b103990281855392fbf01780251e32d8afd86a82f3eaa388bfe35b9634a0b64d7f05d65c658855870b - languageName: node - linkType: hard - -"@ton/crypto@npm:^3.3.0": - version: 3.3.0 - resolution: "@ton/crypto@npm:3.3.0" - dependencies: - "@ton/crypto-primitives": "npm:2.1.0" - jssha: "npm:3.2.0" - tweetnacl: "npm:1.0.3" - checksum: 10c0/2fc008d4ada55f483ef7aba63a0690e09a307be340876ed95e7202253d8373daa1d07253dc031889067c578c95f0d08073903fdbc9cce643106d5ccd68095000 - languageName: node - linkType: hard - "@tsconfig/node10@npm:^1.0.7": version: 1.0.11 resolution: "@tsconfig/node10@npm:1.0.11" @@ -2368,6 +2327,17 @@ __metadata: languageName: node linkType: hard +"asn1.js@npm:^4.10.1": + version: 4.10.1 + resolution: "asn1.js@npm:4.10.1" + dependencies: + bn.js: "npm:^4.0.0" + inherits: "npm:^2.0.1" + minimalistic-assert: "npm:^1.0.0" + checksum: 10c0/afa7f3ab9e31566c80175a75b182e5dba50589dcc738aa485be42bdd787e2a07246a4b034d481861123cbe646a7656f318f4f1cad2e9e5e808a210d5d6feaa88 + languageName: node + linkType: hard + "astral-regex@npm:^2.0.0": version: 2.0.0 resolution: "astral-regex@npm:2.0.0" @@ -2544,6 +2514,20 @@ __metadata: languageName: node linkType: hard +"bn.js@npm:^4.0.0, bn.js@npm:^4.1.0, bn.js@npm:^4.11.9": + version: 4.12.2 + resolution: "bn.js@npm:4.12.2" + checksum: 10c0/09a249faa416a9a1ce68b5f5ec8bbca87fe54e5dd4ef8b1cc8a4969147b80035592bddcb1e9cc814c3ba79e573503d5c5178664b722b509fb36d93620dba9b57 + languageName: node + linkType: hard + +"bn.js@npm:^5.2.1": + version: 5.2.2 + resolution: "bn.js@npm:5.2.2" + checksum: 10c0/cb97827d476aab1a0194df33cd84624952480d92da46e6b4a19c32964aa01553a4a613502396712704da2ec8f831cf98d02e74ca03398404bd78a037ba93f2ab + languageName: node + linkType: hard + "boolbase@npm:^1.0.0": version: 1.0.0 resolution: "boolbase@npm:1.0.0" @@ -2586,6 +2570,13 @@ __metadata: languageName: node linkType: hard +"brorand@npm:^1.0.1, brorand@npm:^1.1.0": + version: 1.1.0 + resolution: "brorand@npm:1.1.0" + checksum: 10c0/6f366d7c4990f82c366e3878492ba9a372a73163c09871e80d82fb4ae0d23f9f8924cb8a662330308206e6b3b76ba1d528b4601c9ef73c2166b440b2ea3b7571 + languageName: node + linkType: hard + "browser-stdout@npm:^1.3.1": version: 1.3.1 resolution: "browser-stdout@npm:1.3.1" @@ -2593,6 +2584,72 @@ __metadata: languageName: node linkType: hard +"browserify-aes@npm:^1.0.4, browserify-aes@npm:^1.2.0": + version: 1.2.0 + resolution: "browserify-aes@npm:1.2.0" + dependencies: + buffer-xor: "npm:^1.0.3" + cipher-base: "npm:^1.0.0" + create-hash: "npm:^1.1.0" + evp_bytestokey: "npm:^1.0.3" + inherits: "npm:^2.0.1" + safe-buffer: "npm:^5.0.1" + checksum: 10c0/967f2ae60d610b7b252a4cbb55a7a3331c78293c94b4dd9c264d384ca93354c089b3af9c0dd023534efdc74ffbc82510f7ad4399cf82bc37bc07052eea485f18 + languageName: node + linkType: hard + +"browserify-cipher@npm:^1.0.1": + version: 1.0.1 + resolution: "browserify-cipher@npm:1.0.1" + dependencies: + browserify-aes: "npm:^1.0.4" + browserify-des: "npm:^1.0.0" + evp_bytestokey: "npm:^1.0.0" + checksum: 10c0/aa256dcb42bc53a67168bbc94ab85d243b0a3b56109dee3b51230b7d010d9b78985ffc1fb36e145c6e4db151f888076c1cfc207baf1525d3e375cbe8187fe27d + languageName: node + linkType: hard + +"browserify-des@npm:^1.0.0": + version: 1.0.2 + resolution: "browserify-des@npm:1.0.2" + dependencies: + cipher-base: "npm:^1.0.1" + des.js: "npm:^1.0.0" + inherits: "npm:^2.0.1" + safe-buffer: "npm:^5.1.2" + checksum: 10c0/943eb5d4045eff80a6cde5be4e5fbb1f2d5002126b5a4789c3c1aae3cdddb1eb92b00fb92277f512288e5c6af330730b1dbabcf7ce0923e749e151fcee5a074d + languageName: node + linkType: hard + +"browserify-rsa@npm:^4.0.0, browserify-rsa@npm:^4.1.0": + version: 4.1.1 + resolution: "browserify-rsa@npm:4.1.1" + dependencies: + bn.js: "npm:^5.2.1" + randombytes: "npm:^2.1.0" + safe-buffer: "npm:^5.2.1" + checksum: 10c0/b650ee1192e3d7f3d779edc06dd96ed8720362e72ac310c367b9d7fe35f7e8dbb983c1829142b2b3215458be8bf17c38adc7224920843024ed8cf39e19c513c0 + languageName: node + linkType: hard + +"browserify-sign@npm:^4.2.3": + version: 4.2.3 + resolution: "browserify-sign@npm:4.2.3" + dependencies: + bn.js: "npm:^5.2.1" + browserify-rsa: "npm:^4.1.0" + create-hash: "npm:^1.2.0" + create-hmac: "npm:^1.1.7" + elliptic: "npm:^6.5.5" + hash-base: "npm:~3.0" + inherits: "npm:^2.0.4" + parse-asn1: "npm:^5.1.7" + readable-stream: "npm:^2.3.8" + safe-buffer: "npm:^5.2.1" + checksum: 10c0/30c0eba3f5970a20866a4d3fbba2c5bd1928cd24f47faf995f913f1499214c6f3be14bb4d6ec1ab5c6cafb1eca9cb76ba1c2e1c04ed018370634d4e659c77216 + languageName: node + linkType: hard + "browserslist@npm:^4.24.0, browserslist@npm:^4.24.3": version: 4.24.4 resolution: "browserslist@npm:4.24.4" @@ -2646,6 +2703,13 @@ __metadata: languageName: node linkType: hard +"buffer-xor@npm:^1.0.3": + version: 1.0.3 + resolution: "buffer-xor@npm:1.0.3" + checksum: 10c0/fd269d0e0bf71ecac3146187cfc79edc9dbb054e2ee69b4d97dfb857c6d997c33de391696d04bdd669272751fa48e7872a22f3a6c7b07d6c0bc31dbe02a4075c + languageName: node + linkType: hard + "buffer@npm:^5.5.0": version: 5.7.1 resolution: "buffer@npm:5.7.1" @@ -2986,6 +3050,16 @@ __metadata: languageName: node linkType: hard +"cipher-base@npm:^1.0.0, cipher-base@npm:^1.0.1, cipher-base@npm:^1.0.3": + version: 1.0.6 + resolution: "cipher-base@npm:1.0.6" + dependencies: + inherits: "npm:^2.0.4" + safe-buffer: "npm:^5.2.1" + checksum: 10c0/f73268e0ee6585800875d9748f2a2377ae7c2c3375cba346f75598ac6f6bc3a25dec56e984a168ced1a862529ffffe615363f750c40349039d96bd30fba0fca8 + languageName: node + linkType: hard + "cjs-module-lexer@npm:^1.0.0": version: 1.4.3 resolution: "cjs-module-lexer@npm:1.4.3" @@ -3194,6 +3268,43 @@ __metadata: languageName: node linkType: hard +"create-ecdh@npm:^4.0.4": + version: 4.0.4 + resolution: "create-ecdh@npm:4.0.4" + dependencies: + bn.js: "npm:^4.1.0" + elliptic: "npm:^6.5.3" + checksum: 10c0/77b11a51360fec9c3bce7a76288fc0deba4b9c838d5fb354b3e40c59194d23d66efe6355fd4b81df7580da0661e1334a235a2a5c040b7569ba97db428d466e7f + languageName: node + linkType: hard + +"create-hash@npm:^1.1.0, create-hash@npm:^1.1.2, create-hash@npm:^1.2.0": + version: 1.2.0 + resolution: "create-hash@npm:1.2.0" + dependencies: + cipher-base: "npm:^1.0.1" + inherits: "npm:^2.0.1" + md5.js: "npm:^1.3.4" + ripemd160: "npm:^2.0.1" + sha.js: "npm:^2.4.0" + checksum: 10c0/d402e60e65e70e5083cb57af96d89567954d0669e90550d7cec58b56d49c4b193d35c43cec8338bc72358198b8cbf2f0cac14775b651e99238e1cf411490f915 + languageName: node + linkType: hard + +"create-hmac@npm:^1.1.4, create-hmac@npm:^1.1.7": + version: 1.1.7 + resolution: "create-hmac@npm:1.1.7" + dependencies: + cipher-base: "npm:^1.0.3" + create-hash: "npm:^1.1.0" + inherits: "npm:^2.0.1" + ripemd160: "npm:^2.0.0" + safe-buffer: "npm:^5.0.1" + sha.js: "npm:^2.4.8" + checksum: 10c0/24332bab51011652a9a0a6d160eed1e8caa091b802335324ae056b0dcb5acbc9fcf173cf10d128eba8548c3ce98dfa4eadaa01bd02f44a34414baee26b651835 + languageName: node + linkType: hard + "create-jest@npm:^29.7.0": version: 29.7.0 resolution: "create-jest@npm:29.7.0" @@ -3229,6 +3340,26 @@ __metadata: languageName: node linkType: hard +"crypto-browserify@npm:^3.12.1": + version: 3.12.1 + resolution: "crypto-browserify@npm:3.12.1" + dependencies: + browserify-cipher: "npm:^1.0.1" + browserify-sign: "npm:^4.2.3" + create-ecdh: "npm:^4.0.4" + create-hash: "npm:^1.2.0" + create-hmac: "npm:^1.1.7" + diffie-hellman: "npm:^5.0.3" + hash-base: "npm:~3.0.4" + inherits: "npm:^2.0.4" + pbkdf2: "npm:^3.1.2" + public-encrypt: "npm:^4.0.3" + randombytes: "npm:^2.1.0" + randomfill: "npm:^1.0.4" + checksum: 10c0/184a2def7b16628e79841243232ab5497f18d8e158ac21b7ce90ab172427d0a892a561280adc08f9d4d517bce8db2a5b335dc21abb970f787f8e874bd7b9db7d + languageName: node + linkType: hard + "css-select@npm:^5.1.0": version: 5.1.0 resolution: "css-select@npm:5.1.0" @@ -3249,7 +3380,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.4.0": +"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.4.0": version: 4.4.0 resolution: "debug@npm:4.4.0" dependencies: @@ -3261,6 +3392,18 @@ __metadata: languageName: node linkType: hard +"debug@npm:^4.0.0": + version: 4.4.1 + resolution: "debug@npm:4.4.1" + dependencies: + ms: "npm:^2.1.3" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 10c0/d2b44bc1afd912b49bb7ebb0d50a860dc93a4dd7d946e8de94abc957bb63726b7dd5aa48c18c2386c379ec024c46692e15ed3ed97d481729f929201e671fcd55 + languageName: node + linkType: hard + "decamelize@npm:^4.0.0": version: 4.0.0 resolution: "decamelize@npm:4.0.0" @@ -3359,6 +3502,16 @@ __metadata: languageName: node linkType: hard +"des.js@npm:^1.0.0": + version: 1.1.0 + resolution: "des.js@npm:1.1.0" + dependencies: + inherits: "npm:^2.0.1" + minimalistic-assert: "npm:^1.0.0" + checksum: 10c0/671354943ad67493e49eb4c555480ab153edd7cee3a51c658082fcde539d2690ed2a4a0b5d1f401f9cde822edf3939a6afb2585f32c091f2d3a1b1665cd45236 + languageName: node + linkType: hard + "detect-libc@npm:^2.0.0": version: 2.0.3 resolution: "detect-libc@npm:2.0.3" @@ -3394,6 +3547,17 @@ __metadata: languageName: node linkType: hard +"diffie-hellman@npm:^5.0.3": + version: 5.0.3 + resolution: "diffie-hellman@npm:5.0.3" + dependencies: + bn.js: "npm:^4.1.0" + miller-rabin: "npm:^4.0.0" + randombytes: "npm:^2.0.0" + checksum: 10c0/ce53ccafa9ca544b7fc29b08a626e23a9b6562efc2a98559a0c97b4718937cebaa9b5d7d0a05032cc9c1435e9b3c1532b9e9bf2e0ede868525922807ad6e1ecf + languageName: node + linkType: hard + "dom-serializer@npm:^2.0.0": version: 2.0.0 resolution: "dom-serializer@npm:2.0.0" @@ -3477,6 +3641,21 @@ __metadata: languageName: node linkType: hard +"elliptic@npm:^6.5.3, elliptic@npm:^6.5.5": + version: 6.6.1 + resolution: "elliptic@npm:6.6.1" + dependencies: + bn.js: "npm:^4.11.9" + brorand: "npm:^1.1.0" + hash.js: "npm:^1.0.0" + hmac-drbg: "npm:^1.0.1" + inherits: "npm:^2.0.4" + minimalistic-assert: "npm:^1.0.1" + minimalistic-crypto-utils: "npm:^1.0.1" + checksum: 10c0/8b24ef782eec8b472053793ea1e91ae6bee41afffdfcb78a81c0a53b191e715cbe1292aa07165958a9bbe675bd0955142560b1a007ffce7d6c765bcaf951a867 + languageName: node + linkType: hard + "emittery@npm:^0.13.1": version: 0.13.1 resolution: "emittery@npm:0.13.1" @@ -3868,6 +4047,17 @@ __metadata: languageName: node linkType: hard +"evp_bytestokey@npm:^1.0.0, evp_bytestokey@npm:^1.0.3": + version: 1.0.3 + resolution: "evp_bytestokey@npm:1.0.3" + dependencies: + md5.js: "npm:^1.3.4" + node-gyp: "npm:latest" + safe-buffer: "npm:^5.1.1" + checksum: 10c0/77fbe2d94a902a80e9b8f5a73dcd695d9c14899c5e82967a61b1fc6cbbb28c46552d9b127cff47c45fcf684748bdbcfa0a50410349109de87ceb4b199ef6ee99 + languageName: node + linkType: hard + "execa@npm:^5.0.0": version: 5.1.1 resolution: "execa@npm:5.1.1" @@ -4471,6 +4661,37 @@ __metadata: languageName: node linkType: hard +"hash-base@npm:^3.0.0": + version: 3.1.0 + resolution: "hash-base@npm:3.1.0" + dependencies: + inherits: "npm:^2.0.4" + readable-stream: "npm:^3.6.0" + safe-buffer: "npm:^5.2.0" + checksum: 10c0/663eabcf4173326fbb65a1918a509045590a26cc7e0964b754eef248d281305c6ec9f6b31cb508d02ffca383ab50028180ce5aefe013e942b44a903ac8dc80d0 + languageName: node + linkType: hard + +"hash-base@npm:~3.0, hash-base@npm:~3.0.4": + version: 3.0.5 + resolution: "hash-base@npm:3.0.5" + dependencies: + inherits: "npm:^2.0.4" + safe-buffer: "npm:^5.2.1" + checksum: 10c0/6dc185b79bad9b6d525cd132a588e4215380fdc36fec6f7a8a58c5db8e3b642557d02ad9c367f5e476c7c3ad3ccffa3607f308b124e1ed80e3b80a1b254db61e + languageName: node + linkType: hard + +"hash.js@npm:^1.0.0, hash.js@npm:^1.0.3": + version: 1.1.7 + resolution: "hash.js@npm:1.1.7" + dependencies: + inherits: "npm:^2.0.3" + minimalistic-assert: "npm:^1.0.1" + checksum: 10c0/41ada59494eac5332cfc1ce6b7ebdd7b88a3864a6d6b08a3ea8ef261332ed60f37f10877e0c825aaa4bddebf164fbffa618286aeeec5296675e2671cbfa746c4 + languageName: node + linkType: hard + "hasown@npm:^2.0.2": version: 2.0.2 resolution: "hasown@npm:2.0.2" @@ -4489,6 +4710,17 @@ __metadata: languageName: node linkType: hard +"hmac-drbg@npm:^1.0.1": + version: 1.0.1 + resolution: "hmac-drbg@npm:1.0.1" + dependencies: + hash.js: "npm:^1.0.3" + minimalistic-assert: "npm:^1.0.0" + minimalistic-crypto-utils: "npm:^1.0.1" + checksum: 10c0/f3d9ba31b40257a573f162176ac5930109816036c59a09f901eb2ffd7e5e705c6832bedfff507957125f2086a0ab8f853c0df225642a88bf1fcaea945f20600d + languageName: node + linkType: hard + "hosted-git-info@npm:^2.1.4": version: 2.8.9 resolution: "hosted-git-info@npm:2.8.9" @@ -4659,7 +4891,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3, inherits@npm:~2.0.4": +"inherits@npm:2, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3, inherits@npm:~2.0.4": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 @@ -5669,13 +5901,6 @@ __metadata: languageName: node linkType: hard -"jssha@npm:3.2.0": - version: 3.2.0 - resolution: "jssha@npm:3.2.0" - checksum: 10c0/eba7fb986a6ed12238d57b959c522fae90ff25a9e427d70aeffaf698d4ffadc7a994af7cb28e121139b1a54e38e0bd9b08f2da4ea7979c72653ccba2fb558924 - languageName: node - linkType: hard - "jszip@npm:^3.10.1": version: 3.10.1 resolution: "jszip@npm:3.10.1" @@ -6050,6 +6275,17 @@ __metadata: languageName: node linkType: hard +"md5.js@npm:^1.3.4": + version: 1.3.5 + resolution: "md5.js@npm:1.3.5" + dependencies: + hash-base: "npm:^3.0.0" + inherits: "npm:^2.0.1" + safe-buffer: "npm:^5.1.2" + checksum: 10c0/b7bd75077f419c8e013fc4d4dada48be71882e37d69a44af65a2f2804b91e253441eb43a0614423a1c91bb830b8140b0dc906bc797245e2e275759584f4efcc5 + languageName: node + linkType: hard + "mdast-util-find-and-replace@npm:^1.1.0": version: 1.1.1 resolution: "mdast-util-find-and-replace@npm:1.1.1" @@ -6282,6 +6518,18 @@ __metadata: languageName: node linkType: hard +"miller-rabin@npm:^4.0.0": + version: 4.0.1 + resolution: "miller-rabin@npm:4.0.1" + dependencies: + bn.js: "npm:^4.0.0" + brorand: "npm:^1.0.1" + bin: + miller-rabin: bin/miller-rabin + checksum: 10c0/26b2b96f6e49dbcff7faebb78708ed2f5f9ae27ac8cbbf1d7c08f83cf39bed3d418c0c11034dce997da70d135cc0ff6f3a4c15dc452f8e114c11986388a64346 + languageName: node + linkType: hard + "mime-db@npm:1.52.0": version: 1.52.0 resolution: "mime-db@npm:1.52.0" @@ -6328,6 +6576,20 @@ __metadata: languageName: node linkType: hard +"minimalistic-assert@npm:^1.0.0, minimalistic-assert@npm:^1.0.1": + version: 1.0.1 + resolution: "minimalistic-assert@npm:1.0.1" + checksum: 10c0/96730e5601cd31457f81a296f521eb56036e6f69133c0b18c13fe941109d53ad23a4204d946a0d638d7f3099482a0cec8c9bb6d642604612ce43ee536be3dddd + languageName: node + linkType: hard + +"minimalistic-crypto-utils@npm:^1.0.1": + version: 1.0.1 + resolution: "minimalistic-crypto-utils@npm:1.0.1" + checksum: 10c0/790ecec8c5c73973a4fbf2c663d911033e8494d5fb0960a4500634766ab05d6107d20af896ca2132e7031741f19888154d44b2408ada0852446705441383e9f8 + languageName: node + linkType: hard + "minimatch@npm:^10.0.0": version: 10.0.1 resolution: "minimatch@npm:10.0.1" @@ -6815,6 +7077,20 @@ __metadata: languageName: node linkType: hard +"parse-asn1@npm:^5.0.0, parse-asn1@npm:^5.1.7": + version: 5.1.7 + resolution: "parse-asn1@npm:5.1.7" + dependencies: + asn1.js: "npm:^4.10.1" + browserify-aes: "npm:^1.2.0" + evp_bytestokey: "npm:^1.0.3" + hash-base: "npm:~3.0" + pbkdf2: "npm:^3.1.2" + safe-buffer: "npm:^5.2.1" + checksum: 10c0/05eb5937405c904eb5a7f3633bab1acc11f4ae3478a07ef5c6d81ce88c3c0e505ff51f9c7b935ebc1265c868343793698fc91025755a895d0276f620f95e8a82 + languageName: node + linkType: hard + "parse-entities@npm:^2.0.0": version: 2.0.0 resolution: "parse-entities@npm:2.0.0" @@ -6960,6 +7236,19 @@ __metadata: languageName: node linkType: hard +"pbkdf2@npm:^3.1.2": + version: 3.1.2 + resolution: "pbkdf2@npm:3.1.2" + dependencies: + create-hash: "npm:^1.1.2" + create-hmac: "npm:^1.1.4" + ripemd160: "npm:^2.0.1" + safe-buffer: "npm:^5.0.1" + sha.js: "npm:^2.4.8" + checksum: 10c0/5a30374e87d33fa080a92734d778cf172542cc7e41b96198c4c88763997b62d7850de3fbda5c3111ddf79805ee7c1da7046881c90ac4920b5e324204518b05fd + languageName: node + linkType: hard + "pend@npm:~1.2.0": version: 1.2.0 resolution: "pend@npm:1.2.0" @@ -7115,6 +7404,20 @@ __metadata: languageName: node linkType: hard +"public-encrypt@npm:^4.0.3": + version: 4.0.3 + resolution: "public-encrypt@npm:4.0.3" + dependencies: + bn.js: "npm:^4.1.0" + browserify-rsa: "npm:^4.0.0" + create-hash: "npm:^1.1.0" + parse-asn1: "npm:^5.0.0" + randombytes: "npm:^2.0.1" + safe-buffer: "npm:^5.1.2" + checksum: 10c0/6c2cc19fbb554449e47f2175065d6b32f828f9b3badbee4c76585ac28ae8641aafb9bb107afc430c33c5edd6b05dbe318df4f7d6d7712b1093407b11c4280700 + languageName: node + linkType: hard + "pump@npm:^3.0.0": version: 3.0.2 resolution: "pump@npm:3.0.2" @@ -7132,6 +7435,13 @@ __metadata: languageName: node linkType: hard +"punycode@npm:^1.4.1": + version: 1.4.1 + resolution: "punycode@npm:1.4.1" + checksum: 10c0/354b743320518aef36f77013be6e15da4db24c2b4f62c5f1eb0529a6ed02fbaf1cb52925785f6ab85a962f2b590d9cd5ad730b70da72b5f180e2556b8bd3ca08 + languageName: node + linkType: hard + "punycode@npm:^2.1.0": version: 2.3.1 resolution: "punycode@npm:2.3.1" @@ -7146,7 +7456,7 @@ __metadata: languageName: node linkType: hard -"qs@npm:^6.9.1": +"qs@npm:^6.12.3, qs@npm:^6.9.1": version: 6.14.0 resolution: "qs@npm:6.14.0" dependencies: @@ -7162,7 +7472,7 @@ __metadata: languageName: node linkType: hard -"randombytes@npm:^2.1.0": +"randombytes@npm:^2.0.0, randombytes@npm:^2.0.1, randombytes@npm:^2.0.5, randombytes@npm:^2.1.0": version: 2.1.0 resolution: "randombytes@npm:2.1.0" dependencies: @@ -7171,6 +7481,16 @@ __metadata: languageName: node linkType: hard +"randomfill@npm:^1.0.4": + version: 1.0.4 + resolution: "randomfill@npm:1.0.4" + dependencies: + randombytes: "npm:^2.0.5" + safe-buffer: "npm:^5.1.0" + checksum: 10c0/11aeed35515872e8f8a2edec306734e6b74c39c46653607f03c68385ab8030e2adcc4215f76b5e4598e028c4750d820afd5c65202527d831d2a5f207fe2bc87c + languageName: node + linkType: hard + "rc-config-loader@npm:^4.1.3": version: 4.1.3 resolution: "rc-config-loader@npm:4.1.3" @@ -7248,18 +7568,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.5.0": - version: 3.6.2 - resolution: "readable-stream@npm:3.6.2" - dependencies: - inherits: "npm:^2.0.3" - string_decoder: "npm:^1.1.1" - util-deprecate: "npm:^1.0.1" - checksum: 10c0/e37be5c79c376fdd088a45fa31ea2e423e5d48854be7a22a58869b4e84d25047b193f6acb54f1012331e1bcd667ffb569c01b99d36b0bd59658fb33f513511b7 - languageName: node - linkType: hard - -"readable-stream@npm:~2.3.6": +"readable-stream@npm:^2.3.8, readable-stream@npm:~2.3.6": version: 2.3.8 resolution: "readable-stream@npm:2.3.8" dependencies: @@ -7274,6 +7583,17 @@ __metadata: languageName: node linkType: hard +"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.5.0, readable-stream@npm:^3.6.0": + version: 3.6.2 + resolution: "readable-stream@npm:3.6.2" + dependencies: + inherits: "npm:^2.0.3" + string_decoder: "npm:^1.1.1" + util-deprecate: "npm:^1.0.1" + checksum: 10c0/e37be5c79c376fdd088a45fa31ea2e423e5d48854be7a22a58869b4e84d25047b193f6acb54f1012331e1bcd667ffb569c01b99d36b0bd59658fb33f513511b7 + languageName: node + linkType: hard + "readdirp@npm:~3.6.0": version: 3.6.0 resolution: "readdirp@npm:3.6.0" @@ -7463,6 +7783,16 @@ __metadata: languageName: node linkType: hard +"ripemd160@npm:^2.0.0, ripemd160@npm:^2.0.1": + version: 2.0.2 + resolution: "ripemd160@npm:2.0.2" + dependencies: + hash-base: "npm:^3.0.0" + inherits: "npm:^2.0.1" + checksum: 10c0/f6f0df78817e78287c766687aed4d5accbebc308a8e7e673fb085b9977473c1f139f0c5335d353f172a915bb288098430755d2ad3c4f30612f4dd0c901cd2c3a + languageName: node + linkType: hard + "run-applescript@npm:^7.0.0": version: 7.0.0 resolution: "run-applescript@npm:7.0.0" @@ -7479,7 +7809,7 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:~5.2.0": +"safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.1.1, safe-buffer@npm:^5.1.2, safe-buffer@npm:^5.2.0, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 @@ -7615,6 +7945,18 @@ __metadata: languageName: node linkType: hard +"sha.js@npm:^2.4.0, sha.js@npm:^2.4.8": + version: 2.4.11 + resolution: "sha.js@npm:2.4.11" + dependencies: + inherits: "npm:^2.0.1" + safe-buffer: "npm:^5.0.1" + bin: + sha.js: ./bin.js + checksum: 10c0/b7a371bca8821c9cc98a0aeff67444a03d48d745cb103f17228b96793f455f0eb0a691941b89ea1e60f6359207e36081d9be193252b0f128e0daf9cfea2815a5 + languageName: node + linkType: hard + "shallow-clone@npm:^3.0.0": version: 3.0.1 resolution: "shallow-clone@npm:3.0.1" @@ -8089,13 +8431,6 @@ __metadata: languageName: node linkType: hard -"symbol.inspect@npm:1.0.1": - version: 1.0.1 - resolution: "symbol.inspect@npm:1.0.1" - checksum: 10c0/7ed8636838ede2740293b09175964aef7d65d4ed14b4ffa197785f9b66bd8f964a05979be3d87c021c1a90a25c01262b0528211c97b14ffe64b2acdb941ad214 - languageName: node - linkType: hard - "table@npm:^6.9.0": version: 6.9.0 resolution: "table@npm:6.9.0" @@ -8434,13 +8769,6 @@ __metadata: languageName: node linkType: hard -"tweetnacl@npm:1.0.3": - version: 1.0.3 - resolution: "tweetnacl@npm:1.0.3" - checksum: 10c0/069d9df51e8ad4a89fbe6f9806c68e06c65be3c7d42f0701cc43dba5f0d6064686b238bbff206c5addef8854e3ce00c643bff59432ea2f2c639feab0ee1a93f9 - languageName: node - linkType: hard - "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" @@ -8681,6 +9009,16 @@ __metadata: languageName: node linkType: hard +"url@npm:^0.11.3": + version: 0.11.4 + resolution: "url@npm:0.11.4" + dependencies: + punycode: "npm:^1.4.1" + qs: "npm:^6.12.3" + checksum: 10c0/cc93405ae4a9b97a2aa60ca67f1cb1481c0221cb4725a7341d149be5e2f9cfda26fd432d64dbbec693d16593b68b8a46aad8e5eab21f814932134c9d8620c662 + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.1, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" @@ -8818,7 +9156,6 @@ __metadata: resolution: "vscode-tact@workspace:." dependencies: "@scaleton/func-debug-symbols": "npm:^0.1.5" - "@tact-lang/opcode": "npm:^0.3.0" "@textlint/markdown-to-ast": "npm:14.4.2" "@types/jest": "npm:^29.5.14" "@types/mocha": "npm:^10.0.6" @@ -8832,6 +9169,7 @@ __metadata: c8: "npm:^10.1.3" change-case: "npm:^5.4.4" copy-webpack-plugin: "npm:^12.0.2" + crypto-browserify: "npm:^3.12.1" eslint: "npm:^9.19.0" eslint-plugin-functional: "npm:^9.0.1" eslint-plugin-unicorn: "npm:^56.0.1" @@ -8851,6 +9189,7 @@ __metadata: tsconfig-paths-webpack-plugin: "npm:^4.2.0" typescript: "npm:^5.7.0" typescript-eslint: "npm:^8.22.0" + url: "npm:^0.11.3" util: "npm:^0.12.5" vscode-languageclient: "npm:^8.0.2" vscode-languageserver: "npm:^8.0.2" From 299a0a866b2f2b7f67e35de92f4cb16849fe9f0d Mon Sep 17 00:00:00 2001 From: i582 <51853996+i582@users.noreply.github.com> Date: Fri, 30 May 2025 21:49:37 +0400 Subject: [PATCH 3/5] build for web --- .gitignore | 1 + client/src/extension.ts | 5 +- empty-module.js | 1 + package.json | 6 + .../languages/tact/compiler/MistiAnalyzer.ts | 18 +- .../languages/tact/compiler/TactCompiler.ts | 18 +- server/src/languages/tact/compiler/utils.ts | 45 ++- .../tact/semantic-tokens/comments.ts | 316 ------------------ .../languages/tact/semantic-tokens/index.ts | 7 +- .../src/languages/tact/toolchain/toolchain.ts | 38 ++- webpack.config.js | 108 +++++- yarn.lock | 30 +- 12 files changed, 258 insertions(+), 335 deletions(-) create mode 100644 empty-module.js delete mode 100644 server/src/languages/tact/semantic-tokens/comments.ts diff --git a/.gitignore b/.gitignore index caa87125..dc93e78f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ yarn-error.log # coverage coverage/ +.vscode-test-web/ diff --git a/client/src/extension.ts b/client/src/extension.ts index 90e0a6b4..a94b625b 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -49,11 +49,12 @@ export function deactivate(): Thenable | undefined { async function startServer(context: vscode.ExtensionContext): Promise { const disposables: vscode.Disposable[] = [] + const outputChannel = createClientLog() if (typeof globalThis === "undefined") { const lspNode = await import("vscode-languageclient/node") const clientOptions: lspCommon.LanguageClientOptions = { - outputChannel: createClientLog(), + outputChannel, revealOutputChannelOn: lspNode.RevealOutputChannelOn.Never, documentSelector: [ {scheme: "file", language: "tact"}, @@ -108,7 +109,7 @@ async function startServer(context: vscode.ExtensionContext): Promise { + if (isWebEnvironment) { + console.warn("MistiAnalyzer.checkFile not available in web environment") + return [] + } return this.runMistiCommand(settings.linters.misti.binPath, "--output-format", "json", path) } public static async checkProject(settings: TactSettings): Promise { + if (isWebEnvironment) { + console.warn("MistiAnalyzer.checkProject not available in web environment") + return [] + } return this.runMistiCommand( settings.linters.misti.binPath, "./tact.config.json", @@ -87,6 +98,11 @@ export class MistiAnalyzer { } private static async runMistiCommand(...args: string[]): Promise { + if (isWebEnvironment) { + return [] + } + + const cp = await import("node:child_process") return new Promise((resolve, reject) => { const process = cp.exec(args.join(" "), (_error, stdout, stderr) => { const output = stdout + "\n" + stderr diff --git a/server/src/languages/tact/compiler/TactCompiler.ts b/server/src/languages/tact/compiler/TactCompiler.ts index 5008cfd0..5d911009 100644 --- a/server/src/languages/tact/compiler/TactCompiler.ts +++ b/server/src/languages/tact/compiler/TactCompiler.ts @@ -1,8 +1,11 @@ // SPDX-License-Identifier: MIT // Copyright © 2025 TON Studio -import * as cp from "node:child_process" import {toolchain} from "@server/toolchain" +const isWebEnvironment = + typeof importScripts === "function" || + (typeof self !== "undefined" && typeof self.importScripts === "function") + export enum Severity { INFO = 1, LOW = 2, @@ -69,10 +72,18 @@ export class TactCompiler { } public static async checkFile(path: string): Promise { + if (isWebEnvironment) { + console.warn("TactCompiler.checkFile not available in web environment") + return [] + } return this.runCompilerCommand(toolchain.compilerPath, "--check", path) } public static async checkProject(): Promise { + if (isWebEnvironment) { + console.warn("TactCompiler.checkProject not available in web environment") + return [] + } return this.runCompilerCommand( toolchain.compilerPath, "--check", @@ -82,6 +93,11 @@ export class TactCompiler { } private static async runCompilerCommand(...args: string[]): Promise { + if (isWebEnvironment) { + return [] + } + + const cp = await import("node:child_process") return new Promise((resolve, reject) => { const process = cp.exec(args.join(" "), (_error, _stdout, stderr) => { const errors = this.parseCompilerOutput(stderr) diff --git a/server/src/languages/tact/compiler/utils.ts b/server/src/languages/tact/compiler/utils.ts index 1d9382f8..41832557 100644 --- a/server/src/languages/tact/compiler/utils.ts +++ b/server/src/languages/tact/compiler/utils.ts @@ -3,9 +3,52 @@ import type {Node as SyntaxNode} from "web-tree-sitter" import type {TactFile} from "@server/languages/tact/psi/TactFile" import {CallLike} from "@server/languages/tact/psi/TactNode" -import {createHash} from "node:crypto" import {crc32BigInt} from "@server/languages/tact/compiler/crc32" +const isWebEnvironment = + typeof importScripts === "function" || + (typeof self !== "undefined" && typeof self.importScripts === "function") + +let createHash: any + +if (!isWebEnvironment) { + try { + const crypto = require("node:crypto") + createHash = crypto.createHash + } catch (error) { + console.warn("Failed to load node:crypto:", error) + createHash = (algorithm: string) => ({ + update: (data: string) => ({ + digest: () => Buffer.from("fallback", "utf8"), + }), + }) + } +} else { + createHash = (algorithm: string) => ({ + update: (data: string) => ({ + digest: () => { + // Простая заглушка - возвращаем Buffer с фиксированными данными + const encoder = new TextEncoder() + const arrayBuffer = encoder.encode(data + "fallback") + const uint8Array = new Uint8Array(arrayBuffer) + // Создаем Buffer-подобный объект + return { + readUInt32BE: (offset: number) => { + // Простая хеш-функция для замены + let hash = 0 + for (let i = 0; i < data.length; i++) { + const char = data.charCodeAt(i) + hash = (hash << 5) - hash + char + hash = hash & hash // Convert to 32bit integer + } + return Math.abs(hash) + }, + } + }, + }), + }) +} + export function requireFunctionExitCode( callNode: SyntaxNode, file: TactFile, diff --git a/server/src/languages/tact/semantic-tokens/comments.ts b/server/src/languages/tact/semantic-tokens/comments.ts deleted file mode 100644 index 43c044ab..00000000 --- a/server/src/languages/tact/semantic-tokens/comments.ts +++ /dev/null @@ -1,316 +0,0 @@ -// SPDX-License-Identifier: MIT -// Copyright © 2025 TON Studio -import {Position} from "vscode-languageclient" -import type {Node as SyntaxNode, Parser} from "web-tree-sitter" -import {parse} from "@textlint/markdown-to-ast" -import {TxtCodeBlockNode} from "@textlint/ast-node-types" -import * as lsp from "vscode-languageserver" -import {RecursiveVisitor} from "@server/languages/tact/psi/visitor" -import {Tokens} from "@server/languages/tact/semantic-tokens/tokens" -import {SemanticTokenTypes} from "vscode-languageserver-protocol" - -const KEYWORDS = { - extend: true, - public: true, - fun: true, - let: true, - return: true, - receive: true, - native: true, - primitive: true, - null: true, - if: true, - else: true, - while: true, - repeat: true, - do: true, - until: true, - try: true, - catch: true, - foreach: true, - as: true, - map: true, - mutates: true, - extends: true, - external: true, - import: true, - with: true, - trait: true, - initOf: true, - override: true, - abstract: true, - virtual: true, - inline: true, - const: true, - true: true, - false: true, - init: true, - contract: true, - message: true, - struct: true, -} - -const PUNCTUATION = { - "(": true, - ")": true, - "{": true, - "}": true, - "[": true, - "]": true, - "<": true, - ">": true, - ":": true, - ";": true, - ",": true, - ".": true, - "=": true, - "==": true, - "!=": true, - ">=": true, - "<=": true, - "+": true, - "-": true, - "/": true, - "*": true, - "%": true, - "!": true, - "!!": true, - "&": true, - "|": true, - "&&": true, - "||": true, - "?": true, - "^": true, - "#<=": true, - "#<": true, -} - -function processTactNode( - n: SyntaxNode, - tokens: Tokens, - shift: { - line: number - character: number - }, -): boolean { - if (n.text in KEYWORDS) { - tokens.node(n, lsp.SemanticTokenTypes.keyword, shift) - return true - } - if (n.type in PUNCTUATION) { - tokens.node(n, lsp.SemanticTokenTypes.operator, shift) - return true - } - - switch (n.type) { - case "integer": { - tokens.node(n, lsp.SemanticTokenTypes.number, shift) - break - } - case "boolean": - case "null": - case "self": { - tokens.node(n, lsp.SemanticTokenTypes.keyword, shift) - break - } - case "string": { - tokens.node(n, lsp.SemanticTokenTypes.string, shift) - break - } - case "type_identifier": { - tokens.node(n, lsp.SemanticTokenTypes.type, shift) - break - } - case "global_function": { - const name = n.childForFieldName("name") - if (!name) return true - tokens.node(name, lsp.SemanticTokenTypes.function, shift) - break - } - case "static_call_expression": { - const name = n.childForFieldName("name") - if (!name) return true - tokens.node(name, lsp.SemanticTokenTypes.function, shift) - break - } - case "method_call_expression": { - const name = n.childForFieldName("name") - if (!name) return true - tokens.node(name, lsp.SemanticTokenTypes.function, shift) - break - } - case "field_access_expression": { - const name = n.childForFieldName("name") - if (!name) return true - tokens.node(name, lsp.SemanticTokenTypes.property, shift) - break - } - case "let_statement": { - const name = n.childForFieldName("name") - if (!name) return true - tokens.node(name, lsp.SemanticTokenTypes.variable, shift) - break - } - case "identifier": { - tokens.node(n, lsp.SemanticTokenTypes.variable, shift) - break - } - } - return true -} - -function processTlbNode( - n: SyntaxNode, - tokens: Tokens, - shift: { - line: number - character: number - }, -): boolean { - if (n.type in PUNCTUATION) { - tokens.node(n, lsp.SemanticTokenTypes.operator, shift) - return true - } - - switch (n.type) { - case "##": { - tokens.node(n, lsp.SemanticTokenTypes.macro, shift) - break - } - case "number": - case "hex": { - tokens.node(n, lsp.SemanticTokenTypes.number, shift) - break - } - case "constructor_tag": { - tokens.node(n, lsp.SemanticTokenTypes.number, shift) - break - } - case "identifier": { - const parent = n.parent - if (!parent) return true - if (parent.type === "field_named") { - tokens.node(n, lsp.SemanticTokenTypes.property, shift) - break - } - tokens.node(n, lsp.SemanticTokenTypes.number, shift) - break - } - case "type_identifier": { - const parent = n.parent - if (!parent) break - - if (parent.type === "combinator" || parent.type === "combinator_expr") { - tokens.node(n, SemanticTokenTypes.class, shift) - break - } - - tokens.node(n, SemanticTokenTypes.type, shift) - break - } - case "field_named": { - const identifier = n.firstNamedChild - if (!identifier) break - tokens.node(identifier, SemanticTokenTypes.property, shift) - break - } - case "constructor_": { - const identifier = n.firstNamedChild - if (identifier && identifier.type === "identifier") { - tokens.node(identifier, SemanticTokenTypes.type, shift) - } - break - } - case "combinator": { - break - } - case "builtin_field": { - tokens.node(n, SemanticTokenTypes.property, shift) - break - } - } - return true -} - -export function processDocComment( - tokens: Tokens, - comment: { - lines: string[] - startPosition: Position - }, - parser: Parser, - tlbParser: Parser, -): void { - const ast = parse(comment.lines.join("\n")) - for (const node of ast.children) { - if (node.type === "Paragraph") { - node.children.forEach(child => { - if (child.type === "Code") { - tokens.push( - { - line: comment.startPosition.line + child.loc.start.line - 1, - character: comment.startPosition.character + 4 + child.loc.start.column, - }, - child.loc.end.column - child.loc.start.column, - lsp.SemanticTokenTypes.variable, - ) - return - } - if (child.type === "Strong") { - tokens.push( - { - line: comment.startPosition.line + child.loc.start.line - 1, - character: comment.startPosition.character + 4 + child.loc.start.column, - }, - child.loc.end.column - child.loc.start.column, - lsp.SemanticTokenTypes.operator, - ) - return - } - }) - } - - if (node.type !== "CodeBlock") continue - - if (node.lang === "tact") { - const tree = parser.parse(node.value) - if (!tree) { - cannotParseCommentError(node) - continue - } - - const shift = { - line: node.loc.start.line + comment.startPosition.line, - character: node.loc.start.column + comment.startPosition.character + 4, - } - - RecursiveVisitor.visit(tree.rootNode, (n): boolean => processTactNode(n, tokens, shift)) - } - - if ( - node.lang === "tlb" || - node.lang === "tl-b" || - node.lang === "TL-B" || - node.lang === "TL-b" - ) { - const tree = tlbParser.parse(node.value) - if (!tree) { - cannotParseCommentError(node) - continue - } - - const shift = { - line: node.loc.start.line + comment.startPosition.line, - character: node.loc.start.column + comment.startPosition.character + 4, - } - - RecursiveVisitor.visit(tree.rootNode, (n): boolean => processTlbNode(n, tokens, shift)) - } - } -} - -function cannotParseCommentError(node: TxtCodeBlockNode): void { - console.error("cannot parse code from doc comment:") - console.error("comment:", node.value) - console.error("position:", node.loc) -} diff --git a/server/src/languages/tact/semantic-tokens/index.ts b/server/src/languages/tact/semantic-tokens/index.ts index 9d38c6ca..c5d6e7b1 100644 --- a/server/src/languages/tact/semantic-tokens/index.ts +++ b/server/src/languages/tact/semantic-tokens/index.ts @@ -7,8 +7,6 @@ import {extractCommentsDocContent, NamedNode, TactNode} from "@server/languages/ import * as lsp from "vscode-languageserver" import type {SemanticTokens} from "vscode-languageserver" import {isDocCommentOwner, isNamedFunNode} from "@server/languages/tact/psi/utils" -import {createTactParser, createTlbParser} from "@server/parser" -import {processDocComment} from "@server/languages/tact/semantic-tokens/comments" import {Tokens} from "@server/languages/tact/semantic-tokens/tokens" export function provideTactSemanticTokens( @@ -19,9 +17,6 @@ export function provideTactSemanticTokens( ): SemanticTokens { const tokens = new Tokens() - const parser = createTactParser() - const tlbParser = createTlbParser() - RecursiveVisitor.visit(file.rootNode, (n): boolean => { const type = n.type @@ -145,7 +140,7 @@ export function provideTactSemanticTokens( const comment = extractCommentsDocContent(node.node) if (!comment) return true - processDocComment(tokens, comment, parser, tlbParser) + // processDocComment(tokens, comment, parser, tlbParser) } return true diff --git a/server/src/languages/tact/toolchain/toolchain.ts b/server/src/languages/tact/toolchain/toolchain.ts index 0744d398..fd611e52 100644 --- a/server/src/languages/tact/toolchain/toolchain.ts +++ b/server/src/languages/tact/toolchain/toolchain.ts @@ -5,6 +5,10 @@ import {EnvironmentInfo, ToolchainInfo} from "@shared/shared-msgtypes" import {existsVFS, globalVFS} from "@server/vfs/files-adapter" import {filePathToUri} from "@server/files" +const isWebEnvironment = + typeof importScripts === "function" || + (typeof self !== "undefined" && typeof self.importScripts === "function") + export class InvalidToolchainError extends Error { public constructor(message: string) { super(message) @@ -30,12 +34,17 @@ export class Toolchain { this.isAutoDetected = isAutoDetected this.detectionMethod = detectionMethod this.version = { - number: "", - commit: "", + number: "1.0.0", + commit: "web-fallback", } } public static async autoDetect(root: string): Promise { + if (isWebEnvironment) { + // В веб-окружении возвращаем заглушку + return new Toolchain("@tact-lang/compiler", true, "web-fallback") + } + const candidatesPaths = [ path.join(root, "node_modules", ".bin", "tact"), path.join(root, "bin", "tact.js"), // path in compiler repo @@ -54,6 +63,9 @@ export class Toolchain { } public static async fromPath(path: string): Promise { + if (isWebEnvironment) { + return new Toolchain(path, false, "web-manual") + } return new Toolchain(path, false, "manual").validate() } @@ -62,7 +74,15 @@ export class Toolchain { } public async getEnvironmentInfo(): Promise { - let platform = "web" + if (isWebEnvironment) { + return { + nodeVersion: undefined, + platform: "web", + arch: "unknown", + } + } + + let platform = "unknown" let arch = "unknown" try { @@ -97,6 +117,14 @@ export class Toolchain { } private async setVersion(): Promise { + if (isWebEnvironment) { + this.version = { + number: "1.0.0", + commit: "web-fallback", + } + return this + } + try { const cp = await import("node:child_process") const result = cp.execSync(`"${this.compilerPath}" -v`) @@ -114,6 +142,10 @@ export class Toolchain { } private async validate(): Promise { + if (isWebEnvironment) { + return this + } + try { const cp = await import("node:child_process") const result = cp.execSync(`"${this.compilerPath}" -v`) diff --git a/webpack.config.js b/webpack.config.js index 5b3dd60a..c90a97e2 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -122,20 +122,43 @@ const webConfig = { ...commonConfig.resolve, fallback: { path: require.resolve("path-browserify"), + "node:path": require.resolve("path-browserify"), "node:buffer": require.resolve("buffer"), crypto: require.resolve("crypto-browserify"), + "node:crypto": require.resolve("crypto-browserify"), url: require.resolve("url/"), "node:url": require.resolve("url/"), fs: false, "node:fs": false, - os: false, + "node:fs/promises": false, + os: require.resolve("os-browserify/browser"), + "node:os": require.resolve("os-browserify/browser"), util: require.resolve("util"), buffer: require.resolve("buffer"), stream: require.resolve("stream-browserify"), + "node:stream": require.resolve("stream-browserify"), + "node:string_decoder": require.resolve("string_decoder"), + "node:events": require.resolve("events"), child_process: false, + "node:child_process": false, + vm: require.resolve("vm-browserify"), + }, + alias: { + "empty-module": path.resolve(__dirname, "./empty-module"), }, }, - module: commonConfig.module, + module: { + ...commonConfig.module, + rules: [ + ...commonConfig.module.rules, + { + test: /\.m?js$/, + resolve: { + fullySpecified: false, + }, + }, + ], + }, target: "webworker", entry: { server: "./server/src/server.ts", @@ -144,7 +167,8 @@ const webConfig = { output: { path: path.join(distDir, "web"), filename: "[name].js", - libraryTarget: "commonjs-static", + libraryTarget: "var", + library: "serverExportVar", devtoolModuleFilenameTemplate: "../[resource-path]", }, externals: { @@ -155,9 +179,87 @@ const webConfig = { Buffer: ["buffer", "Buffer"], process: "process/browser", }), + new webpack.DefinePlugin({ + "process.env": JSON.stringify(process.env), + global: "globalThis", + }), new CopyPlugin({ patterns: COPY_FILE_PATTERNS, }), + new webpack.NormalModuleReplacementPlugin(/^node:/, resource => { + const mod = resource.request.replace(/^node:/, "") + switch (mod) { + case "buffer": + resource.request = "buffer" + break + case "stream": + resource.request = "stream-browserify" + break + case "path": + resource.request = "path-browserify" + break + case "crypto": + resource.request = "crypto-browserify" + break + case "util": + resource.request = "util" + break + case "assert": + resource.request = "assert" + break + case "url": + resource.request = "url" + break + case "events": + resource.request = "events" + break + case "string_decoder": + resource.request = "string_decoder" + break + case "console": + resource.request = "console-browserify" + break + case "os": + resource.request = "os-browserify/browser" + break + case "timers": + resource.request = "timers-browserify" + break + case "querystring": + resource.request = "querystring-es3" + break + case "punycode": + resource.request = "punycode" + break + case "zlib": + resource.request = "browserify-zlib" + break + case "http": + resource.request = "stream-http" + break + case "https": + resource.request = "https-browserify" + break + case "fs": + case "fs/promises": + case "child_process": + case "net": + case "tls": + case "dns": + case "dgram": + case "http2": + case "perf_hooks": + case "diagnostics_channel": + case "async_hooks": + case "worker_threads": + case "inspector": + case "trace_events": + resource.request = "empty-module" + break + default: + throw new Error(`Not found ${resource.request}`) + } + }), ], } diff --git a/yarn.lock b/yarn.lock index 044e5caa..ff90f754 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1430,6 +1430,13 @@ __metadata: languageName: node linkType: hard +"@types/events@npm:^3": + version: 3.0.3 + resolution: "@types/events@npm:3.0.3" + checksum: 10c0/3a56f8c51eb4ebc0d05dcadca0c6636c816acc10216ce36c976fad11e54a01f4bb979a07211355686015884753b37f17d74bfdc7aaf4ebb027c1e8a501c7b21d + languageName: node + linkType: hard + "@types/graceful-fs@npm:^4.1.3": version: 4.1.9 resolution: "@types/graceful-fs@npm:4.1.9" @@ -4040,7 +4047,7 @@ __metadata: languageName: node linkType: hard -"events@npm:^3.0.0, events@npm:^3.2.0": +"events@npm:^3.0.0, events@npm:^3.2.0, events@npm:^3.3.0": version: 3.3.0 resolution: "events@npm:3.3.0" checksum: 10c0/d6b6f2adbccbcda74ddbab52ed07db727ef52e31a61ed26db9feb7dc62af7fc8e060defa65e5f8af9449b86b52cc1a1f6a79f2eafcf4e62add2b7a1fa4a432f6 @@ -6995,6 +7002,13 @@ __metadata: languageName: node linkType: hard +"os-browserify@npm:^0.3.0": + version: 0.3.0 + resolution: "os-browserify@npm:0.3.0" + checksum: 10c0/6ff32cb1efe2bc6930ad0fd4c50e30c38010aee909eba8d65be60af55efd6cbb48f0287e3649b4e3f3a63dce5a667b23c187c4293a75e557f0d5489d735bcf52 + languageName: node + linkType: hard + "p-limit@npm:^2.2.0": version: 2.3.0 resolution: "p-limit@npm:2.3.0" @@ -8291,7 +8305,7 @@ __metadata: languageName: node linkType: hard -"string_decoder@npm:^1.1.1": +"string_decoder@npm:^1.1.1, string_decoder@npm:^1.3.0": version: 1.3.0 resolution: "string_decoder@npm:1.3.0" dependencies: @@ -9098,6 +9112,13 @@ __metadata: languageName: node linkType: hard +"vm-browserify@npm:^1.1.2": + version: 1.1.2 + resolution: "vm-browserify@npm:1.1.2" + checksum: 10c0/0cc1af6e0d880deb58bc974921320c187f9e0a94f25570fca6b1bd64e798ce454ab87dfd797551b1b0cc1849307421aae0193cedf5f06bdb5680476780ee344b + languageName: node + linkType: hard + "vscode-jsonrpc@npm:8.1.0": version: 8.1.0 resolution: "vscode-jsonrpc@npm:8.1.0" @@ -9157,6 +9178,7 @@ __metadata: dependencies: "@scaleton/func-debug-symbols": "npm:^0.1.5" "@textlint/markdown-to-ast": "npm:14.4.2" + "@types/events": "npm:^3" "@types/jest": "npm:^29.5.14" "@types/mocha": "npm:^10.0.6" "@types/node": "npm:^22.2.0" @@ -9174,14 +9196,17 @@ __metadata: eslint-plugin-functional: "npm:^9.0.1" eslint-plugin-unicorn: "npm:^56.0.1" eslint-plugin-unused-imports: "npm:^4.1.4" + events: "npm:^3.3.0" glob: "npm:^11.0.1" husky: "npm:^9.1.7" jest: "npm:^29.7.0" mocha: "npm:^10.3.0" + os-browserify: "npm:^0.3.0" path-browserify: "npm:^1.0.1" prettier: "npm:3.4.2" process: "npm:^0.11.10" stream-browserify: "npm:^3.0.0" + string_decoder: "npm:^1.3.0" tree-sitter-cli: "npm:^0.25.0" ts-jest: "npm:^29.2.6" ts-loader: "npm:^9.5.1" @@ -9191,6 +9216,7 @@ __metadata: typescript-eslint: "npm:^8.22.0" url: "npm:^0.11.3" util: "npm:^0.12.5" + vm-browserify: "npm:^1.1.2" vscode-languageclient: "npm:^8.0.2" vscode-languageserver: "npm:^8.0.2" vscode-languageserver-textdocument: "npm:^1.0.7" From c77fcfaed9f72d7429eeaf177082337f90b1329e Mon Sep 17 00:00:00 2001 From: i582 <51853996+i582@users.noreply.github.com> Date: Fri, 30 May 2025 22:56:48 +0400 Subject: [PATCH 4/5] works somehow --- client/src/extension.ts | 69 +- empty-module.js | 2 +- package.json | 31 +- server/src/connection.ts | 8 +- server/src/files.ts | 10 +- server/src/indexing-root.ts | 19 +- .../languages/tact/completion/data/types.ts | 5 +- server/src/languages/tact/indexes/index.ts | 11 +- .../tact/intentions/ExtractToFile.ts | 9 +- server/src/psi/File.ts | 9 +- server/src/server.ts | 11 +- server/src/vfs/files-adapter.ts | 2 + server/src/vfs/fs-provider.ts | 35 +- server/src/vfs/index.ts | 2 +- server/src/vfs/vfs.ts | 67 ++ server/src/vfs/vscode-provider.ts | 69 +- tsconfig.json | 2 +- webpack.config.js | 166 ++- yarn.lock | 985 +++++++++++++++++- 19 files changed, 1398 insertions(+), 114 deletions(-) diff --git a/client/src/extension.ts b/client/src/extension.ts index a94b625b..e72d1333 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -117,6 +117,7 @@ async function startServer(context: vscode.ExtensionContext): Promise { + console.error("Worker error:", error) + outputChannel.appendLine(`Worker error: ${error.message}`) + } + + worker.onmessage = message => { + console.log("Worker message:", message) + } + client = new lspBrowser.LanguageClient( "tact-server", "Tact Language Server", @@ -154,7 +177,17 @@ async function startServer(context: vscode.ExtensionContext): Promise { - return typeof globalThis !== "undefined" + return typeof self !== "undefined" && typeof importScripts === "function" } export const openConnection = (): Connection => { @@ -15,14 +15,10 @@ export const openConnection = (): Connection => { const messageReader = new lspBrowser.BrowserMessageReader(self) const messageWriter = new lspBrowser.BrowserMessageWriter(self) - messageReader.listen(message => { - console.log("Received message from main thread:", message) - }) - return lspBrowser.createConnection(messageReader, messageWriter) } - return lspNode.createConnection(lspBrowser.ProposedFeatures.all) + return lspNode.createConnection(lspNode.ProposedFeatures.all) } export const connection = openConnection() diff --git a/server/src/files.ts b/server/src/files.ts index 2db7a0f1..d618b21c 100644 --- a/server/src/files.ts +++ b/server/src/files.ts @@ -1,7 +1,6 @@ import * as lsp from "vscode-languageserver" import {TextDocument} from "vscode-languageserver-textdocument" import {TactFile} from "@server/languages/tact/psi/TactFile" -import {pathToFileURL} from "url" import {createFiftParser, createTactParser, createTlbParser} from "@server/parser" import {readFileVFS, globalVFS} from "@server/vfs/files-adapter" import {FiftFile} from "@server/languages/fift/psi/FiftFile" @@ -98,7 +97,8 @@ async function readOrUndefined(uri: string): Promise { } export function uriToFilePath(uri: string): string { - return fileURLToPath(uri) + const normalizedUri = uri.replace(/\\/g, "/") + return URI.parse(normalizedUri).fsPath } export const isTactFile = ( @@ -124,7 +124,11 @@ export const filePathToUri = (filePath: string): string => { return url.replace(/c:/g, "c%3A").replace(/d:/g, "d%3A") } -function fileURLToPath(uri: string): string { +const pathToFileURL = (path: string): string => { + return "file://" + path +} + +export function fileURLToPath(uri: string): string { const normalizedUri = uri.replace(/\\/g, "/") return URI.parse(normalizedUri).fsPath } diff --git a/server/src/indexing-root.ts b/server/src/indexing-root.ts index f8cc8c50..3c372de2 100644 --- a/server/src/indexing-root.ts +++ b/server/src/indexing-root.ts @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MIT // Copyright © 2025 TON Studio -import {glob} from "glob" +import {globFiles} from "@server/utils/glob" import {index} from "@server/languages/tact/indexes" -import {fileURLToPath} from "url" import * as path from "path" import {filePathToUri, findTactFile} from "@server/files" +import {URI} from "vscode-uri" export enum IndexingRootKind { Stdlib = "stdlib", @@ -46,8 +46,14 @@ export class IndexingRoot { "**/tact-lang/compiler/**", ] - const rootDir = fileURLToPath(this.root) - const files = await glob("**/*.tact", { + let rootDir: string + try { + rootDir = this.root.startsWith("file://") ? uriToFilePath(this.root) : this.root + } catch { + rootDir = this.root + } + + const files = await globFiles("**/*.tact", { cwd: rootDir, ignore: ignore, }) @@ -63,3 +69,8 @@ export class IndexingRoot { } } } + +function uriToFilePath(uri: string): string { + const normalizedUri = uri.replace(/\\/g, "/") + return URI.parse(normalizedUri).fsPath +} diff --git a/server/src/languages/tact/completion/data/types.ts b/server/src/languages/tact/completion/data/types.ts index f2706f7f..bdd5065a 100644 --- a/server/src/languages/tact/completion/data/types.ts +++ b/server/src/languages/tact/completion/data/types.ts @@ -3,7 +3,6 @@ import * as path from "path" import {Node as SyntaxNode} from "web-tree-sitter" import {globalVFS, readFileVFS} from "@server/vfs/files-adapter" -import {pathToFileURL} from "url" export interface AsmInstruction { readonly mnemonic: string @@ -51,6 +50,10 @@ export async function asmData(): Promise { return data } +const pathToFileURL = (path: string): string => { + return "file://" + path +} + export const filePathToUri = (filePath: string): string => { const url = pathToFileURL(filePath).toString() return url.replace(/c:/g, "c%3A").replace(/d:/g, "d%3A") diff --git a/server/src/languages/tact/indexes/index.ts b/server/src/languages/tact/indexes/index.ts index 24167baa..18ce6caf 100644 --- a/server/src/languages/tact/indexes/index.ts +++ b/server/src/languages/tact/indexes/index.ts @@ -14,8 +14,7 @@ import { import {isNamedFunNode} from "@server/languages/tact/psi/utils" import {ScopeProcessor} from "@server/languages/tact/psi/Reference" import {CACHE} from "@server/languages/tact/cache" -import {fileURLToPath} from "url" -import {PARSED_FILES_CACHE} from "@server/files" +import {PARSED_FILES_CACHE, fileURLToPath} from "@server/files" import {ResolveState} from "@server/psi/ResolveState" export interface IndexKeyToType { @@ -264,8 +263,8 @@ export class IndexRoot { // most likely VS Code temp file can be only in the workspace return this.name === "workspace" } - const filepath = fileURLToPath(file) - const rootDir = fileURLToPath(this.root) + const filepath = uriToFilePath(file) + const rootDir = uriToFilePath(this.root) return filepath.startsWith(rootDir) } @@ -513,4 +512,8 @@ export class GlobalIndex { } } +export function uriToFilePath(uri: string): string { + return fileURLToPath(uri) +} + export const index = new GlobalIndex() diff --git a/server/src/languages/tact/intentions/ExtractToFile.ts b/server/src/languages/tact/intentions/ExtractToFile.ts index 7a2f9579..568301d5 100644 --- a/server/src/languages/tact/intentions/ExtractToFile.ts +++ b/server/src/languages/tact/intentions/ExtractToFile.ts @@ -18,10 +18,9 @@ import { Primitive, } from "@server/languages/tact/psi/Decls" import * as path from "path" -import {fileURLToPath} from "url" -import * as lsp from "vscode-languageserver" -import {filePathToUri} from "@server/files" +import {filePathToUri, uriToFilePath} from "@server/files" import {existsVFS, globalVFS} from "@server/vfs/files-adapter" +import * as lsp from "vscode-languageserver" export class ExtractToFile implements AsyncIntention { public readonly id: string = "tact.extract-to-file" @@ -137,7 +136,7 @@ export class ExtractToFile implements AsyncIntention { const newFileContent = this.generateFileContent(elementText) const documentChanges: (lsp.TextDocumentEdit | lsp.CreateFile)[] = [] - const newFilePath = fileURLToPath(newFileUri) + const newFilePath = uriToFilePath(newFileUri) const fileExists = await existsVFS(globalVFS, newFilePath) if (fileExists) { @@ -216,7 +215,7 @@ export class ExtractToFile implements AsyncIntention { } private generateFileUri(fileName: string, currentFile: TactFile): string { - const currentFilePath = fileURLToPath(currentFile.uri) + const currentFilePath = uriToFilePath(currentFile.uri) const currentDir = path.dirname(currentFilePath) const newFilePath = path.join(currentDir, fileName) return filePathToUri(newFilePath) diff --git a/server/src/psi/File.ts b/server/src/psi/File.ts index ab3c09ef..a003ff6e 100644 --- a/server/src/psi/File.ts +++ b/server/src/psi/File.ts @@ -2,7 +2,7 @@ // Copyright © 2025 TON Studio import * as path from "path" import type {Node as SyntaxNode, Tree} from "web-tree-sitter" -import {fileURLToPath} from "url" +import {URI} from "vscode-uri" export class File { public constructor( @@ -16,10 +16,15 @@ export class File { } public get path(): string { - return fileURLToPath(this.uri) + return uriToFilePath(this.uri) } public get name(): string { return path.basename(this.path, ".tact") } } + +export function uriToFilePath(uri: string): string { + const normalizedUri = uri.replace(/\\/g, "/") + return URI.parse(normalizedUri).fsPath +} diff --git a/server/src/server.ts b/server/src/server.ts index 6c18f2e8..89959a02 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -40,7 +40,6 @@ import { import {setToolchain, setWorkspaceRoot, toolchain} from "@server/toolchain" import * as toolchainManager from "@server/toolchain-manager" import {formatCode} from "@server/languages/tact/compiler/fmt/fmt" -import {fileURLToPath} from "url" import {onFileRenamed, processFileRenaming} from "@server/languages/tact/rename/file-renaming" import {provideSelectionGasConsumption} from "@server/languages/tact/custom/selection-gas-consumption" import {runInspections} from "@server/languages/tact/inspections" @@ -100,6 +99,7 @@ import {provideTlbCompletion} from "@server/languages/tlb/completion" import {TLB_CACHE} from "@server/languages/tlb/cache" import {provideTlbReferences} from "@server/languages/tlb/references" import {TextDocument} from "vscode-languageserver-textdocument" +import {URI} from "vscode-uri" /** * Whenever LS is initialized. @@ -223,6 +223,11 @@ function findStubs(): string | null { return path.join(__dirname, "stubs") } +export function uriToFilePath(uri: string): string { + const normalizedUri = uri.replace(/\\/g, "/") + return URI.parse(normalizedUri).fsPath +} + async function initialize(): Promise { if (!workspaceFolders || workspaceFolders.length === 0 || initialized) { // use fallback later, see `initializeFallback` @@ -235,7 +240,7 @@ async function initialize(): Promise { reporter.begin("Tact Language Server", 0) const rootUri = workspaceFolders[0].uri - const rootDir = fileURLToPath(rootUri) + const rootDir = uriToFilePath(rootUri) setWorkspaceRoot(rootDir) @@ -344,7 +349,7 @@ async function findConfigFileDir(startPath: string, fileName: string): Promise { // let's try to initialize with this way - const filepath = fileURLToPath(uri) + const filepath = uriToFilePath(uri) const projectDir = await findConfigFileDir(path.dirname(filepath), "tact.config.json") if (projectDir === null) { console.info(`project directory not found, using file directory`) diff --git a/server/src/vfs/files-adapter.ts b/server/src/vfs/files-adapter.ts index 4e7493fd..f317534f 100644 --- a/server/src/vfs/files-adapter.ts +++ b/server/src/vfs/files-adapter.ts @@ -4,6 +4,8 @@ import {VFS, readFile, exists} from "./vfs" export {globalVFS} from "./global" +export {glob} from "./vfs" + export async function readFileVFS(vfs: VFS, uri: string): Promise { try { const file = await readFile(vfs, uri) diff --git a/server/src/vfs/fs-provider.ts b/server/src/vfs/fs-provider.ts index 1475926c..308a8b02 100644 --- a/server/src/vfs/fs-provider.ts +++ b/server/src/vfs/fs-provider.ts @@ -2,17 +2,17 @@ // Copyright © 2025 TON Studio /* eslint-disable @typescript-eslint/require-await */ -import {readFileSync, existsSync, readdirSync, statSync} from "fs" -import {join} from "path" -import {fileURLToPath} from "url" +import * as fs from "fs" +import * as path from "path" import {FileSystemProvider, VirtualFile} from "./types" +import {URI} from "vscode-uri" export function createNodeFSProvider(): FileSystemProvider { return { async readFile(uri: string): Promise { try { - const filePath = fileURLToPath(uri) - const content = readFileSync(filePath, "utf8") + const filePath = uriToFilePath(uri) + const content = fs.readFileSync(filePath, "utf8") return { uri, @@ -30,8 +30,8 @@ export function createNodeFSProvider(): FileSystemProvider { async exists(uri: string): Promise { try { - const filePath = fileURLToPath(uri) - return existsSync(filePath) + const filePath = uriToFilePath(uri) + return fs.existsSync(filePath) } catch { return false } @@ -39,14 +39,14 @@ export function createNodeFSProvider(): FileSystemProvider { async listFiles(uri: string): Promise { try { - const dirPath = fileURLToPath(uri) - const entries = readdirSync(dirPath) + const dirPath = uriToFilePath(uri) + const entries = fs.readdirSync(dirPath) const files: string[] = [] for (const entry of entries) { - const fullPath = join(dirPath, entry) - const stat = statSync(fullPath) + const fullPath = path.join(dirPath, entry) + const stat = fs.statSync(fullPath) if (stat.isFile()) { files.push(entry) @@ -61,14 +61,14 @@ export function createNodeFSProvider(): FileSystemProvider { async listDirs(uri: string): Promise { try { - const dirPath = fileURLToPath(uri) - const entries = readdirSync(dirPath) + const dirPath = uriToFilePath(uri) + const entries = fs.readdirSync(dirPath) const files: string[] = [] for (const entry of entries) { - const fullPath = join(dirPath, entry) - const stat = statSync(fullPath) + const fullPath = path.join(dirPath, entry) + const stat = fs.statSync(fullPath) if (stat.isDirectory()) { files.push(entry) @@ -82,3 +82,8 @@ export function createNodeFSProvider(): FileSystemProvider { }, } } + +function uriToFilePath(uri: string): string { + const normalizedUri = uri.replace(/\\/g, "/") + return URI.parse(normalizedUri).fsPath +} diff --git a/server/src/vfs/index.ts b/server/src/vfs/index.ts index 197543de..2fbb1ce9 100644 --- a/server/src/vfs/index.ts +++ b/server/src/vfs/index.ts @@ -3,7 +3,7 @@ export type {FileSystemProvider, VirtualFile} from "./types" -export {createVFS, readFile, exists, listFiles} from "./vfs" +export {createVFS, readFile, exists, listFiles, glob} from "./vfs" export type {VFS} from "./vfs" export {createNodeFSProvider} from "./fs-provider" diff --git a/server/src/vfs/vfs.ts b/server/src/vfs/vfs.ts index 81ec4882..c51a763e 100644 --- a/server/src/vfs/vfs.ts +++ b/server/src/vfs/vfs.ts @@ -25,3 +25,70 @@ export async function listFiles(vfs: VFS, uri: string): Promise { export async function listDirs(vfs: VFS, uri: string): Promise { return vfs.provider.listDirs(uri) } + +export async function glob( + vfs: VFS, + pattern: string, + options: { + cwd?: string + ignore?: string[] + }, +): Promise { + const cwd = options.cwd ?? "" + const ignore = options.ignore ?? [] + + const results: string[] = [] + + async function walkDirectory(dirUri: string, currentPath: string): Promise { + try { + const files = await listFiles(vfs, dirUri) + const dirs = await listDirs(vfs, dirUri) + + // Проверяем файлы + for (const file of files) { + const filePath = currentPath ? `${currentPath}/${file}` : file + + // Проверяем, не игнорируется ли файл + const isIgnored = ignore.some(ignorePattern => + matchesPattern(filePath, ignorePattern), + ) + + if (!isIgnored && matchesPattern(filePath, pattern)) { + results.push(filePath) + } + } + + // Рекурсивно обходим директории + for (const dir of dirs) { + const dirPath = currentPath ? `${currentPath}/${dir}` : dir + + // Проверяем, не игнорируется ли директория + const isIgnored = ignore.some(ignorePattern => + matchesPattern(dirPath, ignorePattern), + ) + + if (!isIgnored) { + const childDirUri = `${dirUri}/${dir}` + await walkDirectory(childDirUri, dirPath) + } + } + } catch (error) { + // Игнорируем ошибки доступа к директориям + console.debug(`Failed to read directory ${dirUri}:`, error) + } + } + + await walkDirectory(cwd, "") + return results +} + +function matchesPattern(filePath: string, pattern: string): boolean { + const regexPattern = pattern + .replace(/\*\*/g, ".*") // ** -> .* + .replace(/\*/g, "[^/]*") // * -> [^/]* + .replace(/\./g, "\\.") // . -> \. + .replace(/\?/g, ".") // ? -> . + + const regex = new RegExp(`^${regexPattern}$`) + return regex.test(filePath) +} diff --git a/server/src/vfs/vscode-provider.ts b/server/src/vfs/vscode-provider.ts index b95b1128..654e73b8 100644 --- a/server/src/vfs/vscode-provider.ts +++ b/server/src/vfs/vscode-provider.ts @@ -5,18 +5,71 @@ import {FileSystemProvider, VirtualFile} from "./types" export function createVSCodeProvider(): FileSystemProvider { + const virtualFiles: Map = new Map() + const virtualDirs: Map> = new Map() + + const initVirtualFS = () => { + virtualDirs.set("", new Set([])) + + console.debug("VS Code provider initialized in web environment") + } + + initVirtualFS() + return { - async readFile(_uri: string): Promise { - return null + async readFile(uri: string): Promise { + const content = virtualFiles.get(uri) + if (content !== undefined) { + return { + uri, + content, + exists: true, + } + } + + return { + uri, + content: "", + exists: false, + } }, - async exists(_uri: string): Promise { - return false + + async exists(uri: string): Promise { + return virtualFiles.has(uri) }, - async listFiles(_uri: string): Promise { - return [] + + async listFiles(uri: string): Promise { + const dirContent = virtualDirs.get(uri) + if (!dirContent) { + return [] + } + + const files: string[] = [] + for (const item of dirContent) { + const fullPath = uri ? `${uri}/${item}` : item + if (virtualFiles.has(fullPath)) { + files.push(item) + } + } + + return files }, - async listDirs(_uri: string): Promise { - return [] + + async listDirs(uri: string): Promise { + const dirContent = virtualDirs.get(uri) + if (!dirContent) { + return [] + } + + const dirs: string[] = [] + for (const item of dirContent) { + const fullPath = uri ? `${uri}/${item}` : item + if (virtualDirs.has(fullPath)) { + dirs.push(item) + } + } + + return dirs }, } } diff --git a/tsconfig.json b/tsconfig.json index 707d44d4..4e177b2e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "module": "commonjs", "target": "es2020", - "lib": ["es2020", "WebWorker"], + "lib": ["ES2020", "DOM", "WebWorker"], "sourceMap": true, "strict": true, "allowUnreachableCode": true, diff --git a/webpack.config.js b/webpack.config.js index c90a97e2..06a156c6 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -60,7 +60,7 @@ const commonConfig = { alias: { // provides alternate implementation for node module and source files }, - plugins: [new TsconfigPathsPlugin()], + plugins: [new (require("tsconfig-paths-webpack-plugin"))()], fallback: {}, }, module: { @@ -80,8 +80,8 @@ const commonConfig = { /**@type {import("webpack").Configuration}*/ const nodeConfig = { - mode: commonConfig.mode, - devtool: commonConfig.devtool, + mode: "development", + devtool: "source-map", resolve: { ...commonConfig.resolve, fallback: {}, @@ -116,8 +116,8 @@ const nodeConfig = { // Конфигурация для VS Code Web (Browser/WebWorker) /**@type {import("webpack").Configuration}*/ const webConfig = { - mode: commonConfig.mode, - devtool: commonConfig.devtool, + mode: "development", + devtool: "source-map", resolve: { ...commonConfig.resolve, fallback: { @@ -161,14 +161,12 @@ const webConfig = { }, target: "webworker", entry: { - server: "./server/src/server.ts", client: "./client/src/extension.ts", }, output: { path: path.join(distDir, "web"), filename: "[name].js", - libraryTarget: "var", - library: "serverExportVar", + libraryTarget: "commonjs2", devtoolModuleFilenameTemplate: "../[resource-path]", }, externals: { @@ -184,7 +182,155 @@ const webConfig = { global: "globalThis", }), new CopyPlugin({ - patterns: COPY_FILE_PATTERNS, + patterns: COPY_FILE_PATTERNS.map(pattern => ({ + ...pattern, + to: pattern.to.replace(distDir, path.join(distDir, "web")), + })), + }), + new webpack.NormalModuleReplacementPlugin(/^node:/, resource => { + const mod = resource.request.replace(/^node:/, "") + switch (mod) { + case "buffer": + resource.request = "buffer" + break + case "stream": + resource.request = "stream-browserify" + break + case "path": + resource.request = "path-browserify" + break + case "crypto": + resource.request = "crypto-browserify" + break + case "util": + resource.request = "util" + break + case "assert": + resource.request = "assert" + break + case "url": + resource.request = "url" + break + case "events": + resource.request = "events" + break + case "string_decoder": + resource.request = "string_decoder" + break + case "console": + resource.request = "console-browserify" + break + case "os": + resource.request = "os-browserify/browser" + break + case "timers": + resource.request = "timers-browserify" + break + case "querystring": + resource.request = "querystring-es3" + break + case "punycode": + resource.request = "punycode" + break + case "zlib": + resource.request = "browserify-zlib" + break + case "http": + resource.request = "stream-http" + break + case "https": + resource.request = "https-browserify" + break + case "fs": + case "fs/promises": + case "child_process": + case "net": + case "tls": + case "dns": + case "dgram": + case "http2": + case "perf_hooks": + case "diagnostics_channel": + case "async_hooks": + case "worker_threads": + case "inspector": + case "trace_events": + resource.request = "empty-module" + break + default: + throw new Error(`Not found ${resource.request}`) + } + }), + ], +} + +// Конфигурация для webworker (языковой сервер) +/**@type {import("webpack").Configuration}*/ +const webWorkerConfig = { + mode: "development", + devtool: "source-map", + resolve: { + ...commonConfig.resolve, + fallback: { + path: require.resolve("path-browserify"), + "node:path": require.resolve("path-browserify"), + "node:buffer": require.resolve("buffer"), + crypto: require.resolve("crypto-browserify"), + "node:crypto": require.resolve("crypto-browserify"), + url: require.resolve("url/"), + "node:url": require.resolve("url/"), + fs: false, + "node:fs": false, + "node:fs/promises": false, + os: require.resolve("os-browserify/browser"), + "node:os": require.resolve("os-browserify/browser"), + util: require.resolve("util"), + buffer: require.resolve("buffer"), + stream: require.resolve("stream-browserify"), + "node:stream": require.resolve("stream-browserify"), + "node:string_decoder": require.resolve("string_decoder"), + "node:events": require.resolve("events"), + child_process: false, + "node:child_process": false, + vm: require.resolve("vm-browserify"), + }, + alias: { + "empty-module": path.resolve(__dirname, "./empty-module"), + }, + }, + module: { + ...commonConfig.module, + rules: [ + ...commonConfig.module.rules, + { + test: /\.m?js$/, + resolve: { + fullySpecified: false, + }, + }, + ], + }, + target: "webworker", + entry: { + server: "./server/src/server.ts", + }, + output: { + path: path.join(distDir, "web"), + filename: "[name].js", + globalObject: "self", + devtoolModuleFilenameTemplate: "../[resource-path]", + }, + externals: { + // vscode API недоступно в webworker + }, + plugins: [ + new webpack.ProvidePlugin({ + Buffer: ["buffer", "Buffer"], + process: "process/browser", + }), + new webpack.DefinePlugin({ + "process.env": JSON.stringify(process.env), + global: "globalThis", }), new webpack.NormalModuleReplacementPlugin(/^node:/, resource => { const mod = resource.request.replace(/^node:/, "") @@ -265,7 +411,7 @@ const webConfig = { module.exports = (env, _argv) => { if (env && env.target === "web") { - return webConfig + return [webConfig, webWorkerConfig] } return nodeConfig } diff --git a/yarn.lock b/yarn.lock index ff90f754..8fa2b295 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1021,6 +1021,26 @@ __metadata: languageName: node linkType: hard +"@koa/cors@npm:^5.0.0": + version: 5.0.0 + resolution: "@koa/cors@npm:5.0.0" + dependencies: + vary: "npm:^1.1.2" + checksum: 10c0/49e5f3b861590bd81aa3663a2f0658234a9b378840bb54a2947b3c5f2067f9d966b6fa2e9049fdc7c74c787456d1885bacd0b7ee1f134274d28282c7df99c3fd + languageName: node + linkType: hard + +"@koa/router@npm:^13.1.0": + version: 13.1.0 + resolution: "@koa/router@npm:13.1.0" + dependencies: + http-errors: "npm:^2.0.0" + koa-compose: "npm:^4.1.0" + path-to-regexp: "npm:^6.3.0" + checksum: 10c0/7237aab14b48cf8b4120eaba33f4caf0d2d9a9b6fb88a47788c71e5e3af3c39e74ed35b5e48e7000bffb34fe41e901e34896877bdc223face94b92fcbb22a806 + languageName: node + linkType: hard + "@nodelib/fs.scandir@npm:2.1.5": version: 2.1.5 resolution: "@nodelib/fs.scandir@npm:2.1.5" @@ -1077,6 +1097,15 @@ __metadata: languageName: node linkType: hard +"@playwright/browser-chromium@npm:^1.52.0": + version: 1.52.0 + resolution: "@playwright/browser-chromium@npm:1.52.0" + dependencies: + playwright-core: "npm:1.52.0" + checksum: 10c0/6cbe1d18550dcbc21279da7bcd65c2c8a94f68f4789ff21525ccb0c60a514ebe137a70843d5da043ba6210806ca845d2a3f52005b80a692801f9f230158a7af4 + languageName: node + linkType: hard + "@scaleton/func-debug-symbols@npm:^0.1.5": version: 0.1.5 resolution: "@scaleton/func-debug-symbols@npm:0.1.5" @@ -1527,6 +1556,13 @@ __metadata: languageName: node linkType: hard +"@types/punycode@npm:^2": + version: 2.1.4 + resolution: "@types/punycode@npm:2.1.4" + checksum: 10c0/0472cc871783a22859ad83fe7cb62d23226ff78694b9807d2a3ec37571d46b05409ca9282c8ccedfb59e58e4a4561b27463623ce95bcfd6bd9c11ac1ef3cd0d1 + languageName: node + linkType: hard + "@types/sarif@npm:^2.1.4": version: 2.1.7 resolution: "@types/sarif@npm:2.1.7" @@ -1790,6 +1826,31 @@ __metadata: languageName: node linkType: hard +"@vscode/test-web@npm:^0.0.69": + version: 0.0.69 + resolution: "@vscode/test-web@npm:0.0.69" + dependencies: + "@koa/cors": "npm:^5.0.0" + "@koa/router": "npm:^13.1.0" + "@playwright/browser-chromium": "npm:^1.52.0" + gunzip-maybe: "npm:^1.4.2" + http-proxy-agent: "npm:^7.0.2" + https-proxy-agent: "npm:^7.0.6" + koa: "npm:^3.0.0" + koa-morgan: "npm:^1.0.1" + koa-mount: "npm:^4.2.0" + koa-static: "npm:^5.0.0" + minimist: "npm:^1.2.8" + playwright: "npm:^1.52.0" + tar-fs: "npm:^3.0.8" + tinyglobby: "npm:0.2.13" + vscode-uri: "npm:^3.1.0" + bin: + vscode-test-web: out/server/index.js + checksum: 10c0/dd40d27cb397b55b0ab33316f366a0bc3c2f5f5ef3f94aa3e879295b86d0d4d1fa5e8c4bb777f327331024bbd5795343b1e73c4c37781fe16188a07f9271f672 + languageName: node + linkType: hard + "@vscode/vsce-sign-alpine-arm64@npm:2.0.2": version: 2.0.2 resolution: "@vscode/vsce-sign-alpine-arm64@npm:2.0.2" @@ -2137,6 +2198,16 @@ __metadata: languageName: node linkType: hard +"accepts@npm:^1.3.5": + version: 1.3.8 + resolution: "accepts@npm:1.3.8" + dependencies: + mime-types: "npm:~2.1.34" + negotiator: "npm:0.6.3" + checksum: 10c0/3a35c5f5586cfb9a21163ca47a5f77ac34fa8ceb5d17d2fa2c0d81f41cbd7f8c6fa52c77e2c039acc0f4d09e71abdc51144246900f6bef5e3c4b333f77d89362 + languageName: node + linkType: hard + "acorn-jsx@npm:^5.3.2": version: 5.3.2 resolution: "acorn-jsx@npm:5.3.2" @@ -2345,6 +2416,19 @@ __metadata: languageName: node linkType: hard +"assert@npm:^2.1.0": + version: 2.1.0 + resolution: "assert@npm:2.1.0" + dependencies: + call-bind: "npm:^1.0.2" + is-nan: "npm:^1.3.2" + object-is: "npm:^1.1.5" + object.assign: "npm:^4.1.4" + util: "npm:^0.12.5" + checksum: 10c0/7271a5da883c256a1fa690677bf1dd9d6aa882139f2bed1cd15da4f9e7459683e1da8e32a203d6cc6767e5e0f730c77a9532a87b896b4b0af0dd535f668775f0 + languageName: node + linkType: hard + "astral-regex@npm:^2.0.0": version: 2.0.0 resolution: "astral-regex@npm:2.0.0" @@ -2385,6 +2469,13 @@ __metadata: languageName: node linkType: hard +"b4a@npm:^1.6.4": + version: 1.6.7 + resolution: "b4a@npm:1.6.7" + checksum: 10c0/ec2f004d1daae04be8c5a1f8aeb7fea213c34025e279db4958eb0b82c1729ee25f7c6e89f92a5f65c8a9cf2d017ce27e3dda912403341d1781bd74528a4849d4 + languageName: node + linkType: hard + "babel-jest@npm:^29.7.0": version: 29.7.0 resolution: "babel-jest@npm:29.7.0" @@ -2478,6 +2569,62 @@ __metadata: languageName: node linkType: hard +"bare-events@npm:^2.2.0, bare-events@npm:^2.5.4": + version: 2.5.4 + resolution: "bare-events@npm:2.5.4" + checksum: 10c0/877a9cea73d545e2588cdbd6fd01653e27dac48ad6b44985cdbae73e1f57f292d4ba52e25d1fba53674c1053c463d159f3d5c7bc36a2e6e192e389b499ddd627 + languageName: node + linkType: hard + +"bare-fs@npm:^4.0.1": + version: 4.1.5 + resolution: "bare-fs@npm:4.1.5" + dependencies: + bare-events: "npm:^2.5.4" + bare-path: "npm:^3.0.0" + bare-stream: "npm:^2.6.4" + peerDependencies: + bare-buffer: "*" + peerDependenciesMeta: + bare-buffer: + optional: true + checksum: 10c0/af72ec30bb7844524faa14ae2b74d13b08920b1d839c638da4ad1abdda643958d0b86653d284878a2f9160072b603c9dce55c8cc29da8d84e14ffce1c5d42a01 + languageName: node + linkType: hard + +"bare-os@npm:^3.0.1": + version: 3.6.1 + resolution: "bare-os@npm:3.6.1" + checksum: 10c0/13064789b3d0d3051d6a89424e6d861c08be101798d69faa78821cffb428b36d1fd4e17c824d5a4939bcd96dbff42c11921494139c8e53c3e520bc0e3f83aeee + languageName: node + linkType: hard + +"bare-path@npm:^3.0.0": + version: 3.0.0 + resolution: "bare-path@npm:3.0.0" + dependencies: + bare-os: "npm:^3.0.1" + checksum: 10c0/56a3ca82a9f808f4976cb1188640ac206546ce0ddff582afafc7bd2a6a5b31c3bd16422653aec656eeada2830cfbaa433c6cbf6d6b4d9eba033d5e06d60d9a68 + languageName: node + linkType: hard + +"bare-stream@npm:^2.6.4": + version: 2.6.5 + resolution: "bare-stream@npm:2.6.5" + dependencies: + streamx: "npm:^2.21.0" + peerDependencies: + bare-buffer: "*" + bare-events: "*" + peerDependenciesMeta: + bare-buffer: + optional: true + bare-events: + optional: true + checksum: 10c0/1242286f8f3147e9fd353cdaa9cf53226a807ac0dde8177c13f1463aa4cd1f88e07407c883a1b322b901e9af2d1cd30aacd873529031132c384622972e0419df + languageName: node + linkType: hard + "base64-js@npm:^1.3.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" @@ -2485,6 +2632,15 @@ __metadata: languageName: node linkType: hard +"basic-auth@npm:~2.0.1": + version: 2.0.1 + resolution: "basic-auth@npm:2.0.1" + dependencies: + safe-buffer: "npm:5.1.2" + checksum: 10c0/05f56db3a0fc31c89c86b605231e32ee143fb6ae38dc60616bc0970ae6a0f034172def99e69d3aed0e2c9e7cac84e2d63bc51a0b5ff6ab5fc8808cc8b29923c1 + languageName: node + linkType: hard + "binary-extensions@npm:^2.0.0": version: 2.3.0 resolution: "binary-extensions@npm:2.3.0" @@ -2657,6 +2813,24 @@ __metadata: languageName: node linkType: hard +"browserify-zlib@npm:^0.1.4": + version: 0.1.4 + resolution: "browserify-zlib@npm:0.1.4" + dependencies: + pako: "npm:~0.2.0" + checksum: 10c0/0cde7ca5d33d43125649330fd75c056397e53731956a2593c4a2529f4e609a8e6abdb2b8e1921683abf5645375b92cfb2a21baa42fe3c9fc3e2556d32043af93 + languageName: node + linkType: hard + +"browserify-zlib@npm:^0.2.0": + version: 0.2.0 + resolution: "browserify-zlib@npm:0.2.0" + dependencies: + pako: "npm:~1.0.5" + checksum: 10c0/9ab10b6dc732c6c5ec8ebcbe5cb7fe1467f97402c9b2140113f47b5f187b9438f93a8e065d8baf8b929323c18324fbf1105af479ee86d9d36cab7d7ef3424ad9 + languageName: node + linkType: hard + "browserslist@npm:^4.24.0, browserslist@npm:^4.24.3": version: 4.24.4 resolution: "browserslist@npm:4.24.4" @@ -2744,6 +2918,13 @@ __metadata: languageName: node linkType: hard +"builtin-status-codes@npm:^3.0.0": + version: 3.0.0 + resolution: "builtin-status-codes@npm:3.0.0" + checksum: 10c0/c37bbba11a34c4431e56bd681b175512e99147defbe2358318d8152b3a01df7bf25e0305873947e5b350073d5ef41a364a22b37e48f1fb6d2fe6d5286a0f348c + languageName: node + linkType: hard + "bundle-name@npm:^4.1.0": version: 4.1.0 resolution: "bundle-name@npm:4.1.0" @@ -2820,6 +3001,16 @@ __metadata: languageName: node linkType: hard +"cache-content-type@npm:^1.0.0": + version: 1.0.1 + resolution: "cache-content-type@npm:1.0.1" + dependencies: + mime-types: "npm:^2.1.18" + ylru: "npm:^1.2.0" + checksum: 10c0/59b50e29e64a24bb52a16e5d35b69ad27ef14313701acc5e462b0aeebf2f09ff87fb6538eb0c0f0de4de05c8a1eecaef47f455f5b4928079e68f607f816a0843 + languageName: node + linkType: hard + "call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.2": version: 1.0.2 resolution: "call-bind-apply-helpers@npm:1.0.2" @@ -2840,7 +3031,7 @@ __metadata: languageName: node linkType: hard -"call-bind@npm:^1.0.8": +"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2, call-bind@npm:^1.0.7, call-bind@npm:^1.0.8": version: 1.0.8 resolution: "call-bind@npm:1.0.8" dependencies: @@ -3236,6 +3427,29 @@ __metadata: languageName: node linkType: hard +"console-browserify@npm:^1.2.0": + version: 1.2.0 + resolution: "console-browserify@npm:1.2.0" + checksum: 10c0/89b99a53b7d6cee54e1e64fa6b1f7ac24b844b4019c5d39db298637e55c1f4ffa5c165457ad984864de1379df2c8e1886cbbdac85d9dbb6876a9f26c3106f226 + languageName: node + linkType: hard + +"content-disposition@npm:~0.5.2": + version: 0.5.4 + resolution: "content-disposition@npm:0.5.4" + dependencies: + safe-buffer: "npm:5.2.1" + checksum: 10c0/bac0316ebfeacb8f381b38285dc691c9939bf0a78b0b7c2d5758acadad242d04783cee5337ba7d12a565a19075af1b3c11c728e1e4946de73c6ff7ce45f3f1bb + languageName: node + linkType: hard + +"content-type@npm:^1.0.4, content-type@npm:^1.0.5": + version: 1.0.5 + resolution: "content-type@npm:1.0.5" + checksum: 10c0/b76ebed15c000aee4678c3707e0860cb6abd4e680a598c0a26e17f0bfae723ec9cc2802f0ff1bc6e4d80603719010431d2231018373d4dde10f9ccff9dadf5af + languageName: node + linkType: hard + "convert-source-map@npm:^2.0.0": version: 2.0.0 resolution: "convert-source-map@npm:2.0.0" @@ -3243,6 +3457,16 @@ __metadata: languageName: node linkType: hard +"cookies@npm:~0.9.1": + version: 0.9.1 + resolution: "cookies@npm:0.9.1" + dependencies: + depd: "npm:~2.0.0" + keygrip: "npm:~1.1.0" + checksum: 10c0/3ffa1c0e992b62ee119adae4dd2ddd4a89166fa5434cd9bd9ff84ec4d2f14dfe2318a601280abfe32a4f64f884ec9345fb1912e488b002d188d2efa0d3919ba3 + languageName: node + linkType: hard + "copy-webpack-plugin@npm:^12.0.2": version: 12.0.2 resolution: "copy-webpack-plugin@npm:12.0.2" @@ -3387,6 +3611,15 @@ __metadata: languageName: node linkType: hard +"debug@npm:2.6.9": + version: 2.6.9 + resolution: "debug@npm:2.6.9" + dependencies: + ms: "npm:2.0.0" + checksum: 10c0/121908fb839f7801180b69a7e218a40b5a0b718813b886b7d6bdb82001b931c938e2941d1e4450f33a1b1df1da653f5f7a0440c197f29fbf8a6e9d45ff6ef589 + languageName: node + linkType: hard + "debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.4.0": version: 4.4.0 resolution: "debug@npm:4.4.0" @@ -3399,7 +3632,16 @@ __metadata: languageName: node linkType: hard -"debug@npm:^4.0.0": +"debug@npm:^3.1.0": + version: 3.2.7 + resolution: "debug@npm:3.2.7" + dependencies: + ms: "npm:^2.1.1" + checksum: 10c0/37d96ae42cbc71c14844d2ae3ba55adf462ec89fd3a999459dec3833944cd999af6007ff29c780f1c61153bcaaf2c842d1e4ce1ec621e4fc4923244942e4a02a + languageName: node + linkType: hard + +"debug@npm:^4.0.0, debug@npm:^4.0.1": version: 4.4.1 resolution: "debug@npm:4.4.1" dependencies: @@ -3439,6 +3681,13 @@ __metadata: languageName: node linkType: hard +"deep-equal@npm:~1.0.1": + version: 1.0.1 + resolution: "deep-equal@npm:1.0.1" + checksum: 10c0/bef838ef9824e124d10335deb9c7540bfc9f2f0eab17ad1bb870d0eee83ee4e7e6f6f892e5eebc2bd82759a76676926ad5246180097e28e57752176ff7dae888 + languageName: node + linkType: hard + "deep-extend@npm:^0.6.0": version: 0.6.0 resolution: "deep-extend@npm:0.6.0" @@ -3484,7 +3733,7 @@ __metadata: languageName: node linkType: hard -"define-data-property@npm:^1.1.4": +"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4": version: 1.1.4 resolution: "define-data-property@npm:1.1.4" dependencies: @@ -3502,6 +3751,17 @@ __metadata: languageName: node linkType: hard +"define-properties@npm:^1.1.3, define-properties@npm:^1.2.1": + version: 1.2.1 + resolution: "define-properties@npm:1.2.1" + dependencies: + define-data-property: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.0" + object-keys: "npm:^1.1.1" + checksum: 10c0/88a152319ffe1396ccc6ded510a3896e77efac7a1bfbaa174a7b00414a1747377e0bb525d303794a47cf30e805c2ec84e575758512c6e44a993076d29fd4e6c3 + languageName: node + linkType: hard + "delayed-stream@npm:~1.0.0": version: 1.0.0 resolution: "delayed-stream@npm:1.0.0" @@ -3509,6 +3769,27 @@ __metadata: languageName: node linkType: hard +"delegates@npm:^1.0.0": + version: 1.0.0 + resolution: "delegates@npm:1.0.0" + checksum: 10c0/ba05874b91148e1db4bf254750c042bf2215febd23a6d3cda2e64896aef79745fbd4b9996488bd3cafb39ce19dbce0fd6e3b6665275638befffe1c9b312b91b5 + languageName: node + linkType: hard + +"depd@npm:2.0.0, depd@npm:~2.0.0": + version: 2.0.0 + resolution: "depd@npm:2.0.0" + checksum: 10c0/58bd06ec20e19529b06f7ad07ddab60e504d9e0faca4bd23079fac2d279c3594334d736508dc350e06e510aba5e22e4594483b3a6562ce7c17dd797f4cc4ad2c + languageName: node + linkType: hard + +"depd@npm:~1.1.2": + version: 1.1.2 + resolution: "depd@npm:1.1.2" + checksum: 10c0/acb24aaf936ef9a227b6be6d495f0d2eb20108a9a6ad40585c5bda1a897031512fef6484e4fdbb80bd249fdaa82841fa1039f416ece03188e677ba11bcfda249 + languageName: node + linkType: hard + "des.js@npm:^1.0.0": version: 1.1.0 resolution: "des.js@npm:1.1.0" @@ -3519,6 +3800,13 @@ __metadata: languageName: node linkType: hard +"destroy@npm:^1.0.4": + version: 1.2.0 + resolution: "destroy@npm:1.2.0" + checksum: 10c0/bd7633942f57418f5a3b80d5cb53898127bcf53e24cdf5d5f4396be471417671f0fee48a4ebe9a1e9defbde2a31280011af58a57e090ff822f589b443ed4e643 + languageName: node + linkType: hard + "detect-libc@npm:^2.0.0": version: 2.0.3 resolution: "detect-libc@npm:2.0.3" @@ -3614,6 +3902,18 @@ __metadata: languageName: node linkType: hard +"duplexify@npm:^3.5.0, duplexify@npm:^3.6.0": + version: 3.7.1 + resolution: "duplexify@npm:3.7.1" + dependencies: + end-of-stream: "npm:^1.0.0" + inherits: "npm:^2.0.1" + readable-stream: "npm:^2.0.0" + stream-shift: "npm:^1.0.0" + checksum: 10c0/59d1440c1b4e3a4db35ae96933392703ce83518db1828d06b9b6322920d6cbbf0b7159e88be120385fe459e77f1eb0c7622f26e9ec1f47c9ff05c2b35747dbd3 + languageName: node + linkType: hard + "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -3630,6 +3930,13 @@ __metadata: languageName: node linkType: hard +"ee-first@npm:1.1.1": + version: 1.1.1 + resolution: "ee-first@npm:1.1.1" + checksum: 10c0/b5bb125ee93161bc16bfe6e56c6b04de5ad2aa44234d8f644813cc95d861a6910903132b05093706de2b706599367c4130eb6d170f6b46895686b95f87d017b7 + languageName: node + linkType: hard + "ejs@npm:^3.1.10": version: 3.1.10 resolution: "ejs@npm:3.1.10" @@ -3691,6 +3998,13 @@ __metadata: languageName: node linkType: hard +"encodeurl@npm:^2.0.0": + version: 2.0.0 + resolution: "encodeurl@npm:2.0.0" + checksum: 10c0/5d317306acb13e6590e28e27924c754163946a2480de11865c991a3a7eed4315cd3fba378b543ca145829569eefe9b899f3d84bb09870f675ae60bc924b01ceb + languageName: node + linkType: hard + "encoding-sniffer@npm:^0.2.0": version: 0.2.0 resolution: "encoding-sniffer@npm:0.2.0" @@ -3710,7 +4024,7 @@ __metadata: languageName: node linkType: hard -"end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": +"end-of-stream@npm:^1.0.0, end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": version: 1.4.4 resolution: "end-of-stream@npm:1.4.4" dependencies: @@ -3817,6 +4131,13 @@ __metadata: languageName: node linkType: hard +"escape-html@npm:^1.0.3": + version: 1.0.3 + resolution: "escape-html@npm:1.0.3" + checksum: 10c0/524c739d776b36c3d29fa08a22e03e8824e3b2fd57500e5e44ecf3cc4707c34c60f9ca0781c0e33d191f2991161504c295e98f68c78fe7baa6e57081ec6ac0a3 + languageName: node + linkType: hard + "escape-string-regexp@npm:^1.0.5": version: 1.0.5 resolution: "escape-string-regexp@npm:1.0.5" @@ -4130,6 +4451,13 @@ __metadata: languageName: node linkType: hard +"fast-fifo@npm:^1.2.0, fast-fifo@npm:^1.3.2": + version: 1.3.2 + resolution: "fast-fifo@npm:1.3.2" + checksum: 10c0/d53f6f786875e8b0529f784b59b4b05d4b5c31c651710496440006a398389a579c8dbcd2081311478b5bf77f4b0b21de69109c5a4eabea9d8e8783d1eb864e4c + languageName: node + linkType: hard + "fast-glob@npm:^3.3.2, fast-glob@npm:^3.3.3": version: 3.3.3 resolution: "fast-glob@npm:3.3.3" @@ -4207,6 +4535,18 @@ __metadata: languageName: node linkType: hard +"fdir@npm:^6.4.4": + version: 6.4.5 + resolution: "fdir@npm:6.4.5" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: 10c0/5d63330a1b97165e9b0fb20369fafc7cf826bc4b3e374efcb650bc77d7145ac01193b5da1a7591eab89ae6fd6b15cdd414085910b2a2b42296b1480c9f2677af + languageName: node + linkType: hard + "file-entry-cache@npm:^8.0.0": version: 8.0.0 resolution: "file-entry-cache@npm:8.0.0" @@ -4318,6 +4658,13 @@ __metadata: languageName: node linkType: hard +"fresh@npm:~0.5.2": + version: 0.5.2 + resolution: "fresh@npm:0.5.2" + checksum: 10c0/c6d27f3ed86cc5b601404822f31c900dd165ba63fff8152a3ef714e2012e7535027063bc67ded4cb5b3a49fa596495d46cacd9f47d6328459cf570f08b7d9e5a + languageName: node + linkType: hard + "fs-constants@npm:^1.0.0": version: 1.0.0 resolution: "fs-constants@npm:1.0.0" @@ -4352,6 +4699,16 @@ __metadata: languageName: node linkType: hard +"fsevents@npm:2.3.2": + version: 2.3.2 + resolution: "fsevents@npm:2.3.2" + dependencies: + node-gyp: "npm:latest" + checksum: 10c0/be78a3efa3e181cda3cf7a4637cb527bcebb0bd0ea0440105a3bb45b86f9245b307dc10a2507e8f4498a7d4ec349d1910f4d73e4d4495b16103106e07eee735b + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@npm:^2.3.2, fsevents@npm:~2.3.2": version: 2.3.3 resolution: "fsevents@npm:2.3.3" @@ -4362,6 +4719,15 @@ __metadata: languageName: node linkType: hard +"fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin": + version: 2.3.2 + resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin::version=2.3.2&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@patch:fsevents@npm%3A^2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" @@ -4629,6 +4995,22 @@ __metadata: languageName: node linkType: hard +"gunzip-maybe@npm:^1.4.2": + version: 1.4.2 + resolution: "gunzip-maybe@npm:1.4.2" + dependencies: + browserify-zlib: "npm:^0.1.4" + is-deflate: "npm:^1.0.0" + is-gzip: "npm:^1.0.0" + peek-stream: "npm:^1.1.0" + pumpify: "npm:^1.3.3" + through2: "npm:^2.0.3" + bin: + gunzip-maybe: bin.js + checksum: 10c0/42798a8061759885c2084e1804e51313d14f2dc9cf6c137e222953ec802f914e592d6f9dbf6ad67f4e78eb036e86db017d9c7c93bb23e90cd5ae09326296ed77 + languageName: node + linkType: hard + "has-flag@npm:^3.0.0": version: 3.0.0 resolution: "has-flag@npm:3.0.0" @@ -4643,7 +5025,7 @@ __metadata: languageName: node linkType: hard -"has-property-descriptors@npm:^1.0.2": +"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2": version: 1.0.2 resolution: "has-property-descriptors@npm:1.0.2" dependencies: @@ -4772,6 +5154,16 @@ __metadata: languageName: node linkType: hard +"http-assert@npm:^1.3.0": + version: 1.5.0 + resolution: "http-assert@npm:1.5.0" + dependencies: + deep-equal: "npm:~1.0.1" + http-errors: "npm:~1.8.0" + checksum: 10c0/7b4e631114a1a77654f9ba3feb96da305ddbdeb42112fe384b7b3249c7141e460d7177970155bea6e54e655a04850415b744b452c1fe5052eba6f4186d16b095 + languageName: node + linkType: hard + "http-cache-semantics@npm:^4.1.1": version: 4.1.1 resolution: "http-cache-semantics@npm:4.1.1" @@ -4779,6 +5171,44 @@ __metadata: languageName: node linkType: hard +"http-errors@npm:^1.7.3, http-errors@npm:~1.8.0": + version: 1.8.1 + resolution: "http-errors@npm:1.8.1" + dependencies: + depd: "npm:~1.1.2" + inherits: "npm:2.0.4" + setprototypeof: "npm:1.2.0" + statuses: "npm:>= 1.5.0 < 2" + toidentifier: "npm:1.0.1" + checksum: 10c0/f01aeecd76260a6fe7f08e192fcbe9b2f39ed20fc717b852669a69930167053b01790998275c6297d44f435cf0e30edd50c05223d1bec9bc484e6cf35b2d6f43 + languageName: node + linkType: hard + +"http-errors@npm:^2.0.0": + version: 2.0.0 + resolution: "http-errors@npm:2.0.0" + dependencies: + depd: "npm:2.0.0" + inherits: "npm:2.0.4" + setprototypeof: "npm:1.2.0" + statuses: "npm:2.0.1" + toidentifier: "npm:1.0.1" + checksum: 10c0/fc6f2715fe188d091274b5ffc8b3657bd85c63e969daa68ccb77afb05b071a4b62841acb7a21e417b5539014dff2ebf9550f0b14a9ff126f2734a7c1387f8e19 + languageName: node + linkType: hard + +"http-errors@npm:~1.6.2": + version: 1.6.3 + resolution: "http-errors@npm:1.6.3" + dependencies: + depd: "npm:~1.1.2" + inherits: "npm:2.0.3" + setprototypeof: "npm:1.1.0" + statuses: "npm:>= 1.4.0 < 2" + checksum: 10c0/17ec4046ee974477778bfdd525936c254b872054703ec2caa4d6f099566b8adade636ae6aeeacb39302c5cd6e28fb407ebd937f500f5010d0b6850750414ff78 + languageName: node + linkType: hard + "http-proxy-agent@npm:^7.0.0, http-proxy-agent@npm:^7.0.2": version: 7.0.2 resolution: "http-proxy-agent@npm:7.0.2" @@ -4789,7 +5219,14 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:^7.0.0, https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.5": +"https-browserify@npm:^1.0.0": + version: 1.0.0 + resolution: "https-browserify@npm:1.0.0" + checksum: 10c0/e17b6943bc24ea9b9a7da5714645d808670af75a425f29baffc3284962626efdc1eb3aa9bbffaa6e64028a6ad98af5b09fabcb454a8f918fb686abfdc9e9b8ae + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.0, https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.5, https-proxy-agent@npm:^7.0.6": version: 7.0.6 resolution: "https-proxy-agent@npm:7.0.6" dependencies: @@ -4898,13 +5335,20 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3, inherits@npm:~2.0.4": +"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3, inherits@npm:~2.0.4": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 languageName: node linkType: hard +"inherits@npm:2.0.3": + version: 2.0.3 + resolution: "inherits@npm:2.0.3" + checksum: 10c0/6e56402373149ea076a434072671f9982f5fad030c7662be0332122fe6c0fa490acb3cc1010d90b6eff8d640b1167d77674add52dfd1bb85d545cf29e80e73e7 + languageName: node + linkType: hard + "ini@npm:~1.3.0": version: 1.3.8 resolution: "ini@npm:1.3.8" @@ -5011,6 +5455,13 @@ __metadata: languageName: node linkType: hard +"is-deflate@npm:^1.0.0": + version: 1.0.0 + resolution: "is-deflate@npm:1.0.0" + checksum: 10c0/35f7ffcbef3549dd8a4d8df5dc09b4f4656a0fc88326e8b5201cda54114a9c2d8efb689d87c16f3f35c95bd71dcf13dc790d62b7504745b42c53ab4b40238f5a + languageName: node + linkType: hard + "is-docker@npm:^3.0.0": version: 3.0.0 resolution: "is-docker@npm:3.0.0" @@ -5062,6 +5513,13 @@ __metadata: languageName: node linkType: hard +"is-gzip@npm:^1.0.0": + version: 1.0.0 + resolution: "is-gzip@npm:1.0.0" + checksum: 10c0/cbc1db080c636a6fb0f7346e3076f8276a29a9d8b52ae67c1971a8131c43f308e98ed227d1a6f49970e6c6ebabee0568e60aed7a3579dd4e1817cddf2faaf9b7 + languageName: node + linkType: hard + "is-hexadecimal@npm:^1.0.0": version: 1.0.4 resolution: "is-hexadecimal@npm:1.0.4" @@ -5101,6 +5559,16 @@ __metadata: languageName: node linkType: hard +"is-nan@npm:^1.3.2": + version: 1.3.2 + resolution: "is-nan@npm:1.3.2" + dependencies: + call-bind: "npm:^1.0.0" + define-properties: "npm:^1.1.3" + checksum: 10c0/8bfb286f85763f9c2e28ea32e9127702fe980ffd15fa5d63ade3be7786559e6e21355d3625dd364c769c033c5aedf0a2ed3d4025d336abf1b9241e3d9eddc5b0 + languageName: node + linkType: hard + "is-number@npm:^7.0.0": version: 7.0.0 resolution: "is-number@npm:7.0.0" @@ -5962,6 +6430,15 @@ __metadata: languageName: node linkType: hard +"keygrip@npm:~1.1.0": + version: 1.1.0 + resolution: "keygrip@npm:1.1.0" + dependencies: + tsscmp: "npm:1.0.6" + checksum: 10c0/2aceec1a1e642a0caf938044056ed67b1909cfe67a93a59b32aae2863e0f35a1a53782ecc8f9cd0e3bdb60863fa0f401ccbd257cd7dfae61915f78445139edea + languageName: node + linkType: hard + "keytar@npm:^7.7.0": version: 7.9.0 resolution: "keytar@npm:7.9.0" @@ -5996,6 +6473,80 @@ __metadata: languageName: node linkType: hard +"koa-compose@npm:^4.1.0": + version: 4.1.0 + resolution: "koa-compose@npm:4.1.0" + checksum: 10c0/f1f786f994a691931148e7f38f443865bf2702af4a61610d1eea04dab79c04b1232285b59d82a0cf61c830516dd92f10ab0d009b024fcecd4098e7d296ab771a + languageName: node + linkType: hard + +"koa-morgan@npm:^1.0.1": + version: 1.0.1 + resolution: "koa-morgan@npm:1.0.1" + dependencies: + morgan: "npm:^1.6.1" + checksum: 10c0/385714f35d6fc094961688d6470e64868600c9ddfa6c18737e916cd2ffcf400af67c9214b250a164df0eb3e8659820c5e68c324666ab1a69a861886d5f1bb253 + languageName: node + linkType: hard + +"koa-mount@npm:^4.2.0": + version: 4.2.0 + resolution: "koa-mount@npm:4.2.0" + dependencies: + debug: "npm:^4.0.1" + koa-compose: "npm:^4.1.0" + checksum: 10c0/2eb2201df6ab7ad09e8a9c4c9e2da3b51c8e4b1acd1847e4e44d9e9f317abdf3b014bf7ccf2a89558381fe8b1773a25ea1fde2212c79d76b4fb052d3e8a38363 + languageName: node + linkType: hard + +"koa-send@npm:^5.0.0": + version: 5.0.1 + resolution: "koa-send@npm:5.0.1" + dependencies: + debug: "npm:^4.1.1" + http-errors: "npm:^1.7.3" + resolve-path: "npm:^1.4.0" + checksum: 10c0/787a8abaf3690a86cf2e6021f1d870daba5f8393f4b4da4da74c26e7d1f7a89636fa2f251a0ec1ea75364fc81a9ef20d3c52e8e2dc7ad9f1d5053357a0db204f + languageName: node + linkType: hard + +"koa-static@npm:^5.0.0": + version: 5.0.0 + resolution: "koa-static@npm:5.0.0" + dependencies: + debug: "npm:^3.1.0" + koa-send: "npm:^5.0.0" + checksum: 10c0/4cb7a4e98506d54274658eb3565b24fcbe606bbb6916cb5ef226b2613d3ffd417dec3404000baa171f2206f2a6d29117bbe881fd26b27d54ef746d9de6de3e91 + languageName: node + linkType: hard + +"koa@npm:^3.0.0": + version: 3.0.0 + resolution: "koa@npm:3.0.0" + dependencies: + accepts: "npm:^1.3.5" + cache-content-type: "npm:^1.0.0" + content-disposition: "npm:~0.5.2" + content-type: "npm:^1.0.4" + cookies: "npm:~0.9.1" + debug: "npm:^4.3.2" + delegates: "npm:^1.0.0" + destroy: "npm:^1.0.4" + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + fresh: "npm:~0.5.2" + http-assert: "npm:^1.3.0" + http-errors: "npm:^2.0.0" + koa-compose: "npm:^4.1.0" + on-finished: "npm:^2.3.0" + parseurl: "npm:^1.3.2" + statuses: "npm:^2.0.1" + type-is: "npm:^2.0.1" + vary: "npm:^1.1.2" + checksum: 10c0/300203227074ee6c4c4a1393692fbeea49a2ece71539ecc9f99862e001a2ad9ffe9aa38327bf599d74541d59af4391fa1e4384bd5a4b8d7050012ed0adf4d9fc + languageName: node + linkType: hard + "leven@npm:^3.1.0": version: 3.1.0 resolution: "leven@npm:3.1.0" @@ -6416,6 +6967,13 @@ __metadata: languageName: node linkType: hard +"media-typer@npm:^1.1.0": + version: 1.1.0 + resolution: "media-typer@npm:1.1.0" + checksum: 10c0/7b4baa40b25964bb90e2121ee489ec38642127e48d0cc2b6baa442688d3fde6262bfdca86d6bbf6ba708784afcac168c06840c71facac70e390f5f759ac121b9 + languageName: node + linkType: hard + "merge-stream@npm:^2.0.0": version: 2.0.0 resolution: "merge-stream@npm:2.0.0" @@ -6544,7 +7102,14 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27": +"mime-db@npm:^1.54.0": + version: 1.54.0 + resolution: "mime-db@npm:1.54.0" + checksum: 10c0/8d907917bc2a90fa2df842cdf5dfeaf509adc15fe0531e07bb2f6ab15992416479015828d6a74200041c492e42cce3ebf78e5ce714388a0a538ea9c53eece284 + languageName: node + linkType: hard + +"mime-types@npm:^2.1.12, mime-types@npm:^2.1.18, mime-types@npm:^2.1.27, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -6553,6 +7118,15 @@ __metadata: languageName: node linkType: hard +"mime-types@npm:^3.0.0": + version: 3.0.1 + resolution: "mime-types@npm:3.0.1" + dependencies: + mime-db: "npm:^1.54.0" + checksum: 10c0/bd8c20d3694548089cf229016124f8f40e6a60bbb600161ae13e45f793a2d5bb40f96bbc61f275836696179c77c1d6bf4967b2a75e0a8ad40fe31f4ed5be4da5 + languageName: node + linkType: hard + "mime@npm:^1.3.4": version: 1.6.0 resolution: "mime@npm:1.6.0" @@ -6633,7 +7207,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.6": +"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.6, minimist@npm:^1.2.8": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 @@ -6764,6 +7338,26 @@ __metadata: languageName: node linkType: hard +"morgan@npm:^1.6.1": + version: 1.10.0 + resolution: "morgan@npm:1.10.0" + dependencies: + basic-auth: "npm:~2.0.1" + debug: "npm:2.6.9" + depd: "npm:~2.0.0" + on-finished: "npm:~2.3.0" + on-headers: "npm:~1.0.2" + checksum: 10c0/684db061daca28f8d8e3bfd50bd0d21734401b46f74ea76f6df7785d45698fcd98f6d3b81a6bad59f8288c429183afba728c428e8f66d2e8c30fd277af3b5b3a + languageName: node + linkType: hard + +"ms@npm:2.0.0": + version: 2.0.0 + resolution: "ms@npm:2.0.0" + checksum: 10c0/f8fda810b39fd7255bbdc451c46286e549794fcc700dc9cd1d25658bbc4dc2563a5de6fe7c60f798a16a60c6ceb53f033cb353f493f0cf63e5199b702943159d + languageName: node + linkType: hard + "ms@npm:^2.1.1, ms@npm:^2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" @@ -6792,6 +7386,13 @@ __metadata: languageName: node linkType: hard +"negotiator@npm:0.6.3": + version: 0.6.3 + resolution: "negotiator@npm:0.6.3" + checksum: 10c0/3ec9fd413e7bf071c937ae60d572bc67155262068ed522cf4b3be5edbe6ddf67d095ec03a3a14ebf8fc8e95f8e1d61be4869db0dbb0de696f6b837358bd43fc2 + languageName: node + linkType: hard + "negotiator@npm:^1.0.0": version: 1.0.0 resolution: "negotiator@npm:1.0.0" @@ -6941,6 +7542,62 @@ __metadata: languageName: node linkType: hard +"object-is@npm:^1.1.5": + version: 1.1.6 + resolution: "object-is@npm:1.1.6" + dependencies: + call-bind: "npm:^1.0.7" + define-properties: "npm:^1.2.1" + checksum: 10c0/506af444c4dce7f8e31f34fc549e2fb8152d6b9c4a30c6e62852badd7f520b579c679af433e7a072f9d78eb7808d230dc12e1cf58da9154dfbf8813099ea0fe0 + languageName: node + linkType: hard + +"object-keys@npm:^1.1.1": + version: 1.1.1 + resolution: "object-keys@npm:1.1.1" + checksum: 10c0/b11f7ccdbc6d406d1f186cdadb9d54738e347b2692a14439ca5ac70c225fa6db46db809711b78589866d47b25fc3e8dee0b4c722ac751e11180f9380e3d8601d + languageName: node + linkType: hard + +"object.assign@npm:^4.1.4": + version: 4.1.7 + resolution: "object.assign@npm:4.1.7" + dependencies: + call-bind: "npm:^1.0.8" + call-bound: "npm:^1.0.3" + define-properties: "npm:^1.2.1" + es-object-atoms: "npm:^1.0.0" + has-symbols: "npm:^1.1.0" + object-keys: "npm:^1.1.1" + checksum: 10c0/3b2732bd860567ea2579d1567525168de925a8d852638612846bd8082b3a1602b7b89b67b09913cbb5b9bd6e95923b2ae73580baa9d99cb4e990564e8cbf5ddc + languageName: node + linkType: hard + +"on-finished@npm:^2.3.0": + version: 2.4.1 + resolution: "on-finished@npm:2.4.1" + dependencies: + ee-first: "npm:1.1.1" + checksum: 10c0/46fb11b9063782f2d9968863d9cbba33d77aa13c17f895f56129c274318b86500b22af3a160fe9995aa41317efcd22941b6eba747f718ced08d9a73afdb087b4 + languageName: node + linkType: hard + +"on-finished@npm:~2.3.0": + version: 2.3.0 + resolution: "on-finished@npm:2.3.0" + dependencies: + ee-first: "npm:1.1.1" + checksum: 10c0/c904f9e518b11941eb60279a3cbfaf1289bd0001f600a950255b1dede9fe3df8cd74f38483550b3bb9485165166acb5db500c3b4c4337aec2815c88c96fcc2ea + languageName: node + linkType: hard + +"on-headers@npm:~1.0.2": + version: 1.0.2 + resolution: "on-headers@npm:1.0.2" + checksum: 10c0/f649e65c197bf31505a4c0444875db0258e198292f34b884d73c2f751e91792ef96bb5cf89aa0f4fecc2e4dc662461dda606b1274b0e564f539cae5d2f5fc32f + languageName: node + linkType: hard + "once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0": version: 1.4.0 resolution: "once@npm:1.4.0" @@ -7075,7 +7732,14 @@ __metadata: languageName: node linkType: hard -"pako@npm:~1.0.2": +"pako@npm:~0.2.0": + version: 0.2.9 + resolution: "pako@npm:0.2.9" + checksum: 10c0/79c1806ebcf325b60ae599e4d7227c2e346d7b829dc20f5cf24cef07c934079dc3a61c5b3c8278a2f7a190c4a613e343ea11e5302dbe252efd11712df4b6b041 + languageName: node + linkType: hard + +"pako@npm:~1.0.2, pako@npm:~1.0.5": version: 1.0.11 resolution: "pako@npm:1.0.11" checksum: 10c0/86dd99d8b34c3930345b8bbeb5e1cd8a05f608eeb40967b293f72fe469d0e9c88b783a8777e4cc7dc7c91ce54c5e93d88ff4b4f060e6ff18408fd21030d9ffbe @@ -7181,6 +7845,13 @@ __metadata: languageName: node linkType: hard +"parseurl@npm:^1.3.2": + version: 1.3.3 + resolution: "parseurl@npm:1.3.3" + checksum: 10c0/90dd4760d6f6174adb9f20cf0965ae12e23879b5f5464f38e92fce8073354341e4b3b76fa3d878351efe7d01e617121955284cfd002ab087fba1a0726ec0b4f5 + languageName: node + linkType: hard + "path-browserify@npm:^1.0.1": version: 1.0.1 resolution: "path-browserify@npm:1.0.1" @@ -7195,7 +7866,7 @@ __metadata: languageName: node linkType: hard -"path-is-absolute@npm:^1.0.0": +"path-is-absolute@npm:1.0.1, path-is-absolute@npm:^1.0.0": version: 1.0.1 resolution: "path-is-absolute@npm:1.0.1" checksum: 10c0/127da03c82172a2a50099cddbf02510c1791fc2cc5f7713ddb613a56838db1e8168b121a920079d052e0936c23005562059756d653b7c544c53185efe53be078 @@ -7236,6 +7907,13 @@ __metadata: languageName: node linkType: hard +"path-to-regexp@npm:^6.3.0": + version: 6.3.0 + resolution: "path-to-regexp@npm:6.3.0" + checksum: 10c0/73b67f4638b41cde56254e6354e46ae3a2ebc08279583f6af3d96fe4664fc75788f74ed0d18ca44fa4a98491b69434f9eee73b97bb5314bd1b5adb700f5c18d6 + languageName: node + linkType: hard + "path-type@npm:^5.0.0": version: 5.0.0 resolution: "path-type@npm:5.0.0" @@ -7263,6 +7941,17 @@ __metadata: languageName: node linkType: hard +"peek-stream@npm:^1.1.0": + version: 1.1.3 + resolution: "peek-stream@npm:1.1.3" + dependencies: + buffer-from: "npm:^1.0.0" + duplexify: "npm:^3.5.0" + through2: "npm:^2.0.3" + checksum: 10c0/3c35d1951b8640036f93b1b5628a90f849e49ca4f2e6aba393ff4978413931d9c491c83f71a92f878d5ea4c670af0bba04dfcfb79b310ead22601db7c1420e36 + languageName: node + linkType: hard + "pend@npm:~1.2.0": version: 1.2.0 resolution: "pend@npm:1.2.0" @@ -7307,6 +7996,30 @@ __metadata: languageName: node linkType: hard +"playwright-core@npm:1.52.0": + version: 1.52.0 + resolution: "playwright-core@npm:1.52.0" + bin: + playwright-core: cli.js + checksum: 10c0/640945507e6ca2144e9f596b2a6ecac042c2fd3683ff99e6271e9a7b38f3602d415f282609d569456f66680aab8b3c5bb1b257d8fb63a7fc0ed648261110421f + languageName: node + linkType: hard + +"playwright@npm:^1.52.0": + version: 1.52.0 + resolution: "playwright@npm:1.52.0" + dependencies: + fsevents: "npm:2.3.2" + playwright-core: "npm:1.52.0" + dependenciesMeta: + fsevents: + optional: true + bin: + playwright: cli.js + checksum: 10c0/2c6edf1e15e59bbaf77f3fa0fe0ac975793c17cff835d9c8b8bc6395a3b6f1c01898b3058ab37891b2e4d424bcc8f1b4844fe70d943e0143d239d7451408c579 + languageName: node + linkType: hard + "pluralize@npm:^2.0.0": version: 2.0.0 resolution: "pluralize@npm:2.0.0" @@ -7432,6 +8145,16 @@ __metadata: languageName: node linkType: hard +"pump@npm:^2.0.0": + version: 2.0.1 + resolution: "pump@npm:2.0.1" + dependencies: + end-of-stream: "npm:^1.1.0" + once: "npm:^1.3.1" + checksum: 10c0/f1fe8960f44d145f8617ea4c67de05392da4557052980314c8f85081aee26953bdcab64afad58a2b1df0e8ff7203e3710e848cbe81a01027978edc6e264db355 + languageName: node + linkType: hard + "pump@npm:^3.0.0": version: 3.0.2 resolution: "pump@npm:3.0.2" @@ -7442,6 +8165,17 @@ __metadata: languageName: node linkType: hard +"pumpify@npm:^1.3.3": + version: 1.5.1 + resolution: "pumpify@npm:1.5.1" + dependencies: + duplexify: "npm:^3.6.0" + inherits: "npm:^2.0.3" + pump: "npm:^2.0.0" + checksum: 10c0/0bcabf9e3dbf2d0cc1f9b84ac80d3c75386111caf8963bfd98817a1e2192000ac0ccc804ca6ccd5b2b8430fdb71347b20fb2f014fe3d41adbacb1b502a841c45 + languageName: node + linkType: hard + "punycode.js@npm:^2.3.1": version: 2.3.1 resolution: "punycode.js@npm:2.3.1" @@ -7456,7 +8190,7 @@ __metadata: languageName: node linkType: hard -"punycode@npm:^2.1.0": +"punycode@npm:^2.1.0, punycode@npm:^2.3.1": version: 2.3.1 resolution: "punycode@npm:2.3.1" checksum: 10c0/14f76a8206bc3464f794fb2e3d3cc665ae416c01893ad7a02b23766eb07159144ee612ad67af5e84fa4479ccfe67678c4feb126b0485651b302babf66f04f9e9 @@ -7479,6 +8213,13 @@ __metadata: languageName: node linkType: hard +"querystring-es3@npm:^0.2.1": + version: 0.2.1 + resolution: "querystring-es3@npm:0.2.1" + checksum: 10c0/476938c1adb45c141f024fccd2ffd919a3746e79ed444d00e670aad68532977b793889648980e7ca7ff5ffc7bfece623118d0fbadcaf217495eeb7059ae51580 + languageName: node + linkType: hard + "queue-microtask@npm:^1.2.2": version: 1.2.3 resolution: "queue-microtask@npm:1.2.3" @@ -7582,7 +8323,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^2.3.8, readable-stream@npm:~2.3.6": +"readable-stream@npm:^2.0.0, readable-stream@npm:^2.3.8, readable-stream@npm:~2.3.6": version: 2.3.8 resolution: "readable-stream@npm:2.3.8" dependencies: @@ -7729,6 +8470,16 @@ __metadata: languageName: node linkType: hard +"resolve-path@npm:^1.4.0": + version: 1.4.0 + resolution: "resolve-path@npm:1.4.0" + dependencies: + http-errors: "npm:~1.6.2" + path-is-absolute: "npm:1.0.1" + checksum: 10c0/7405c01e02c7c71c62f89e42eac1b876e5a1bb9c3b85e07ce674646841dd177571bca5639ff6780528bec9ff58be7b44845e69eced1d8c5d519f4c1d72c30907 + languageName: node + linkType: hard + "resolve.exports@npm:^2.0.0": version: 2.0.3 resolution: "resolve.exports@npm:2.0.3" @@ -7823,20 +8574,20 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.1.1, safe-buffer@npm:^5.1.2, safe-buffer@npm:^5.2.0, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0": - version: 5.2.1 - resolution: "safe-buffer@npm:5.2.1" - checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 - languageName: node - linkType: hard - -"safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": +"safe-buffer@npm:5.1.2, safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": version: 5.1.2 resolution: "safe-buffer@npm:5.1.2" checksum: 10c0/780ba6b5d99cc9a40f7b951d47152297d0e260f0df01472a1b99d4889679a4b94a13d644f7dbc4f022572f09ae9005fa2fbb93bbbd83643316f365a3e9a45b21 languageName: node linkType: hard +"safe-buffer@npm:5.2.1, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.1.1, safe-buffer@npm:^5.1.2, safe-buffer@npm:^5.2.0, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 + languageName: node + linkType: hard + "safe-regex-test@npm:^1.1.0": version: 1.1.0 resolution: "safe-regex-test@npm:1.1.0" @@ -7952,13 +8703,27 @@ __metadata: languageName: node linkType: hard -"setimmediate@npm:^1.0.5": +"setimmediate@npm:^1.0.4, setimmediate@npm:^1.0.5": version: 1.0.5 resolution: "setimmediate@npm:1.0.5" checksum: 10c0/5bae81bfdbfbd0ce992893286d49c9693c82b1bcc00dcaaf3a09c8f428fdeacf4190c013598b81875dfac2b08a572422db7df779a99332d0fce186d15a3e4d49 languageName: node linkType: hard +"setprototypeof@npm:1.1.0": + version: 1.1.0 + resolution: "setprototypeof@npm:1.1.0" + checksum: 10c0/a77b20876689c6a89c3b42f0c3596a9cae02f90fc902570cbd97198e9e8240382086c9303ad043e88cee10f61eae19f1004e51d885395a1e9bf49f9ebed12872 + languageName: node + linkType: hard + +"setprototypeof@npm:1.2.0": + version: 1.2.0 + resolution: "setprototypeof@npm:1.2.0" + checksum: 10c0/68733173026766fa0d9ecaeb07f0483f4c2dc70ca376b3b7c40b7cda909f94b0918f6c5ad5ce27a9160bdfb475efaa9d5e705a11d8eaae18f9835d20976028bc + languageName: node + linkType: hard + "sha.js@npm:^2.4.0, sha.js@npm:^2.4.8": version: 2.4.11 resolution: "sha.js@npm:2.4.11" @@ -8236,6 +9001,20 @@ __metadata: languageName: node linkType: hard +"statuses@npm:2.0.1, statuses@npm:^2.0.1": + version: 2.0.1 + resolution: "statuses@npm:2.0.1" + checksum: 10c0/34378b207a1620a24804ce8b5d230fea0c279f00b18a7209646d5d47e419d1cc23e7cbf33a25a1e51ac38973dc2ac2e1e9c647a8e481ef365f77668d72becfd0 + languageName: node + linkType: hard + +"statuses@npm:>= 1.4.0 < 2, statuses@npm:>= 1.5.0 < 2": + version: 1.5.0 + resolution: "statuses@npm:1.5.0" + checksum: 10c0/e433900956357b3efd79b1c547da4d291799ac836960c016d10a98f6a810b1b5c0dcc13b5a7aa609a58239b5190e1ea176ad9221c2157d2fd1c747393e6b2940 + languageName: node + linkType: hard + "stdin-discarder@npm:^0.1.0": version: 0.1.0 resolution: "stdin-discarder@npm:0.1.0" @@ -8262,6 +9041,39 @@ __metadata: languageName: node linkType: hard +"stream-http@npm:^3.2.0": + version: 3.2.0 + resolution: "stream-http@npm:3.2.0" + dependencies: + builtin-status-codes: "npm:^3.0.0" + inherits: "npm:^2.0.4" + readable-stream: "npm:^3.6.0" + xtend: "npm:^4.0.2" + checksum: 10c0/f128fb8076d60cd548f229554b6a1a70c08a04b7b2afd4dbe7811d20f27f7d4112562eb8bce86d72a8691df3b50573228afcf1271e55e81f981536c67498bc41 + languageName: node + linkType: hard + +"stream-shift@npm:^1.0.0": + version: 1.0.3 + resolution: "stream-shift@npm:1.0.3" + checksum: 10c0/939cd1051ca750d240a0625b106a2b988c45fb5a3be0cebe9a9858cb01bc1955e8c7b9fac17a9462976bea4a7b704e317c5c2200c70f0ca715a3363b9aa4fd3b + languageName: node + linkType: hard + +"streamx@npm:^2.15.0, streamx@npm:^2.21.0": + version: 2.22.0 + resolution: "streamx@npm:2.22.0" + dependencies: + bare-events: "npm:^2.2.0" + fast-fifo: "npm:^1.3.2" + text-decoder: "npm:^1.1.0" + dependenciesMeta: + bare-events: + optional: true + checksum: 10c0/f5017998a5b6360ba652599d20ef308c8c8ab0e26c8e5f624f0706f0ea12624e94fdf1ec18318124498529a1b106a1ab1c94a1b1e1ad6c2eec7cb9c8ac1b9198 + languageName: node + linkType: hard + "string-length@npm:^4.0.1": version: 4.0.2 resolution: "string-length@npm:4.0.2" @@ -8477,6 +9289,23 @@ __metadata: languageName: node linkType: hard +"tar-fs@npm:^3.0.8": + version: 3.0.9 + resolution: "tar-fs@npm:3.0.9" + dependencies: + bare-fs: "npm:^4.0.1" + bare-path: "npm:^3.0.0" + pump: "npm:^3.0.0" + tar-stream: "npm:^3.1.5" + dependenciesMeta: + bare-fs: + optional: true + bare-path: + optional: true + checksum: 10c0/e7c6c8b7d1bf342bab0e94e0a2d96dc73c18d0cc6b59ee7b57f919adb08f5cee7f417cb4baee8322789292dc51ae67028cfd5d73f3559c919723ec7d71aa8959 + languageName: node + linkType: hard + "tar-stream@npm:^2.1.4": version: 2.2.0 resolution: "tar-stream@npm:2.2.0" @@ -8490,6 +9319,17 @@ __metadata: languageName: node linkType: hard +"tar-stream@npm:^3.1.5": + version: 3.1.7 + resolution: "tar-stream@npm:3.1.7" + dependencies: + b4a: "npm:^1.6.4" + fast-fifo: "npm:^1.2.0" + streamx: "npm:^2.15.0" + checksum: 10c0/a09199d21f8714bd729993ac49b6c8efcb808b544b89f23378ad6ffff6d1cb540878614ba9d4cfec11a64ef39e1a6f009a5398371491eb1fda606ffc7f70f718 + languageName: node + linkType: hard + "tar@npm:^7.4.3": version: 7.4.3 resolution: "tar@npm:7.4.3" @@ -8572,6 +9412,15 @@ __metadata: languageName: node linkType: hard +"text-decoder@npm:^1.1.0": + version: 1.2.3 + resolution: "text-decoder@npm:1.2.3" + dependencies: + b4a: "npm:^1.6.4" + checksum: 10c0/569d776b9250158681c83656ef2c3e0a5d5c660c27ca69f87eedef921749a4fbf02095e5f9a0f862a25cf35258379b06e31dee9c125c9f72e273b7ca1a6d1977 + languageName: node + linkType: hard + "text-table@npm:^0.2.0": version: 0.2.0 resolution: "text-table@npm:0.2.0" @@ -8586,6 +9435,35 @@ __metadata: languageName: node linkType: hard +"through2@npm:^2.0.3": + version: 2.0.5 + resolution: "through2@npm:2.0.5" + dependencies: + readable-stream: "npm:~2.3.6" + xtend: "npm:~4.0.1" + checksum: 10c0/cbfe5b57943fa12b4f8c043658c2a00476216d79c014895cef1ac7a1d9a8b31f6b438d0e53eecbb81054b93128324a82ecd59ec1a4f91f01f7ac113dcb14eade + languageName: node + linkType: hard + +"timers-browserify@npm:^2.0.12": + version: 2.0.12 + resolution: "timers-browserify@npm:2.0.12" + dependencies: + setimmediate: "npm:^1.0.4" + checksum: 10c0/98e84db1a685bc8827c117a8bc62aac811ad56a995d07938fc7ed8cdc5bf3777bfe2d4e5da868847194e771aac3749a20f6cdd22091300fe889a76fe214a4641 + languageName: node + linkType: hard + +"tinyglobby@npm:0.2.13": + version: 0.2.13 + resolution: "tinyglobby@npm:0.2.13" + dependencies: + fdir: "npm:^6.4.4" + picomatch: "npm:^4.0.2" + checksum: 10c0/ef07dfaa7b26936601d3f6d999f7928a4d1c6234c5eb36896bb88681947c0d459b7ebe797022400e555fe4b894db06e922b95d0ce60cb05fd827a0a66326b18c + languageName: node + linkType: hard + "tmp@npm:^0.2.3": version: 0.2.3 resolution: "tmp@npm:0.2.3" @@ -8609,6 +9487,13 @@ __metadata: languageName: node linkType: hard +"toidentifier@npm:1.0.1": + version: 1.0.1 + resolution: "toidentifier@npm:1.0.1" + checksum: 10c0/93937279934bd66cc3270016dd8d0afec14fb7c94a05c72dc57321f8bd1fa97e5bea6d1f7c89e728d077ca31ea125b78320a616a6c6cd0e6b9cb94cb864381c1 + languageName: node + linkType: hard + "tree-sitter-cli@npm:^0.25.0": version: 0.25.1 resolution: "tree-sitter-cli@npm:0.25.1" @@ -8767,6 +9652,13 @@ __metadata: languageName: node linkType: hard +"tsscmp@npm:1.0.6": + version: 1.0.6 + resolution: "tsscmp@npm:1.0.6" + checksum: 10c0/2f79a9455e7e3e8071995f98cdf3487ccfc91b760bec21a9abb4d90519557eafaa37246e87c92fa8bf3fef8fd30cfd0cc3c4212bb929baa9fb62494bfa4d24b2 + languageName: node + linkType: hard + "tunnel-agent@npm:^0.6.0": version: 0.6.0 resolution: "tunnel-agent@npm:0.6.0" @@ -8841,6 +9733,17 @@ __metadata: languageName: node linkType: hard +"type-is@npm:^2.0.1": + version: 2.0.1 + resolution: "type-is@npm:2.0.1" + dependencies: + content-type: "npm:^1.0.5" + media-typer: "npm:^1.1.0" + mime-types: "npm:^3.0.0" + checksum: 10c0/7f7ec0a060b16880bdad36824ab37c26019454b67d73e8a465ed5a3587440fbe158bc765f0da68344498235c877e7dbbb1600beccc94628ed05599d667951b99 + languageName: node + linkType: hard + "typed-rest-client@npm:^1.8.4": version: 1.8.11 resolution: "typed-rest-client@npm:1.8.11" @@ -9090,6 +9993,13 @@ __metadata: languageName: node linkType: hard +"vary@npm:^1.1.2": + version: 1.1.2 + resolution: "vary@npm:1.1.2" + checksum: 10c0/f15d588d79f3675135ba783c91a4083dcd290a2a5be9fcb6514220a1634e23df116847b1cc51f66bfb0644cf9353b2abb7815ae499bab06e46dd33c1a6bf1f4f + languageName: node + linkType: hard + "vfile-message@npm:^2.0.0": version: 2.0.4 resolution: "vfile-message@npm:2.0.4" @@ -9183,13 +10093,18 @@ __metadata: "@types/mocha": "npm:^10.0.6" "@types/node": "npm:^22.2.0" "@types/path-browserify": "npm:^1" + "@types/punycode": "npm:^2" "@types/vscode": "npm:^1.63.0" "@vscode/test-cli": "npm:^0.0.10" "@vscode/test-electron": "npm:^2.4.1" + "@vscode/test-web": "npm:^0.0.69" "@vscode/vsce": "npm:^3.0.0" + assert: "npm:^2.1.0" + browserify-zlib: "npm:^0.2.0" buffer: "npm:^6.0.3" c8: "npm:^10.1.3" change-case: "npm:^5.4.4" + console-browserify: "npm:^1.2.0" copy-webpack-plugin: "npm:^12.0.2" crypto-browserify: "npm:^3.12.1" eslint: "npm:^9.19.0" @@ -9198,6 +10113,7 @@ __metadata: eslint-plugin-unused-imports: "npm:^4.1.4" events: "npm:^3.3.0" glob: "npm:^11.0.1" + https-browserify: "npm:^1.0.0" husky: "npm:^9.1.7" jest: "npm:^29.7.0" mocha: "npm:^10.3.0" @@ -9205,8 +10121,12 @@ __metadata: path-browserify: "npm:^1.0.1" prettier: "npm:3.4.2" process: "npm:^0.11.10" + punycode: "npm:^2.3.1" + querystring-es3: "npm:^0.2.1" stream-browserify: "npm:^3.0.0" + stream-http: "npm:^3.2.0" string_decoder: "npm:^1.3.0" + timers-browserify: "npm:^2.0.12" tree-sitter-cli: "npm:^0.25.0" ts-jest: "npm:^29.2.6" ts-loader: "npm:^9.5.1" @@ -9242,6 +10162,13 @@ __metadata: languageName: node linkType: hard +"vscode-uri@npm:^3.1.0": + version: 3.1.0 + resolution: "vscode-uri@npm:3.1.0" + checksum: 10c0/5f6c9c10fd9b1664d71fab4e9fbbae6be93c7f75bb3a1d9d74399a88ab8649e99691223fd7cef4644376cac6e94fa2c086d802521b9a8e31c5af3e60f0f35624 + languageName: node + linkType: hard + "walker@npm:^1.0.8": version: 1.0.8 resolution: "walker@npm:1.0.8" @@ -9491,6 +10418,13 @@ __metadata: languageName: node linkType: hard +"xtend@npm:^4.0.2, xtend@npm:~4.0.1": + version: 4.0.2 + resolution: "xtend@npm:4.0.2" + checksum: 10c0/366ae4783eec6100f8a02dff02ac907bf29f9a00b82ac0264b4d8b832ead18306797e283cf19de776538babfdcb2101375ec5646b59f08c52128ac4ab812ed0e + languageName: node + linkType: hard + "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" @@ -9594,6 +10528,13 @@ __metadata: languageName: node linkType: hard +"ylru@npm:^1.2.0": + version: 1.4.0 + resolution: "ylru@npm:1.4.0" + checksum: 10c0/eaadc38ed6d78d4fda49abed45cfdaf149bd334df761dbeadd3cff62936d25ffa94571f84c25b64a9a4b5efd8f489ee6fee3eaaf8e7b2886418a3bcb9ec84b84 + languageName: node + linkType: hard + "yn@npm:3.1.1": version: 3.1.1 resolution: "yn@npm:3.1.1" From df76dff204b3036a650f2e61782ce5473e9e2203 Mon Sep 17 00:00:00 2001 From: i582 <51853996+i582@users.noreply.github.com> Date: Fri, 30 May 2025 23:40:36 +0400 Subject: [PATCH 5/5] works better --- client/src/extension.ts | 93 ++++++++++++- eslint.config.mjs | 1 + package.json | 2 +- server/src/connection.ts | 2 +- server/src/files.ts | 14 +- .../languages/tact/compiler/MistiAnalyzer.ts | 2 +- .../languages/tact/compiler/TactCompiler.ts | 2 +- server/src/languages/tact/compiler/utils.ts | 28 ++-- server/src/languages/tact/completion/index.ts | 6 +- .../src/languages/tact/toolchain/toolchain.ts | 2 +- server/src/utils/glob.ts | 46 +++++++ server/src/utils/logger.ts | 1 - server/src/vfs/global.ts | 16 ++- server/src/vfs/index.ts | 12 +- server/src/vfs/vfs.ts | 64 ++++----- server/src/vfs/vscode-provider.ts | 127 +++++++++++------- 16 files changed, 302 insertions(+), 116 deletions(-) create mode 100644 server/src/utils/glob.ts diff --git a/client/src/extension.ts b/client/src/extension.ts index e72d1333..68cc8df2 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -160,13 +160,19 @@ async function startServer(context: vscode.ExtensionContext): Promise { console.error("Worker error:", error) outputChannel.appendLine(`Worker error: ${error.message}`) } + // eslint-disable-next-line unicorn/prefer-add-event-listener worker.onmessage = message => { console.log("Worker message:", message) + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (message.data?.method === "vfs/requestFile") { + void handleFileRequest(message.data.params.uri) + } } client = new lspBrowser.LanguageClient( @@ -175,6 +181,8 @@ async function startServer(context: vscode.ExtensionContext): Promise { + await handleFileRequest(params.uri) + }) + + client.onRequest("vfs/getFile", async (params: {uri: string}) => { + return handleGetFileRequest(params.uri) + }) + + client.onRequest("vfs/getDirectory", async (params: {uri: string}) => { + return handleGetDirectoryRequest(params.uri) + }) +} + +async function handleFileRequest(uri: string): Promise { + if (!client) return + + try { + const document = await vscode.workspace.openTextDocument(vscode.Uri.parse(uri)) + const content = document.getText() + + await client.sendNotification("vfs/syncFile", { + uri: uri, + content: content, + }) + + console.debug(`Provided requested file: ${uri}`) + } catch (error) { + console.warn(`Failed to provide requested file ${uri}:`, error) + + await client.sendNotification("vfs/syncFile", { + uri: uri, + content: "", + }) + } +} + +async function handleGetFileRequest( + uri: string, +): Promise<{uri: string; content: string | null; exists: boolean}> { + try { + const document = await vscode.workspace.openTextDocument(vscode.Uri.parse(uri)) + const content = document.getText() + return { + uri: uri, + content: content, + exists: true, + } + } catch (error) { + console.warn(`Client: Failed to read file ${uri}:`, error) + return { + uri: uri, + content: null, + exists: false, + } + } +} + +async function handleGetDirectoryRequest(uri: string): Promise<{uri: string; items: string[]}> { + try { + const folderUri = vscode.Uri.parse(uri) + + const items = await vscode.workspace.fs.readDirectory(folderUri) + const itemNames = items.map(([name, type]) => { + return type === vscode.FileType.Directory ? name + "/" : name + }) + + return { + uri: uri, + items: itemNames, + } + } catch (error) { + console.warn(`Client: Failed to read directory ${uri}:`, error) + return { + uri: uri, + items: [], + } + } +} diff --git a/eslint.config.mjs b/eslint.config.mjs index bd072c5a..4b8c2dd4 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -25,6 +25,7 @@ export default tseslint.config( ".github/*", ".yarn/*", ".vscode-test/*", + ".vscode-test-web", "dist/*", "docs/*", "server/src/languages/fift/tree-sitter-fift/", diff --git a/package.json b/package.json index c949a244..eab45430 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "test:e2e:folding": "yarn test:e2e:compile && ts-node server/src/e2e/runTest.ts --suite folding", "test:e2e:intentions": "yarn test:e2e:compile && ts-node server/src/e2e/runTest.ts --suite intentions", "test:e2e:verbose": "yarn test:e2e:compile && ts-node server/src/e2e/runTest.ts --verbose", - "test:web:open": "yarn build:web && vscode-test-web --browserType=chromium --browserOption=--disable-web-security --extensionDevelopmentPath=. ./test-workspace-web", + "test:web:open": "vscode-test-web --browserType=chromium --browserOption=--disable-web-security --extensionDevelopmentPath=. ./test-workspace-web", "pack:ls": "cd dist && npm pack", "publish:ls": "cd dist && npm publish", "build-server-package-and-publish": "yarn build && yarn pack:ls && yarn publish:ls", diff --git a/server/src/connection.ts b/server/src/connection.ts index 7ad3ccdf..e12c0d73 100644 --- a/server/src/connection.ts +++ b/server/src/connection.ts @@ -7,7 +7,7 @@ import {Connection} from "vscode-languageserver" declare const self: DedicatedWorkerGlobalScope export const isWeb = (): boolean => { - return typeof self !== "undefined" && typeof importScripts === "function" + return self !== undefined && typeof importScripts === "function" } export const openConnection = (): Connection => { diff --git a/server/src/files.ts b/server/src/files.ts index d618b21c..10933ace 100644 --- a/server/src/files.ts +++ b/server/src/files.ts @@ -2,7 +2,7 @@ import * as lsp from "vscode-languageserver" import {TextDocument} from "vscode-languageserver-textdocument" import {TactFile} from "@server/languages/tact/psi/TactFile" import {createFiftParser, createTactParser, createTlbParser} from "@server/parser" -import {readFileVFS, globalVFS} from "@server/vfs/files-adapter" +import {globalVFS, readFileVFS} from "@server/vfs/files-adapter" import {FiftFile} from "@server/languages/fift/psi/FiftFile" import {TlbFile} from "@server/languages/tlb/psi/TlbFile" import {URI} from "vscode-uri" @@ -11,7 +11,19 @@ export const PARSED_FILES_CACHE: Map = new Map() export const FIFT_PARSED_FILES_CACHE: Map = new Map() export const TLB_PARSED_FILES_CACHE: Map = new Map() +const isWebEnvironment = typeof process === "undefined" || typeof process.cwd !== "function" + export async function findTactFile(uri: string, changed: boolean = false): Promise { + if (isWebEnvironment) { + const rawContent = await readOrUndefined(uri) + if (rawContent === undefined) { + console.error(`cannot read ${uri} file`) + } + + const content = rawContent ?? "" + return reparseTactFile(uri, content) + } + const cached = PARSED_FILES_CACHE.get(uri) if (cached !== undefined && !changed) { return cached diff --git a/server/src/languages/tact/compiler/MistiAnalyzer.ts b/server/src/languages/tact/compiler/MistiAnalyzer.ts index 83238216..3f78fa81 100644 --- a/server/src/languages/tact/compiler/MistiAnalyzer.ts +++ b/server/src/languages/tact/compiler/MistiAnalyzer.ts @@ -5,7 +5,7 @@ import {TactSettings} from "@server/settings/settings" const isWebEnvironment = typeof importScripts === "function" || - (typeof self !== "undefined" && typeof self.importScripts === "function") + (typeof globalThis !== "undefined" && typeof globalThis.importScripts === "function") export interface MistiJsonOutput { readonly kind: "warnings" diff --git a/server/src/languages/tact/compiler/TactCompiler.ts b/server/src/languages/tact/compiler/TactCompiler.ts index 5d911009..986695e8 100644 --- a/server/src/languages/tact/compiler/TactCompiler.ts +++ b/server/src/languages/tact/compiler/TactCompiler.ts @@ -4,7 +4,7 @@ import {toolchain} from "@server/toolchain" const isWebEnvironment = typeof importScripts === "function" || - (typeof self !== "undefined" && typeof self.importScripts === "function") + (typeof globalThis !== "undefined" && typeof globalThis.importScripts === "function") export enum Severity { INFO = 1, diff --git a/server/src/languages/tact/compiler/utils.ts b/server/src/languages/tact/compiler/utils.ts index 41832557..a6577189 100644 --- a/server/src/languages/tact/compiler/utils.ts +++ b/server/src/languages/tact/compiler/utils.ts @@ -7,23 +7,11 @@ import {crc32BigInt} from "@server/languages/tact/compiler/crc32" const isWebEnvironment = typeof importScripts === "function" || - (typeof self !== "undefined" && typeof self.importScripts === "function") + (typeof globalThis !== "undefined" && typeof globalThis.importScripts === "function") let createHash: any -if (!isWebEnvironment) { - try { - const crypto = require("node:crypto") - createHash = crypto.createHash - } catch (error) { - console.warn("Failed to load node:crypto:", error) - createHash = (algorithm: string) => ({ - update: (data: string) => ({ - digest: () => Buffer.from("fallback", "utf8"), - }), - }) - } -} else { +if (isWebEnvironment) { createHash = (algorithm: string) => ({ update: (data: string) => ({ digest: () => { @@ -47,6 +35,18 @@ if (!isWebEnvironment) { }, }), }) +} else { + try { + const crypto = require("node:crypto") + createHash = crypto.createHash + } catch (error) { + console.warn("Failed to load node:crypto:", error) + createHash = (algorithm: string) => ({ + update: (data: string) => ({ + digest: () => Buffer.from("fallback", "utf8"), + }), + }) + } } export function requireFunctionExitCode( diff --git a/server/src/languages/tact/completion/index.ts b/server/src/languages/tact/completion/index.ts index c8b35552..8710cb83 100644 --- a/server/src/languages/tact/completion/index.ts +++ b/server/src/languages/tact/completion/index.ts @@ -15,7 +15,6 @@ import type { import {SnippetsCompletionProvider} from "@server/languages/tact/completion/providers/SnippetsCompletionProvider" import {KeywordsCompletionProvider} from "@server/languages/tact/completion/providers/KeywordsCompletionProvider" import {AsKeywordCompletionProvider} from "@server/languages/tact/completion/providers/AsKeywordCompletionProvider" -import {ImportPathCompletionProvider} from "@server/languages/tact/completion/providers/ImportPathCompletionProvider" import {MapTypeCompletionProvider} from "@server/languages/tact/completion/providers/MapTypeCompletionProvider" import {BouncedTypeCompletionProvider} from "@server/languages/tact/completion/providers/BouncedTypeCompletionProvider" import {GetterCompletionProvider} from "@server/languages/tact/completion/providers/GetterCompletionProvider" @@ -31,7 +30,6 @@ import {TraitOrContractConstantsCompletionProvider} from "@server/languages/tact import {SelfCompletionProvider} from "@server/languages/tact/completion/providers/SelfCompletionProvider" import {ReturnCompletionProvider} from "@server/languages/tact/completion/providers/ReturnCompletionProvider" import {ReferenceCompletionProvider} from "@server/languages/tact/completion/providers/ReferenceCompletionProvider" -import {AsmInstructionCompletionProvider} from "@server/languages/tact/completion/providers/AsmInstructionCompletionProvider" import {PostfixCompletionProvider} from "@server/languages/tact/completion/providers/PostfixCompletionProvider" import {TypeTlbSerializationCompletionProvider} from "@server/languages/tact/completion/providers/TypeTlbSerializationCompletionProvider" import {CompletionItemAdditionalInformation} from "@server/languages/tact/completion/ReferenceCompletionProcessor" @@ -135,8 +133,8 @@ export async function provideTactCompletion( } const asyncProviders: AsyncCompletionProvider[] = [ - new ImportPathCompletionProvider(), - new AsmInstructionCompletionProvider(), + // new ImportPathCompletionProvider(), + // new AsmInstructionCompletionProvider(), ] for (const provider of asyncProviders) { diff --git a/server/src/languages/tact/toolchain/toolchain.ts b/server/src/languages/tact/toolchain/toolchain.ts index fd611e52..fd70751f 100644 --- a/server/src/languages/tact/toolchain/toolchain.ts +++ b/server/src/languages/tact/toolchain/toolchain.ts @@ -7,7 +7,7 @@ import {filePathToUri} from "@server/files" const isWebEnvironment = typeof importScripts === "function" || - (typeof self !== "undefined" && typeof self.importScripts === "function") + (typeof globalThis !== "undefined" && typeof globalThis.importScripts === "function") export class InvalidToolchainError extends Error { public constructor(message: string) { diff --git a/server/src/utils/glob.ts b/server/src/utils/glob.ts new file mode 100644 index 00000000..ad825dfc --- /dev/null +++ b/server/src/utils/glob.ts @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: MIT +// Copyright © 2025 TON Studio + +interface GlobOptions { + readonly cwd?: string + readonly ignore?: string[] +} + +export async function globFiles(pattern: string, options: GlobOptions = {}): Promise { + const isNodeEnvironment = typeof process !== "undefined" && process.versions.node + + if (isNodeEnvironment) { + try { + const {glob} = await import("glob") + return await glob(pattern, { + cwd: options.cwd ?? process.cwd(), + ignore: options.ignore ?? [], + }) + } catch (error) { + console.warn("Failed to import glob package, falling back to VFS:", error) + return useVFSGlob(pattern, options) + } + } else { + return useVFSGlob(pattern, options) + } +} + +async function useVFSGlob(pattern: string, options: GlobOptions): Promise { + try { + const {glob, globalVFS} = await import("@server/vfs/files-adapter") + const {filePathToUri} = await import("@server/files") + + let cwd = options.cwd ?? "" + if (cwd && !cwd.startsWith("file://")) { + cwd = filePathToUri(cwd) + } + + return await glob(globalVFS, pattern, { + cwd, + ignore: options.ignore ?? [], + }) + } catch (error) { + console.error("Failed to use VFS glob:", error) + return [] + } +} diff --git a/server/src/utils/logger.ts b/server/src/utils/logger.ts index 2f2bc0cc..ea995551 100644 --- a/server/src/utils/logger.ts +++ b/server/src/utils/logger.ts @@ -1,7 +1,6 @@ // SPDX-License-Identifier: MIT // Copyright © 2025 TON Studio -/* eslint-disable @typescript-eslint/no-base-to-string */ // import type {Connection} from "vscode-languageserver" // import * as fs from "node:fs" // import * as path from "path" diff --git a/server/src/vfs/global.ts b/server/src/vfs/global.ts index 395af1c9..c05f301d 100644 --- a/server/src/vfs/global.ts +++ b/server/src/vfs/global.ts @@ -1,5 +1,17 @@ // SPDX-License-Identifier: MIT // Copyright © 2025 TON Studio -import {createVFS, createDefaultProvider, VFS} from "./index" +import {createVFS} from "./vfs" +import {createNodeFSProvider} from "./fs-provider" +import {createVSCodeProvider} from "./vscode-provider" -export const globalVFS: VFS = createVFS(createDefaultProvider()) +export const globalVFS = (() => { + const isWebEnvironment = + typeof globalThis !== "undefined" && typeof importScripts === "function" + + if (isWebEnvironment) { + const provider = createVSCodeProvider() + return createVFS(provider) + } else { + return createVFS(createNodeFSProvider()) + } +})() diff --git a/server/src/vfs/index.ts b/server/src/vfs/index.ts index 2fbb1ce9..d2a74997 100644 --- a/server/src/vfs/index.ts +++ b/server/src/vfs/index.ts @@ -3,18 +3,8 @@ export type {FileSystemProvider, VirtualFile} from "./types" -export {createVFS, readFile, exists, listFiles, glob} from "./vfs" +export {createVFS, readFile, exists, listFiles, listDirs, glob} from "./vfs" export type {VFS} from "./vfs" export {createNodeFSProvider} from "./fs-provider" export {createVSCodeProvider} from "./vscode-provider" - -import {FileSystemProvider} from "./types" -import {createNodeFSProvider} from "./fs-provider" -import {createVSCodeProvider} from "./vscode-provider" - -export function createDefaultProvider(): FileSystemProvider { - return typeof process !== "undefined" && process.versions.node - ? createNodeFSProvider() - : createVSCodeProvider() -} diff --git a/server/src/vfs/vfs.ts b/server/src/vfs/vfs.ts index c51a763e..85cac011 100644 --- a/server/src/vfs/vfs.ts +++ b/server/src/vfs/vfs.ts @@ -39,56 +39,60 @@ export async function glob( const results: string[] = [] + const ignoreRegexps = ignore.map(pattern => { + const escapedPattern = pattern + .replace(/\./g, "\\.") + .replace(/\*\*/g, ".*") + .replace(/\*/g, "[^/]*") + return new RegExp(`^${escapedPattern}$`) + }) + + const shouldIgnore = (filePath: string): boolean => { + return ignoreRegexps.some(regex => regex.test(filePath)) + } + + const compilePattern = (pattern: string): RegExp => { + const escapedPattern = pattern + .replace(/\./g, "\\.") + .replace(/\*\*/g, ".*") + .replace(/\*/g, "[^/]*") + return new RegExp(`^${escapedPattern}$`) + } + + const patternRegex = compilePattern(pattern) + async function walkDirectory(dirUri: string, currentPath: string): Promise { try { + if (shouldIgnore(currentPath)) { + return + } + const files = await listFiles(vfs, dirUri) const dirs = await listDirs(vfs, dirUri) - // Проверяем файлы for (const file of files) { const filePath = currentPath ? `${currentPath}/${file}` : file - // Проверяем, не игнорируется ли файл - const isIgnored = ignore.some(ignorePattern => - matchesPattern(filePath, ignorePattern), - ) - - if (!isIgnored && matchesPattern(filePath, pattern)) { + if (!shouldIgnore(filePath) && patternRegex.test(filePath)) { results.push(filePath) } } - // Рекурсивно обходим директории for (const dir of dirs) { const dirPath = currentPath ? `${currentPath}/${dir}` : dir + const subDirUri = dirUri ? `${dirUri}/${dir}` : dir - // Проверяем, не игнорируется ли директория - const isIgnored = ignore.some(ignorePattern => - matchesPattern(dirPath, ignorePattern), - ) - - if (!isIgnored) { - const childDirUri = `${dirUri}/${dir}` - await walkDirectory(childDirUri, dirPath) + if (!shouldIgnore(dirPath)) { + await walkDirectory(subDirUri, dirPath) } } } catch (error) { - // Игнорируем ошибки доступа к директориям - console.debug(`Failed to read directory ${dirUri}:`, error) + console.warn(`Error walking directory ${dirUri}:`, error) } } - await walkDirectory(cwd, "") - return results -} - -function matchesPattern(filePath: string, pattern: string): boolean { - const regexPattern = pattern - .replace(/\*\*/g, ".*") // ** -> .* - .replace(/\*/g, "[^/]*") // * -> [^/]* - .replace(/\./g, "\\.") // . -> \. - .replace(/\?/g, ".") // ? -> . + const startUri = cwd || "" + await walkDirectory(startUri, "") - const regex = new RegExp(`^${regexPattern}$`) - return regex.test(filePath) + return results.sort() } diff --git a/server/src/vfs/vscode-provider.ts b/server/src/vfs/vscode-provider.ts index 654e73b8..b05db29b 100644 --- a/server/src/vfs/vscode-provider.ts +++ b/server/src/vfs/vscode-provider.ts @@ -1,75 +1,110 @@ // SPDX-License-Identifier: MIT // Copyright © 2025 TON Studio -/* eslint-disable @typescript-eslint/require-await */ import {FileSystemProvider, VirtualFile} from "./types" +import {connection} from "@server/connection" export function createVSCodeProvider(): FileSystemProvider { - const virtualFiles: Map = new Map() - const virtualDirs: Map> = new Map() - - const initVirtualFS = () => { - virtualDirs.set("", new Set([])) - - console.debug("VS Code provider initialized in web environment") - } - - initVirtualFS() - return { async readFile(uri: string): Promise { - const content = virtualFiles.get(uri) - if (content !== undefined) { + try { + const content = await requestFileFromClientSync(uri) + + if (content === null) { + console.warn(`VFS: File not found on client: ${uri}`) + return { + uri, + content: "", + exists: false, + } + } else { + return { + uri, + content, + exists: true, + } + } + } catch (error) { + console.error(`VFS: Error reading file ${uri}:`, error) return { uri, - content, - exists: true, + content: "", + exists: false, } } - - return { - uri, - content: "", - exists: false, - } }, async exists(uri: string): Promise { - return virtualFiles.has(uri) + try { + const file = await this.readFile(uri) + return file?.exists ?? false + } catch { + return false + } }, async listFiles(uri: string): Promise { - const dirContent = virtualDirs.get(uri) - if (!dirContent) { + try { + const items = await requestDirectoryFromClientSync(uri) + return items.filter(item => !item.endsWith("/")) + } catch (error) { + console.error(`VFS: Error listing files in ${uri}:`, error) return [] } - - const files: string[] = [] - for (const item of dirContent) { - const fullPath = uri ? `${uri}/${item}` : item - if (virtualFiles.has(fullPath)) { - files.push(item) - } - } - - return files }, async listDirs(uri: string): Promise { - const dirContent = virtualDirs.get(uri) - if (!dirContent) { + try { + const items = await requestDirectoryFromClientSync(uri) + return items.filter(item => item.endsWith("/")).map(item => item.slice(0, -1)) + } catch (error) { + console.error(`VFS: Error listing directories in ${uri}:`, error) return [] } + }, + } +} - const dirs: string[] = [] - for (const item of dirContent) { - const fullPath = uri ? `${uri}/${item}` : item - if (virtualDirs.has(fullPath)) { - dirs.push(item) - } - } +export interface FileRequest { + readonly uri: string +} - return dirs - }, +export interface FileResponse { + readonly uri: string + readonly content: string | null + readonly exists: boolean +} + +export interface DirectoryRequest { + readonly uri: string +} + +export interface DirectoryResponse { + readonly uri: string + readonly items: string[] +} + +export async function requestFileFromClientSync(uri: string): Promise { + try { + const request: FileRequest = {uri} + const response: FileResponse = await connection.sendRequest("vfs/getFile", request) + return response.exists ? response.content : null + } catch (error) { + console.error(`VFS: Error requesting file ${uri}:`, error) + return null + } +} + +export async function requestDirectoryFromClientSync(uri: string): Promise { + try { + const request: DirectoryRequest = {uri} + const response: DirectoryResponse = await connection.sendRequest( + "vfs/getDirectory", + request, + ) + return response.items + } catch (error) { + console.error(`VFS: Error requesting directory ${uri}:`, error) + return [] } }